Skip to content

Commit

Permalink
Merge branch 'dt/pre-refs-backend'
Browse files Browse the repository at this point in the history
Code restructuring around the "refs" area to prepare for pluggable
refs backends.

* dt/pre-refs-backend: (24 commits)
  refs: on symref reflog expire, lock symref not referrent
  refs: move resolve_ref_unsafe into common code
  show_head_ref(): check the result of resolve_ref_namespace()
  check_aliased_update(): check that dst_name is non-NULL
  checkout_paths(): remove unneeded flag variable
  cmd_merge(): remove unneeded flag variable
  fsck_head_link(): remove unneeded flag variable
  read_raw_ref(): change flags parameter to unsigned int
  files-backend: inline resolve_ref_1() into resolve_ref_unsafe()
  read_raw_ref(): manage own scratch space
  files-backend: break out ref reading
  resolve_ref_1(): eliminate local variable "bad_name"
  resolve_ref_1(): reorder code
  resolve_ref_1(): eliminate local variable
  resolve_ref_unsafe(): ensure flags is always set
  resolve_ref_unsafe(): use for loop to count up to MAXDEPTH
  resolve_missing_loose_ref(): simplify semantics
  t1430: improve test coverage of deletion of badly-named refs
  t1430: test for-each-ref in the presence of badly-named refs
  t1430: don't rely on symbolic-ref for creating broken symrefs
  ...
  • Loading branch information
gitster committed Apr 25, 2016
2 parents 5b715ec + 41d796e commit edc2f71
Show file tree
Hide file tree
Showing 10 changed files with 440 additions and 288 deletions.
3 changes: 1 addition & 2 deletions builtin/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ static int checkout_paths(const struct checkout_opts *opts,
struct checkout state;
static char *ps_matched;
unsigned char rev[20];
int flag;
struct commit *head;
int errs = 0;
struct lock_file *lock_file;
Expand Down Expand Up @@ -375,7 +374,7 @@ static int checkout_paths(const struct checkout_opts *opts,
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
die(_("unable to write new index file"));

read_ref_full("HEAD", 0, rev, &flag);
read_ref_full("HEAD", 0, rev, NULL);
head = lookup_commit_reference_gently(rev, 1);

errs |= post_checkout_hook(head, head, 0);
Expand Down
3 changes: 1 addition & 2 deletions builtin/fsck.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,13 +493,12 @@ static void fsck_object_dir(const char *path)

static int fsck_head_link(void)
{
int flag;
int null_is_error = 0;

if (verbose)
fprintf(stderr, "Checking HEAD link\n");

head_points_at = resolve_ref_unsafe("HEAD", 0, head_oid.hash, &flag);
head_points_at = resolve_ref_unsafe("HEAD", 0, head_oid.hash, NULL);
if (!head_points_at) {
errors_found |= ERROR_REFS;
return error("Invalid HEAD");
Expand Down
4 changes: 2 additions & 2 deletions builtin/merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -1168,7 +1168,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
struct commit *head_commit;
struct strbuf buf = STRBUF_INIT;
const char *head_arg;
int flag, i, ret = 0, head_subsumed;
int i, ret = 0, head_subsumed;
int best_cnt = -1, merge_was_ok = 0, automerge_was_ok = 0;
struct commit_list *common = NULL;
const char *best_strategy = NULL, *wt_strategy = NULL;
Expand All @@ -1182,7 +1182,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
* Check if we are _not_ on a detached HEAD, i.e. if there is a
* current branch.
*/
branch = branch_to_free = resolve_refdup("HEAD", 0, head_sha1, &flag);
branch = branch_to_free = resolve_refdup("HEAD", 0, head_sha1, NULL);
if (branch && starts_with(branch, "refs/heads/"))
branch += 11;
if (!branch || is_null_sha1(head_sha1))
Expand Down
2 changes: 1 addition & 1 deletion builtin/receive-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -1084,13 +1084,13 @@ static void check_aliased_update(struct command *cmd, struct string_list *list)
if (!(flag & REF_ISSYMREF))
return;

dst_name = strip_namespace(dst_name);
if (!dst_name) {
rp_error("refusing update to broken symref '%s'", cmd->ref_name);
cmd->skip_update = 1;
cmd->error_string = "broken symref";
return;
}
dst_name = strip_namespace(dst_name);

if ((item = string_list_lookup(list, dst_name)) == NULL)
return;
Expand Down
4 changes: 2 additions & 2 deletions http-backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,9 +484,9 @@ static int show_head_ref(const char *refname, const struct object_id *oid,
const char *target = resolve_ref_unsafe(refname,
RESOLVE_REF_READING,
unused.hash, NULL);
const char *target_nons = strip_namespace(target);

strbuf_addf(buf, "ref: %s\n", target_nons);
if (target)
strbuf_addf(buf, "ref: %s\n", strip_namespace(target));
} else {
strbuf_addf(buf, "%s\n", oid_to_hex(oid));
}
Expand Down
149 changes: 149 additions & 0 deletions refs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1080,3 +1080,152 @@ int rename_ref_available(const char *oldname, const char *newname)
strbuf_release(&err);
return ret;
}

int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
{
struct object_id oid;
int flag;

if (submodule) {
if (resolve_gitlink_ref(submodule, "HEAD", oid.hash) == 0)
return fn("HEAD", &oid, 0, cb_data);

return 0;
}

if (!read_ref_full("HEAD", RESOLVE_REF_READING, oid.hash, &flag))
return fn("HEAD", &oid, flag, cb_data);

return 0;
}

int head_ref(each_ref_fn fn, void *cb_data)
{
return head_ref_submodule(NULL, fn, cb_data);
}

int for_each_ref(each_ref_fn fn, void *cb_data)
{
return do_for_each_ref(NULL, "", fn, 0, 0, cb_data);
}

int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
{
return do_for_each_ref(submodule, "", fn, 0, 0, cb_data);
}

int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
{
return do_for_each_ref(NULL, prefix, fn, strlen(prefix), 0, cb_data);
}

int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken)
{
unsigned int flag = 0;

if (broken)
flag = DO_FOR_EACH_INCLUDE_BROKEN;
return do_for_each_ref(NULL, prefix, fn, 0, flag, cb_data);
}

int for_each_ref_in_submodule(const char *submodule, const char *prefix,
each_ref_fn fn, void *cb_data)
{
return do_for_each_ref(submodule, prefix, fn, strlen(prefix), 0, cb_data);
}

int for_each_replace_ref(each_ref_fn fn, void *cb_data)
{
return do_for_each_ref(NULL, git_replace_ref_base, fn,
strlen(git_replace_ref_base), 0, cb_data);
}

int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
{
struct strbuf buf = STRBUF_INIT;
int ret;
strbuf_addf(&buf, "%srefs/", get_git_namespace());
ret = do_for_each_ref(NULL, buf.buf, fn, 0, 0, cb_data);
strbuf_release(&buf);
return ret;
}

int for_each_rawref(each_ref_fn fn, void *cb_data)
{
return do_for_each_ref(NULL, "", fn, 0,
DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
}

/* This function needs to return a meaningful errno on failure */
const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
unsigned char *sha1, int *flags)
{
static struct strbuf sb_refname = STRBUF_INIT;
int unused_flags;
int symref_count;

if (!flags)
flags = &unused_flags;

*flags = 0;

if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
!refname_is_safe(refname)) {
errno = EINVAL;
return NULL;
}

/*
* dwim_ref() uses REF_ISBROKEN to distinguish between
* missing refs and refs that were present but invalid,
* to complain about the latter to stderr.
*
* We don't know whether the ref exists, so don't set
* REF_ISBROKEN yet.
*/
*flags |= REF_BAD_NAME;
}

for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) {
unsigned int read_flags = 0;

if (read_raw_ref(refname, sha1, &sb_refname, &read_flags)) {
*flags |= read_flags;
if (errno != ENOENT || (resolve_flags & RESOLVE_REF_READING))
return NULL;
hashclr(sha1);
if (*flags & REF_BAD_NAME)
*flags |= REF_ISBROKEN;
return refname;
}

*flags |= read_flags;

if (!(read_flags & REF_ISSYMREF)) {
if (*flags & REF_BAD_NAME) {
hashclr(sha1);
*flags |= REF_ISBROKEN;
}
return refname;
}

refname = sb_refname.buf;
if (resolve_flags & RESOLVE_REF_NO_RECURSE) {
hashclr(sha1);
return refname;
}
if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
!refname_is_safe(refname)) {
errno = EINVAL;
return NULL;
}

*flags |= REF_ISBROKEN | REF_BAD_NAME;
}
}

errno = ELOOP;
return NULL;
}
Loading

0 comments on commit edc2f71

Please sign in to comment.