From 755b49ae965c9d17d91fbe7902050428f366bf69 Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Mon, 20 Feb 2017 20:10:32 -0500 Subject: delete_ref: accept a reflog message argument When the current branch is renamed with 'git branch -m/-M' or deleted with 'git update-ref -m -d', the event is recorded in HEAD's log with an empty message. In preparation for adding a more meaningful message to HEAD's log in these cases, update delete_ref() to take a message argument and pass it along to ref_transaction_delete(). Modify all callers to pass NULL for the new message argument; no change in behavior is intended. Note that this is relevant for HEAD's log but not for the deleted ref's log, which is currently deleted along with the ref. Even if it were not, an entry for the deletion wouldn't be present in the deleted ref's log. files_transaction_commit() writes to the log if REF_NEEDS_COMMIT or REF_LOG_ONLY are set, but lock_ref_for_update() doesn't set REF_NEEDS_COMMIT for the deleted ref because REF_DELETING is set. In contrast, the update for HEAD has REF_LOG_ONLY set by split_head_update(), resulting in the deletion being logged. Signed-off-by: Kyle Meyer Signed-off-by: Junio C Hamano --- builtin/am.c | 4 ++-- builtin/branch.c | 2 +- builtin/notes.c | 4 ++-- builtin/remote.c | 4 ++-- builtin/replace.c | 2 +- builtin/reset.c | 2 +- builtin/symbolic-ref.c | 2 +- builtin/tag.c | 2 +- builtin/update-ref.c | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) (limited to 'builtin') diff --git a/builtin/am.c b/builtin/am.c index 31fb60578..f7a7a971f 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1049,7 +1049,7 @@ static void am_setup(struct am_state *state, enum patch_format patch_format, } else { write_state_text(state, "abort-safety", ""); if (!state->rebasing) - delete_ref("ORIG_HEAD", NULL, 0); + delete_ref(NULL, "ORIG_HEAD", NULL, 0); } /* @@ -2172,7 +2172,7 @@ static void am_abort(struct am_state *state) has_curr_head ? &curr_head : NULL, 0, UPDATE_REFS_DIE_ON_ERR); else if (curr_branch) - delete_ref(curr_branch, NULL, REF_NODEREF); + delete_ref(NULL, curr_branch, NULL, REF_NODEREF); free(curr_branch); am_destroy(state); diff --git a/builtin/branch.c b/builtin/branch.c index 9d30f55b0..8f8242e07 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -251,7 +251,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds, goto next; } - if (delete_ref(name, is_null_sha1(sha1) ? NULL : sha1, + if (delete_ref(NULL, name, is_null_sha1(sha1) ? NULL : sha1, REF_NODEREF)) { error(remote_branch ? _("Error deleting remote-tracking branch '%s'") diff --git a/builtin/notes.c b/builtin/notes.c index 5248a9bad..4b492abd4 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -681,9 +681,9 @@ static int merge_abort(struct notes_merge_options *o) * notes_merge_abort() to remove .git/NOTES_MERGE_WORKTREE. */ - if (delete_ref("NOTES_MERGE_PARTIAL", NULL, 0)) + if (delete_ref(NULL, "NOTES_MERGE_PARTIAL", NULL, 0)) ret += error(_("failed to delete ref NOTES_MERGE_PARTIAL")); - if (delete_ref("NOTES_MERGE_REF", NULL, REF_NODEREF)) + if (delete_ref(NULL, "NOTES_MERGE_REF", NULL, REF_NODEREF)) ret += error(_("failed to delete ref NOTES_MERGE_REF")); if (notes_merge_abort(o)) ret += error(_("failed to remove 'git notes merge' worktree")); diff --git a/builtin/remote.c b/builtin/remote.c index 5339ed6ad..2b415911b 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -691,7 +691,7 @@ static int mv(int argc, const char **argv) read_ref_full(item->string, RESOLVE_REF_READING, oid.hash, &flag); if (!(flag & REF_ISSYMREF)) continue; - if (delete_ref(item->string, NULL, REF_NODEREF)) + if (delete_ref(NULL, item->string, NULL, REF_NODEREF)) die(_("deleting '%s' failed"), item->string); } for (i = 0; i < remote_branches.nr; i++) { @@ -1248,7 +1248,7 @@ static int set_head(int argc, const char **argv) head_name = xstrdup(states.heads.items[0].string); free_remote_ref_states(&states); } else if (opt_d && !opt_a && argc == 1) { - if (delete_ref(buf.buf, NULL, REF_NODEREF)) + if (delete_ref(NULL, buf.buf, NULL, REF_NODEREF)) result |= error(_("Could not delete %s"), buf.buf); } else usage_with_options(builtin_remote_sethead_usage, options); diff --git a/builtin/replace.c b/builtin/replace.c index b58c714cb..226d0f952 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -121,7 +121,7 @@ static int for_each_replace_name(const char **argv, each_replace_name_fn fn) static int delete_replace_ref(const char *name, const char *ref, const unsigned char *sha1) { - if (delete_ref(ref, sha1, 0)) + if (delete_ref(NULL, ref, sha1, 0)) return 1; printf("Deleted replace ref '%s'\n", name); return 0; diff --git a/builtin/reset.c b/builtin/reset.c index 8ab915bfc..fc3b906c4 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -256,7 +256,7 @@ static int reset_refs(const char *rev, const struct object_id *oid) update_ref_oid(msg.buf, "ORIG_HEAD", orig, old_orig, 0, UPDATE_REFS_MSG_ON_ERR); } else if (old_orig) - delete_ref("ORIG_HEAD", old_orig->hash, 0); + delete_ref(NULL, "ORIG_HEAD", old_orig->hash, 0); set_reflog_message(&msg, "updating HEAD", rev); update_ref_status = update_ref_oid(msg.buf, "HEAD", oid, orig, 0, UPDATE_REFS_MSG_ON_ERR); diff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c index 96eed9446..70addef15 100644 --- a/builtin/symbolic-ref.c +++ b/builtin/symbolic-ref.c @@ -58,7 +58,7 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) die("Cannot delete %s, not a symbolic ref", argv[0]); if (!strcmp(argv[0], "HEAD")) die("deleting '%s' is not allowed", argv[0]); - return delete_ref(argv[0], NULL, REF_NODEREF); + return delete_ref(NULL, argv[0], NULL, REF_NODEREF); } switch (argc) { diff --git a/builtin/tag.c b/builtin/tag.c index e40c4a967..c23d6d4bc 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -97,7 +97,7 @@ static int for_each_tag_name(const char **argv, each_tag_name_fn fn, static int delete_tag(const char *name, const char *ref, const unsigned char *sha1, const void *cb_data) { - if (delete_ref(ref, sha1, 0)) + if (delete_ref(NULL, ref, sha1, 0)) return 1; printf(_("Deleted tag '%s' (was %s)\n"), name, find_unique_abbrev(sha1, DEFAULT_ABBREV)); return 0; diff --git a/builtin/update-ref.c b/builtin/update-ref.c index 7f30d3a76..86d006d36 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -433,7 +433,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix) * For purposes of backwards compatibility, we treat * NULL_SHA1 as "don't care" here: */ - return delete_ref(refname, + return delete_ref(NULL, refname, (oldval && !is_null_sha1(oldsha1)) ? oldsha1 : NULL, flags); else -- cgit v1.2.1 From de922669ab0508109cdb5672e5515f7524e3ccf8 Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Mon, 20 Feb 2017 20:10:33 -0500 Subject: update-ref: pass reflog message to delete_ref() Now that delete_ref() accepts a reflog message, pass the user-provided message to delete_ref() rather than silently dropping it. Signed-off-by: Kyle Meyer Signed-off-by: Junio C Hamano --- builtin/update-ref.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin') diff --git a/builtin/update-ref.c b/builtin/update-ref.c index 86d006d36..0b2ecf41a 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -433,7 +433,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix) * For purposes of backwards compatibility, we treat * NULL_SHA1 as "don't care" here: */ - return delete_ref(NULL, refname, + return delete_ref(msg, refname, (oldval && !is_null_sha1(oldsha1)) ? oldsha1 : NULL, flags); else -- cgit v1.2.1 From 39ee4c6c2fc80960094ae1454922c2d10c72f210 Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Mon, 20 Feb 2017 20:10:35 -0500 Subject: branch: record creation of renamed branch in HEAD's log Renaming the current branch adds an event to the current branch's log and to HEAD's log. However, the logged entries differ. The entry in the branch's log represents the entire renaming operation (the old and new hash are identical), whereas the entry in HEAD's log represents the deletion only (the new sha1 is null). Extend replace_each_worktree_head_symref(), whose only caller is branch_rename(), to take a reflog message argument. This allows the creation of the new ref to be recorded in HEAD's log. As a result, the renaming event is represented by two entries (a deletion and a creation entry) in HEAD's log. It's a bit unfortunate that the branch's log and HEAD's log now represent the renaming event in different ways. Given that the renaming operation is not atomic, the two-entry form is a more accurate representation of the operation and is more useful for debugging purposes if a failure occurs between the deletion and creation events. It would make sense to move the branch's log to the two-entry form, but this would involve changes to how the rename is carried out and to how the update flags and reflogs are processed for deletions, so it may not be worth the effort. Based-on-patch-by: Jeff King Signed-off-by: Kyle Meyer Signed-off-by: Junio C Hamano --- builtin/branch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'builtin') diff --git a/builtin/branch.c b/builtin/branch.c index 8f8242e07..e1f97dcfc 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -579,14 +579,15 @@ static void rename_branch(const char *oldname, const char *newname, int force) if (rename_ref(oldref.buf, newref.buf, logmsg.buf)) die(_("Branch rename failed")); - strbuf_release(&logmsg); if (recovery) warning(_("Renamed a misnamed branch '%s' away"), oldref.buf + 11); - if (replace_each_worktree_head_symref(oldref.buf, newref.buf)) + if (replace_each_worktree_head_symref(oldref.buf, newref.buf, logmsg.buf)) die(_("Branch renamed to %s, but HEAD is not updated!"), newname); + strbuf_release(&logmsg); + strbuf_addf(&oldsection, "branch.%s", oldref.buf + 11); strbuf_release(&oldref); strbuf_addf(&newsection, "branch.%s", newref.buf + 11); -- cgit v1.2.1