diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2014-03-19 18:14:35 +0100 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2014-03-19 18:14:35 +0100 |
commit | 99797c96cd57a616ada009a2359390c605d33929 (patch) | |
tree | eaa862563a6a681d07fc664648a41fa1768297a5 /src/refdb_fs.c | |
parent | 6aaae94a7060834a68f3fd24d8006dbfe769e04a (diff) | |
download | libgit2-99797c96cd57a616ada009a2359390c605d33929.tar.gz |
reflog: handle symref chains
Given HEAD -> master -> foo, when updating foo's reflog we should also
update HEAD's, as it's considered the current branch.
Diffstat (limited to 'src/refdb_fs.c')
-rw-r--r-- | src/refdb_fs.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 905113226..25316fe46 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -993,23 +993,53 @@ static int maybe_append_head(refdb_fs_backend *backend, const git_reference *ref { int error; git_oid old_id = {{0}}; - git_reference *head; + git_reference *tmp = NULL, *head = NULL, *peeled = NULL; + const char *name; + + if (ref->type == GIT_REF_SYMBOLIC) + return 0; /* if we can't resolve, we use {0}*40 as old id */ git_reference_name_to_id(&old_id, backend->repo, ref->name); - if ((error = git_reference_lookup(&head, backend->repo, "HEAD")) < 0) + if ((error = git_reference_lookup(&head, backend->repo, GIT_HEAD_FILE)) < 0) return error; if (git_reference_type(head) == GIT_REF_OID) goto cleanup; - if (strcmp(git_reference_symbolic_target(head), ref->name)) + if ((error = git_reference_lookup(&tmp, backend->repo, GIT_HEAD_FILE)) < 0) + goto cleanup; + + /* Go down the symref chain until we find the branch */ + while (git_reference_type(tmp) == GIT_REF_SYMBOLIC) { + error = git_reference_lookup(&peeled, backend->repo, git_reference_symbolic_target(tmp)); + if (error < 0) + break; + + git_reference_free(tmp); + tmp = peeled; + } + + if (error == GIT_ENOTFOUND) { + error = 0; + name = git_reference_symbolic_target(tmp); + } else if (error < 0) { + goto cleanup; + } else { + name = git_reference_name(tmp); + } + + if (error < 0) + goto cleanup; + + if (strcmp(name, ref->name)) goto cleanup; error = reflog_append(backend, head, &old_id, git_reference_target(ref), who, message); cleanup: + git_reference_free(tmp); git_reference_free(head); return error; } |