]> git.ipfire.org Git - thirdparty/git.git/commitdiff
rebase --apply: fix reflog
authorPhillip Wood <phillip.wood@dunelm.org.uk>
Wed, 26 Jan 2022 13:05:47 +0000 (13:05 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 26 Jan 2022 20:08:53 +0000 (12:08 -0800)
move_to_original_branch() passes the message intended for the branch
reflog as `orig_head_msg`. Fix this by adding a `branch_msg` member to
struct reset_head_opts and add a regression test.  Note that these
reflog messages do not respect GIT_REFLOG_ACTION. They are not alone
in that and will be fixed in a future series.

The "merge" backend already has tests that check both the branch and
HEAD reflogs.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/rebase.c
reset.c
reset.h
t/t3406-rebase-message.sh

index ecc368dd4f458ad486a367ae1dd832a4b6bd8b74..b55a9cff05db2820763d2d50eed740e4d27845a4 100644 (file)
@@ -570,7 +570,7 @@ static int finish_rebase(struct rebase_options *opts)
 
 static int move_to_original_branch(struct rebase_options *opts)
 {
-       struct strbuf orig_head_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;
+       struct strbuf branch_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;
        struct reset_head_opts ropts = { 0 };
        int ret;
 
@@ -580,17 +580,17 @@ static int move_to_original_branch(struct rebase_options *opts)
        if (!opts->onto)
                BUG("move_to_original_branch without onto");
 
-       strbuf_addf(&orig_head_reflog, "rebase finished: %s onto %s",
+       strbuf_addf(&branch_reflog, "rebase finished: %s onto %s",
                    opts->head_name, oid_to_hex(&opts->onto->object.oid));
        strbuf_addf(&head_reflog, "rebase finished: returning to %s",
                    opts->head_name);
        ropts.branch = opts->head_name;
        ropts.flags = RESET_HEAD_REFS_ONLY;
-       ropts.orig_head_msg = orig_head_reflog.buf;
+       ropts.branch_msg = branch_reflog.buf;
        ropts.head_msg = head_reflog.buf;
        ret = reset_head(the_repository, &ropts);
 
-       strbuf_release(&orig_head_reflog);
+       strbuf_release(&branch_reflog);
        strbuf_release(&head_reflog);
        return ret;
 }
diff --git a/reset.c b/reset.c
index 78145d5c4569e3b2daaf5cdd5802a0915d442a32..e02915c0f65fd3bd804c7f954e47eb548014f117 100644 (file)
--- a/reset.c
+++ b/reset.c
@@ -16,6 +16,7 @@ static int update_refs(const struct reset_head_opts *opts,
        unsigned run_hook = opts->flags & RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
        unsigned update_orig_head = opts->flags & RESET_ORIG_HEAD;
        const char *switch_to_branch = opts->branch;
+       const char *reflog_branch = opts->branch_msg;
        const char *reflog_head = opts->head_msg;
        const char *reflog_orig_head = opts->orig_head_msg;
        const char *default_reflog_action = opts->default_reflog_action;
@@ -58,8 +59,9 @@ static int update_refs(const struct reset_head_opts *opts,
                                 detach_head ? REF_NO_DEREF : 0,
                                 UPDATE_REFS_MSG_ON_ERR);
        else {
-               ret = update_ref(reflog_head, switch_to_branch, oid,
-                                NULL, 0, UPDATE_REFS_MSG_ON_ERR);
+               ret = update_ref(reflog_branch ? reflog_branch : reflog_head,
+                                switch_to_branch, oid, NULL, 0,
+                                UPDATE_REFS_MSG_ON_ERR);
                if (!ret)
                        ret = create_symref("HEAD", switch_to_branch,
                                            reflog_head);
@@ -90,6 +92,12 @@ int reset_head(struct repository *r, const struct reset_head_opts *opts)
        if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
                BUG("Not a fully qualified branch: '%s'", switch_to_branch);
 
+       if (opts->orig_head_msg && !update_orig_head)
+               BUG("ORIG_HEAD reflog message given without updating ORIG_HEAD");
+
+       if (opts->branch_msg && !opts->branch)
+               BUG("branch reflog message given without a branch");
+
        if (!refs_only && repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0) {
                ret = -1;
                goto leave_reset_head;
diff --git a/reset.h b/reset.h
index a205be2fb8511a4149cc3b23a30565f9295f7fd4..7ef7e43ea8c785405de7e4e1b804c982ebf31c3c 100644 (file)
--- a/reset.h
+++ b/reset.h
@@ -30,6 +30,10 @@ struct reset_head_opts {
         * Flags defined above.
         */
        unsigned flags;
+       /*
+        * Optional reflog message for branch, defaults to head_msg.
+        */
+       const char *branch_msg;
        /*
         * Optional reflog message for HEAD, if this omitted but oid or branch
         * are given then default_reflog_action must be given.
index 77a313f62eb36c5c340dff627e3c0afcffb65792..d17b450e811cc0f13ab94ac76e288f782e897d64 100755 (executable)
@@ -105,6 +105,29 @@ test_expect_success 'GIT_REFLOG_ACTION' '
        test_cmp expect actual
 '
 
+test_expect_success 'rebase --apply reflog' '
+       git checkout -b reflog-apply start &&
+       old_head_reflog="$(git log -g --format=%gs -1 HEAD)" &&
+
+       git rebase --apply Y &&
+
+       git log -g --format=%gs -4 HEAD >actual &&
+       cat >expect <<-EOF &&
+       rebase finished: returning to refs/heads/reflog-apply
+       rebase: Z
+       rebase: checkout Y
+       $old_head_reflog
+       EOF
+       test_cmp expect actual &&
+
+       git log -g --format=%gs -2 reflog-apply >actual &&
+       cat >expect <<-EOF &&
+       rebase finished: refs/heads/reflog-apply onto $(git rev-parse Y)
+       branch: Created from start
+       EOF
+       test_cmp expect actual
+'
+
 test_expect_success 'rebase -i onto unrelated history' '
        git init unrelated &&
        test_commit -C unrelated 1 &&