{"thread":{"id":"57450","subject":"[PATCH 3/7] rebase --merge: fix reflog message after skipping","startedAt":"2022-02-21T11:21:20Z","lastAt":"2022-10-26T16:55:06Z","messageCount":73,"participants":["Phillip Wood via GitGitGadget","Phillip Wood","Christian Couder","Elijah Newren","Ævar Arnfjörð Bjarmason","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":7},"messages":[{"id":"448968","messageId":"f4e6e94bc2c894f369546d16d147d970b71554e7.1645441854.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.git.1645441854.gitgitgadget@gmail.com","subject":"[PATCH 3/7] rebase --merge: fix reflog message after skipping","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-21T11:10:50Z","receivedAt":"2022-02-21T11:21:20Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe reflog message for every pick after running \"rebase --skip\" looks\nlike\n\n\trebase (skip) (pick): commit subject line\n\nFix this by not appending \" (skip)\" to the reflog action.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          |  2 --\n t/t3406-rebase-message.sh | 24 ++++++++++++++++++++++++\n 2 files changed, 24 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex cd9a4f3e2f1..36863117fba 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1273,8 +1273,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n \n \t\toptions.action = \"skip\";\n-\t\tset_reflog_action(&options);\n-\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \t\tropts.flags = RESET_HEAD_HARD;\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 3ca2fbb0d59..8aa6a79acc1 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -163,6 +163,30 @@ test_reflog () {\n \t# check there is only one new entry in the branch reflog\n \ttest_cmp_rev fast-forward@{1} X\n \t'\n+\n+\ttest_expect_success \"rebase $mode --skip reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout conflicts &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\tgit rebase --skip\n+\t) &&\n+\n+\tgit log -g --format=%gs -4 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n+\t${reflog_action:-rebase} (pick): Q\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n+\tEOF\n+\ttest_cmp expect actual\n+\t'\n }\n \n test_reflog --merge\n-- \ngitgitgadget\n\n"},{"id":"448969","messageId":"58c560d0e19a3fa6dd5de547821c9642089de3fb.1645441854.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.git.1645441854.gitgitgadget@gmail.com","subject":"[PATCH 4/7] rebase --apply: respect GIT_REFLOG_ACTION","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-21T11:10:51Z","receivedAt":"2022-02-21T11:21:26Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe reflog messages when finishing a rebase hard code \"rebase\" rather\nthan using GIT_REFLOG_ACTION.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 7 ++++---\n t/t3406-rebase-message.sh | 2 +-\n 2 files changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 36863117fba..e50361fc2a9 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -580,10 +580,11 @@ static int move_to_original_branch(struct rebase_options *opts)\n \tif (!opts->onto)\n \t\tBUG(\"move_to_original_branch without onto\");\n \n-\tstrbuf_addf(&branch_reflog, \"rebase finished: %s onto %s\",\n+\tstrbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n+\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n \t\t    opts->head_name, oid_to_hex(&opts->onto->object.oid));\n-\tstrbuf_addf(&head_reflog, \"rebase finished: returning to %s\",\n-\t\t    opts->head_name);\n+\tstrbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n+\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n \tropts.branch = opts->head_name;\n \tropts.flags = RESET_HEAD_REFS_ONLY;\n \tropts.branch_msg = branch_reflog.buf;\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 8aa6a79acc1..bb2a4949abc 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -88,7 +88,7 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n write_reflog_expect () {\n \tif test $mode = --apply\n \tthen\n-\t\tsed 's/.*(finish)/rebase finished/; s/ ([^)]*)//'\n+\t\tsed 's/(finish)/finished/; s/ ([^)]*)//'\n \telse\n \t\tcat\n \tfi >expect\n-- \ngitgitgadget\n\n"},{"id":"448970","messageId":"d26a221a79d2e0b5ec0cee46a68a3b2caa195842.1645441854.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.git.1645441854.gitgitgadget@gmail.com","subject":"[PATCH 7/7] rebase: cleanup action handling","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-21T11:10:54Z","receivedAt":"2022-02-21T11:21:28Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nTreating the action as a string is a hang over from the scripted\nrebase. The last commit removed the only remaining use of the action\nthat required a string so lets convert the other action users to use\nthe existing action enum instead. If we ever need the action name as a\nstring in the future the action_names array exists exactly for that\npurpose.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c | 91 +++++++++++++++++++++++-------------------------\n 1 file changed, 43 insertions(+), 48 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 70426e17b40..323f5154092 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -58,6 +58,26 @@ enum empty_type {\n \tEMPTY_ASK\n };\n \n+enum action {\n+\tACTION_NONE = 0,\n+\tACTION_CONTINUE,\n+\tACTION_SKIP,\n+\tACTION_ABORT,\n+\tACTION_QUIT,\n+\tACTION_EDIT_TODO,\n+\tACTION_SHOW_CURRENT_PATCH\n+};\n+\n+static const char *action_names[] = {\n+\t\"undefined\",\n+\t\"continue\",\n+\t\"skip\",\n+\t\"abort\",\n+\t\"quit\",\n+\t\"edit_todo\",\n+\t\"show_current_patch\"\n+};\n+\n struct rebase_options {\n \tenum rebase_type type;\n \tenum empty_type empty;\n@@ -84,7 +104,7 @@ struct rebase_options {\n \t\tREBASE_INTERACTIVE_EXPLICIT = 1<<4,\n \t} flags;\n \tstruct strvec git_am_opts;\n-\tconst char *action;\n+\tenum action action;\n \tint signoff;\n \tint allow_rerere_autoupdate;\n \tint keep_empty;\n@@ -155,24 +175,6 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)\n \treturn replay;\n }\n \n-enum action {\n-\tACTION_NONE = 0,\n-\tACTION_CONTINUE,\n-\tACTION_SKIP,\n-\tACTION_ABORT,\n-\tACTION_QUIT,\n-\tACTION_EDIT_TODO,\n-\tACTION_SHOW_CURRENT_PATCH\n-};\n-\n-static const char *action_names[] = { \"undefined\",\n-\t\t\t\t      \"continue\",\n-\t\t\t\t      \"skip\",\n-\t\t\t\t      \"abort\",\n-\t\t\t\t      \"quit\",\n-\t\t\t\t      \"edit_todo\",\n-\t\t\t\t      \"show_current_patch\" };\n-\n static int edit_todo_file(unsigned flags)\n {\n \tconst char *todo_file = rebase_path_todo();\n@@ -309,8 +311,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)\n \treturn ret;\n }\n \n-static int run_sequencer_rebase(struct rebase_options *opts,\n-\t\t\t\t  enum action command)\n+static int run_sequencer_rebase(struct rebase_options *opts)\n {\n \tunsigned flags = 0;\n \tint abbreviate_commands = 0, ret = 0;\n@@ -325,7 +326,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n \tflags |= opts->reapply_cherry_picks ? TODO_LIST_REAPPLY_CHERRY_PICKS : 0;\n \tflags |= opts->flags & REBASE_NO_QUIET ? TODO_LIST_WARN_SKIPPED_CHERRY_PICKS : 0;\n \n-\tswitch (command) {\n+\tswitch (opts->action) {\n \tcase ACTION_NONE: {\n \t\tif (!opts->onto && !opts->upstream)\n \t\t\tdie(_(\"a base commit must be provided with --upstream or --onto\"));\n@@ -358,7 +359,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n \t\tbreak;\n \t}\n \tdefault:\n-\t\tBUG(\"invalid command '%d'\", command);\n+\t\tBUG(\"invalid command '%d'\", opts->action);\n \t}\n \n \treturn ret;\n@@ -615,7 +616,7 @@ static int run_am(struct rebase_options *opts)\n \tstrvec_push(&am.args, \"am\");\n \tstrvec_pushf(&am.env_array, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n \t\t     getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n-\tif (opts->action && !strcmp(\"continue\", opts->action)) {\n+\tif (opts->action == ACTION_CONTINUE) {\n \t\tstrvec_push(&am.args, \"--resolved\");\n \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n \t\tif (opts->gpg_sign_opt)\n@@ -626,7 +627,7 @@ static int run_am(struct rebase_options *opts)\n \n \t\treturn move_to_original_branch(opts);\n \t}\n-\tif (opts->action && !strcmp(\"skip\", opts->action)) {\n+\tif (opts->action == ACTION_SKIP) {\n \t\tstrvec_push(&am.args, \"--skip\");\n \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n \t\tstatus = run_command(&am);\n@@ -635,7 +636,7 @@ static int run_am(struct rebase_options *opts)\n \n \t\treturn move_to_original_branch(opts);\n \t}\n-\tif (opts->action && !strcmp(\"show-current-patch\", opts->action)) {\n+\tif (opts->action == ACTION_SHOW_CURRENT_PATCH) {\n \t\tstrvec_push(&am.args, \"--show-current-patch\");\n \t\treturn run_command(&am);\n \t}\n@@ -728,7 +729,7 @@ static int run_am(struct rebase_options *opts)\n \treturn status;\n }\n \n-static int run_specific_rebase(struct rebase_options *opts, enum action action)\n+static int run_specific_rebase(struct rebase_options *opts)\n {\n \tint status;\n \n@@ -746,7 +747,7 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n \t\t\topts->gpg_sign_opt = tmp;\n \t\t}\n \n-\t\tstatus = run_sequencer_rebase(opts, action);\n+\t\tstatus = run_sequencer_rebase(opts);\n \t} else if (opts->type == REBASE_APPLY)\n \t\tstatus = run_am(opts);\n \telse\n@@ -1016,7 +1017,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct object_id merge_base;\n \tint ignore_whitespace = 0;\n-\tenum action action = ACTION_NONE;\n \tconst char *gpg_sign = NULL;\n \tstruct string_list exec = STRING_LIST_INIT_NODUP;\n \tconst char *rebase_merges = NULL;\n@@ -1065,18 +1065,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tOPT_BIT(0, \"no-ff\", &options.flags,\n \t\t\tN_(\"cherry-pick all commits, even if unchanged\"),\n \t\t\tREBASE_FORCE),\n-\t\tOPT_CMDMODE(0, \"continue\", &action, N_(\"continue\"),\n+\t\tOPT_CMDMODE(0, \"continue\", &options.action, N_(\"continue\"),\n \t\t\t    ACTION_CONTINUE),\n-\t\tOPT_CMDMODE(0, \"skip\", &action,\n+\t\tOPT_CMDMODE(0, \"skip\", &options.action,\n \t\t\t    N_(\"skip current patch and continue\"), ACTION_SKIP),\n-\t\tOPT_CMDMODE(0, \"abort\", &action,\n+\t\tOPT_CMDMODE(0, \"abort\", &options.action,\n \t\t\t    N_(\"abort and check out the original branch\"),\n \t\t\t    ACTION_ABORT),\n-\t\tOPT_CMDMODE(0, \"quit\", &action,\n+\t\tOPT_CMDMODE(0, \"quit\", &options.action,\n \t\t\t    N_(\"abort but keep HEAD where it is\"), ACTION_QUIT),\n-\t\tOPT_CMDMODE(0, \"edit-todo\", &action, N_(\"edit the todo list \"\n+\t\tOPT_CMDMODE(0, \"edit-todo\", &options.action, N_(\"edit the todo list \"\n \t\t\t    \"during an interactive rebase\"), ACTION_EDIT_TODO),\n-\t\tOPT_CMDMODE(0, \"show-current-patch\", &action,\n+\t\tOPT_CMDMODE(0, \"show-current-patch\", &options.action,\n \t\t\t    N_(\"show the patch file being applied or merged\"),\n \t\t\t    ACTION_SHOW_CURRENT_PATCH),\n \t\tOPT_CALLBACK_F(0, \"apply\", &options, NULL,\n@@ -1189,7 +1189,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tif (preserve_merges_selected)\n \t\tdie(_(\"--preserve-merges was replaced by --rebase-merges\"));\n \n-\tif (action != ACTION_NONE && total_argc != 2) {\n+\tif (options.action != ACTION_NONE && total_argc != 2) {\n \t\tusage_with_options(builtin_rebase_usage,\n \t\t\t\t   builtin_rebase_options);\n \t}\n@@ -1208,11 +1208,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tif (options.root && options.fork_point > 0)\n \t\tdie(_(\"cannot combine '--root' with '--fork-point'\"));\n \n-\tif (action != ACTION_NONE && !in_progress)\n+\tif (options.action != ACTION_NONE && !in_progress)\n \t\tdie(_(\"No rebase in progress?\"));\n \tsetenv(GIT_REFLOG_ACTION_ENVIRONMENT, \"rebase\", 0);\n \n-\tif (action == ACTION_EDIT_TODO && !is_merge(&options))\n+\tif (options.action == ACTION_EDIT_TODO && !is_merge(&options))\n \t\tdie(_(\"The --edit-todo action can only be used during \"\n \t\t      \"interactive rebase.\"));\n \n@@ -1222,16 +1222,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\telse if (exec.nr)\n \t\t\ttrace2_cmd_mode(\"interactive-exec\");\n \t\telse\n-\t\t\ttrace2_cmd_mode(action_names[action]);\n+\t\t\ttrace2_cmd_mode(action_names[options.action]);\n \t}\n \n-\tswitch (action) {\n+\tswitch (options.action) {\n \tcase ACTION_CONTINUE: {\n \t\tstruct object_id head;\n \t\tstruct lock_file lock_file = LOCK_INIT;\n \t\tint fd;\n \n-\t\toptions.action = \"continue\";\n \t\t/* Sanity check */\n \t\tif (get_oid(\"HEAD\", &head))\n \t\t\tdie(_(\"Cannot read HEAD\"));\n@@ -1257,7 +1256,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tcase ACTION_SKIP: {\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n \n-\t\toptions.action = \"skip\";\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \t\tropts.flags = RESET_HEAD_HARD;\n@@ -1272,7 +1270,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n \t\tstruct strbuf head_msg = STRBUF_INIT;\n \n-\t\toptions.action = \"abort\";\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \n@@ -1312,17 +1309,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tgoto cleanup;\n \t}\n \tcase ACTION_EDIT_TODO:\n-\t\toptions.action = \"edit-todo\";\n \t\toptions.dont_finish_rebase = 1;\n \t\tgoto run_rebase;\n \tcase ACTION_SHOW_CURRENT_PATCH:\n-\t\toptions.action = \"show-current-patch\";\n \t\toptions.dont_finish_rebase = 1;\n \t\tgoto run_rebase;\n \tcase ACTION_NONE:\n \t\tbreak;\n \tdefault:\n-\t\tBUG(\"action: %d\", action);\n+\t\tBUG(\"action: %d\", options.action);\n \t}\n \n \t/* Make sure no rebase is in progress */\n@@ -1346,7 +1341,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif ((options.flags & REBASE_INTERACTIVE_EXPLICIT) ||\n-\t    (action != ACTION_NONE) ||\n+\t    (options.action != ACTION_NONE) ||\n \t    (exec.nr > 0) ||\n \t    options.autosquash) {\n \t\tallow_preemptive_ff = 0;\n@@ -1786,7 +1781,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \toptions.revisions = revisions.buf;\n \n run_rebase:\n-\tret = run_specific_rebase(&options, action);\n+\tret = run_specific_rebase(&options);\n \n cleanup:\n \tstrbuf_release(&buf);\n-- \ngitgitgadget\n"},{"id":"448971","messageId":"1c3ec1654225ff090c194fa646f974082bd9c944.1645441854.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.git.1645441854.gitgitgadget@gmail.com","subject":"[PATCH 5/7] rebase --apply: make reflog messages match rebase --merge","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-21T11:10:52Z","receivedAt":"2022-02-21T11:21:32Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe apply backend creates slightly different reflog messages to the\nmerge backend when starting and finishing a rebase and when picking\ncommits. The choice of backend is really an implementation detail so\nit is confusing to have the same command create different messages\ndepending on which backend is selected. Change the apply backend so\nthe reflog messages from the two backends match as closely as\npossible. Note that there is still a difference when committing a\nconflict resolution - the merge backend will use \"(continue)\" rather\nthan \"(pick)\" in that case as it does not know which command created\nthe conflict that it is committing.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 9 +++++----\n t/t3406-rebase-message.sh | 2 +-\n 2 files changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex e50361fc2a9..678339c7bf7 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -580,10 +580,10 @@ static int move_to_original_branch(struct rebase_options *opts)\n \tif (!opts->onto)\n \t\tBUG(\"move_to_original_branch without onto\");\n \n-\tstrbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n+\tstrbuf_addf(&branch_reflog, \"%s (finish): %s onto %s\",\n \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n \t\t    opts->head_name, oid_to_hex(&opts->onto->object.oid));\n-\tstrbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n+\tstrbuf_addf(&head_reflog, \"%s (finish): returning to %s\",\n \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n \tropts.branch = opts->head_name;\n \tropts.flags = RESET_HEAD_REFS_ONLY;\n@@ -613,7 +613,8 @@ static int run_am(struct rebase_options *opts)\n \n \tam.git_cmd = 1;\n \tstrvec_push(&am.args, \"am\");\n-\n+\tstrvec_pushf(&am.env_array, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n+\t\t     getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n \t\tstrvec_push(&am.args, \"--resolved\");\n \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n@@ -1763,7 +1764,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tprintf(_(\"First, rewinding head to replay your work on top of \"\n \t\t\t \"it...\\n\"));\n \n-\tstrbuf_addf(&msg, \"%s: checkout %s\",\n+\tstrbuf_addf(&msg, \"%s (start): checkout %s\",\n \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);\n \tropts.oid = &options.onto->object.oid;\n \tropts.orig_head = &options.orig_head,\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex bb2a4949abc..5c6cd9af3bc 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -88,7 +88,7 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n write_reflog_expect () {\n \tif test $mode = --apply\n \tthen\n-\t\tsed 's/(finish)/finished/; s/ ([^)]*)//'\n+\t\tsed 's/(continue)/(pick)/'\n \telse\n \t\tcat\n \tfi >expect\n-- \ngitgitgadget\n\n"},{"id":"448972","messageId":"493254ffbb8b11f325f5995790341d70198b5c97.1645441854.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.git.1645441854.gitgitgadget@gmail.com","subject":"[PATCH 2/7] rebase --merge: fix reflog when continuing","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-21T11:10:49Z","receivedAt":"2022-02-21T11:21:35Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe reflog message for a conflict resolution committed by \"rebase\n--continue\" looks like\n\n\trebase (continue): commit subject line\n\nUnfortunately the reflog message each subsequent pick look like\n\n\trebase (continue) (pick): commit subject line\n\nFix this by setting the reflog message for \"rebase --continue\" in\nsequencer_continue() so it does not affect subsequent commits. This\nintroduces a memory leak similar to the one leaking GIT_REFLOG_ACTION\nin pick_commits(). Both of these will be fixed in a future series that\nstops the sequencer calling setenv().\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          |   2 -\n sequencer.c               |   5 ++\n t/t3406-rebase-message.sh | 120 +++++++++++++++++++++++++-------------\n 3 files changed, 86 insertions(+), 41 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 4832f16e675..cd9a4f3e2f1 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1247,8 +1247,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tint fd;\n \n \t\toptions.action = \"continue\";\n-\t\tset_reflog_action(&options);\n-\n \t\t/* Sanity check */\n \t\tif (get_oid(\"HEAD\", &head))\n \t\t\tdie(_(\"Cannot read HEAD\"));\ndiff --git a/sequencer.c b/sequencer.c\nindex bdd66b4b67a..3634ad5baa9 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -4777,6 +4777,8 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \tif (read_populate_opts(opts))\n \t\treturn -1;\n \tif (is_rebase_i(opts)) {\n+\t\tchar *previous_reflog_action;\n+\n \t\tif ((res = read_populate_todo(r, &todo_list, opts)))\n \t\t\tgoto release_todo_list;\n \n@@ -4787,10 +4789,13 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \t\t\tunlink(rebase_path_dropped());\n \t\t}\n \n+\t\tprevious_reflog_action = xstrdup(getenv(GIT_REFLOG_ACTION));\n+\t\tsetenv(GIT_REFLOG_ACTION, reflog_message(opts, \"continue\", NULL), 1);\n \t\tif (commit_staged_changes(r, opts, &todo_list)) {\n \t\t\tres = -1;\n \t\t\tgoto release_todo_list;\n \t\t}\n+\t\tsetenv(GIT_REFLOG_ACTION, previous_reflog_action, 1);\n \t} else if (!file_exists(get_todo_path(opts)))\n \t\treturn continue_single_pick(r, opts);\n \telse if ((res = read_populate_todo(r, &todo_list, opts)))\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex d17b450e811..3ca2fbb0d59 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -10,10 +10,16 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n test_expect_success 'setup' '\n \ttest_commit O fileO &&\n \ttest_commit X fileX &&\n+\tgit branch fast-forward &&\n \ttest_commit A fileA &&\n \ttest_commit B fileB &&\n \ttest_commit Y fileY &&\n \n+\tgit checkout -b conflicts O &&\n+\ttest_commit P &&\n+\ttest_commit conflict-X fileX &&\n+\ttest_commit Q &&\n+\n \tgit checkout -b topic O &&\n \tgit cherry-pick A B &&\n \ttest_commit Z fileZ &&\n@@ -79,54 +85,90 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n \ttest_i18ngrep \"Invalid whitespace option\" err\n '\n \n-test_expect_success 'GIT_REFLOG_ACTION' '\n-\tgit checkout start &&\n-\ttest_commit reflog-onto &&\n-\tgit checkout -b reflog-topic start &&\n-\ttest_commit reflog-to-rebase &&\n-\n-\tgit rebase reflog-onto &&\n-\tgit log -g --format=%gs -3 >actual &&\n-\tcat >expect <<-\\EOF &&\n-\trebase (finish): returning to refs/heads/reflog-topic\n-\trebase (pick): reflog-to-rebase\n-\trebase (start): checkout reflog-onto\n+write_reflog_expect () {\n+\tif test $mode = --apply\n+\tthen\n+\t\tsed 's/.*(finish)/rebase finished/; s/ ([^)]*)//'\n+\telse\n+\t\tcat\n+\tfi >expect\n+}\n+\n+test_reflog () {\n+\tmode=$1\n+\treflog_action=\"$2\"\n+\n+\ttest_expect_success \"rebase $mode reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout conflicts &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\techo resolved >fileX &&\n+\t\tgit add fileX &&\n+\t\tgit rebase --continue\n+\t) &&\n+\n+\tgit log -g --format=%gs -5 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n+\t${reflog_action:-rebase} (pick): Q\n+\t${reflog_action:-rebase} (continue): conflict-X\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n \tEOF\n \ttest_cmp expect actual &&\n \n-\tgit checkout -b reflog-prefix reflog-to-rebase &&\n-\tGIT_REFLOG_ACTION=change-the-reflog git rebase reflog-onto &&\n-\tgit log -g --format=%gs -3 >actual &&\n-\tcat >expect <<-\\EOF &&\n-\tchange-the-reflog (finish): returning to refs/heads/reflog-prefix\n-\tchange-the-reflog (pick): reflog-to-rebase\n-\tchange-the-reflog (start): checkout reflog-onto\n+\tgit log -g --format=%gs -1 conflicts >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): refs/heads/conflicts onto $(git rev-parse main)\n \tEOF\n-\ttest_cmp expect actual\n-'\n-\n-test_expect_success 'rebase --apply reflog' '\n-\tgit checkout -b reflog-apply start &&\n-\told_head_reflog=\"$(git log -g --format=%gs -1 HEAD)\" &&\n-\n-\tgit rebase --apply Y &&\n+\ttest_cmp expect actual &&\n \n-\tgit log -g --format=%gs -4 HEAD >actual &&\n-\tcat >expect <<-EOF &&\n-\trebase finished: returning to refs/heads/reflog-apply\n-\trebase: Z\n-\trebase: checkout Y\n-\t$old_head_reflog\n+\t# check there is only one new entry in the branch reflog\n+\ttest_cmp_rev conflicts@{1} Q\n+\t'\n+\n+\ttest_expect_success \"rebase $mode fast-forward reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout fast-forward &&\n+\ttest_when_finished \"git reset --hard X\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\tgit rebase $mode main\n+\t) &&\n+\n+\tgit log -g --format=%gs -2 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): returning to refs/heads/fast-forward\n+\t${reflog_action:-rebase} (start): checkout main\n \tEOF\n \ttest_cmp expect actual &&\n \n-\tgit log -g --format=%gs -2 reflog-apply >actual &&\n-\tcat >expect <<-EOF &&\n-\trebase finished: refs/heads/reflog-apply onto $(git rev-parse Y)\n-\tbranch: Created from start\n+\tgit log -g --format=%gs -1 fast-forward >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): refs/heads/fast-forward onto $(git rev-parse main)\n \tEOF\n-\ttest_cmp expect actual\n-'\n+\ttest_cmp expect actual &&\n+\n+\t# check there is only one new entry in the branch reflog\n+\ttest_cmp_rev fast-forward@{1} X\n+\t'\n+}\n+\n+test_reflog --merge\n+test_reflog --merge my-reflog-action\n+test_reflog --apply\n+test_reflog --apply my-reflog-action\n \n test_expect_success 'rebase -i onto unrelated history' '\n \tgit init unrelated &&\n-- \ngitgitgadget\n\n"},{"id":"448973","messageId":"243e7b0c372c15cc907c838ee74794433aa79858.1645441854.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.git.1645441854.gitgitgadget@gmail.com","subject":"[PATCH 1/7] rebase --apply: remove duplicated code","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-21T11:10:48Z","receivedAt":"2022-02-21T11:21:36Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nWhen we are reattaching HEAD after a fast-forward we can use\nmove_to_original_branch() rather than open coding a copy of that\ncode. The old code appears to handle the case where the rebase is\nstarted from a detached HEAD but in fact in that case there is nothing\nto do as we have already updated HEAD.\n\nNote that the removal of \"strbuf_release(&msg)\" is safe as there is an\nidentical call just above this hunk.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c | 11 +----------\n 1 file changed, 1 insertion(+), 10 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex e942c300f8c..4832f16e675 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1782,19 +1782,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t * If the onto is a proper descendant of the tip of the branch, then\n \t * we just fast-forwarded.\n \t */\n-\tstrbuf_reset(&msg);\n \tif (oideq(&merge_base, &options.orig_head)) {\n \t\tprintf(_(\"Fast-forwarded %s to %s.\\n\"),\n \t\t\tbranch_name, options.onto_name);\n-\t\tstrbuf_addf(&msg, \"rebase finished: %s onto %s\",\n-\t\t\toptions.head_name ? options.head_name : \"detached HEAD\",\n-\t\t\toid_to_hex(&options.onto->object.oid));\n-\t\tmemset(&ropts, 0, sizeof(ropts));\n-\t\tropts.branch = options.head_name;\n-\t\tropts.flags = RESET_HEAD_REFS_ONLY;\n-\t\tropts.head_msg = msg.buf;\n-\t\treset_head(the_repository, &ropts);\n-\t\tstrbuf_release(&msg);\n+\t\tmove_to_original_branch(&options);\n \t\tret = finish_rebase(&options);\n \t\tgoto cleanup;\n \t}\n-- \ngitgitgadget\n\n"},{"id":"448974","messageId":"pull.1150.git.1645441854.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":null,"subject":"[PATCH 0/7] rebase: make reflog messages independent of the backend","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-21T11:10:47Z","receivedAt":"2022-02-21T11:21:38Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"This is a series of rebase reflog related patches with the aim of unifying\nthe reflog messages from the two rebase backends.\n\n * improve rebase reflog test coverage\n * rebase --merge: fix reflog messages for --continue and --skip\n * rebase --apply: respect GIT_REFLOG_ACTION\n * rebase --abort: improve reflog message\n * unify reflog messages between the two rebase backends\n\nThis series is based on pw/use-inprocess-checkout-in-rebase\n\nPhillip Wood (7):\n  rebase --apply: remove duplicated code\n  rebase --merge: fix reflog when continuing\n  rebase --merge: fix reflog message after skipping\n  rebase --apply: respect GIT_REFLOG_ACTION\n  rebase --apply: make reflog messages match rebase --merge\n  rebase --abort: improve reflog message\n  rebase: cleanup action handling\n\n builtin/rebase.c          | 144 ++++++++++++-----------------\n sequencer.c               |   5 ++\n t/t3406-rebase-message.sh | 185 +++++++++++++++++++++++++++++++-------\n 3 files changed, 214 insertions(+), 120 deletions(-)\n\n\nbase-commit: 38c541ce94048cf72aa4f465be9314423a57f445\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1150%2Fphillipwood%2Fwip%2Frebase-reflog-fixes-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1150/phillipwood/wip/rebase-reflog-fixes-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/1150\n-- \ngitgitgadget\n"},{"id":"448975","messageId":"c863cebbdc8485225af40593cf2952c933f4ea8d.1645441854.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.git.1645441854.gitgitgadget@gmail.com","subject":"[PATCH 6/7] rebase --abort: improve reflog message","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-21T11:10:53Z","receivedAt":"2022-02-21T11:21:39Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nWhen aborting a rebase the reflog message looks like\n\n\trebase (abort): updating HEAD\n\nwhich is not very informative. Improve the message by mentioning the\nbranch that we are returning to as we do at the end of a successful\nrebase so it looks like.\n\n\trebase (abort): returning to refs/heads/topic\n\nIf GIT_REFLOG_ACTION is set in the environment we no longer omit\n\"(abort)\" from the reflog message. We don't omit \"(start)\" and\n\"(finish)\" when starting and finishing a rebase in that case so we\nshouldn't omit \"(abort)\".\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 28 ++++++---------------\n t/t3406-rebase-message.sh | 51 +++++++++++++++++++++++++++++++++++++++\n 2 files changed, 59 insertions(+), 20 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 678339c7bf7..70426e17b40 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -992,23 +992,6 @@ static void NORETURN error_on_missing_default_upstream(void)\n \texit(1);\n }\n \n-static void set_reflog_action(struct rebase_options *options)\n-{\n-\tconst char *env;\n-\tstruct strbuf buf = STRBUF_INIT;\n-\n-\tif (!is_merge(options))\n-\t\treturn;\n-\n-\tenv = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);\n-\tif (env && strcmp(\"rebase\", env))\n-\t\treturn; /* only override it if it is \"rebase\" */\n-\n-\tstrbuf_addf(&buf, \"rebase (%s)\", options->action);\n-\tsetenv(GIT_REFLOG_ACTION_ENVIRONMENT, buf.buf, 1);\n-\tstrbuf_release(&buf);\n-}\n-\n static int check_exec_cmd(const char *cmd)\n {\n \tif (strchr(cmd, '\\n'))\n@@ -1287,18 +1270,23 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t}\n \tcase ACTION_ABORT: {\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n-\t\toptions.action = \"abort\";\n-\t\tset_reflog_action(&options);\n+\t\tstruct strbuf head_msg = STRBUF_INIT;\n \n+\t\toptions.action = \"abort\";\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \n \t\tif (read_basic_state(&options))\n \t\t\texit(1);\n+\n+\t\tstrbuf_addf(&head_msg, \"%s (abort): returning to %s\",\n+\t\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n+\t\t\t    options.head_name ? options.head_name\n+\t\t\t\t\t      : oid_to_hex(&options.orig_head));\n \t\tropts.oid = &options.orig_head;\n+\t\tropts.head_msg = head_msg.buf;\n \t\tropts.branch = options.head_name;\n \t\tropts.flags = RESET_HEAD_HARD;\n-\t\tropts.default_reflog_action = DEFAULT_REFLOG_ACTION;\n \t\tif (reset_head(the_repository, &ropts) < 0)\n \t\t\tdie(_(\"could not move back to %s\"),\n \t\t\t    oid_to_hex(&options.orig_head));\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 5c6cd9af3bc..ceca1600053 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -187,6 +187,57 @@ test_reflog () {\n \tEOF\n \ttest_cmp expect actual\n \t'\n+\n+\ttest_expect_success \"rebase $mode --abort reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout conflicts &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\tgit log -g -1 conflicts >branch-expect &&\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\tgit rebase --abort\n+\t) &&\n+\n+\tgit log -g --format=%gs -3 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (abort): returning to refs/heads/conflicts\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n+\tEOF\n+\ttest_cmp expect actual &&\n+\n+\t# check branch reflog is unchanged\n+\tgit log -g -1 conflicts >branch-actual &&\n+\ttest_cmp branch-expect branch-actual\n+\t'\n+\n+\ttest_expect_success \"rebase $mode --abort detached HEAD reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout Q &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\tgit rebase --abort\n+\t) &&\n+\n+\tgit log -g --format=%gs -3 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (abort): returning to $(git rev-parse Q)\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n+\tEOF\n+\ttest_cmp expect actual\n+\t'\n }\n \n test_reflog --merge\n-- \ngitgitgadget\n\n"},{"id":"453037","messageId":"64cae3bc-e1b9-d118-2d78-208dc772f74a@gmail.com","threadId":"57450","inReplyTo":"pull.1150.git.1645441854.gitgitgadget@gmail.com","subject":"Review Request (was Re: [PATCH 0/7] rebase: make reflog messages independent of the backend)","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2022-04-04T15:34:18Z","receivedAt":"2022-04-04T15:34:30Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"If anyone has time to review these patches I'd be very grateful. I've \ncc'd this message to some list regulars who have reviewed rebase patches \nbefore but if anyone else fancies taking a look at them that would be great.\n\nThanks\n\nPhillip\n\nOn 21/02/2022 11:10, Phillip Wood via GitGitGadget wrote:\n> This is a series of rebase reflog related patches with the aim of unifying\n> the reflog messages from the two rebase backends.\n> \n>   * improve rebase reflog test coverage\n>   * rebase --merge: fix reflog messages for --continue and --skip\n>   * rebase --apply: respect GIT_REFLOG_ACTION\n>   * rebase --abort: improve reflog message\n>   * unify reflog messages between the two rebase backends\n> \n> This series is based on pw/use-inprocess-checkout-in-rebase\n> \n> Phillip Wood (7):\n>    rebase --apply: remove duplicated code\n>    rebase --merge: fix reflog when continuing\n>    rebase --merge: fix reflog message after skipping\n>    rebase --apply: respect GIT_REFLOG_ACTION\n>    rebase --apply: make reflog messages match rebase --merge\n>    rebase --abort: improve reflog message\n>    rebase: cleanup action handling\n> \n>   builtin/rebase.c          | 144 ++++++++++++-----------------\n>   sequencer.c               |   5 ++\n>   t/t3406-rebase-message.sh | 185 +++++++++++++++++++++++++++++++-------\n>   3 files changed, 214 insertions(+), 120 deletions(-)\n> \n> \n> base-commit: 38c541ce94048cf72aa4f465be9314423a57f445\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1150%2Fphillipwood%2Fwip%2Frebase-reflog-fixes-v1\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1150/phillipwood/wip/rebase-reflog-fixes-v1\n> Pull-Request: https://github.com/gitgitgadget/git/pull/1150\n"},{"id":"453260","messageId":"CAP8UFD25KjNYuMoVb72N2kGmo3yJ0qGgfJn78axc562Z+YhAGQ@mail.gmail.com","threadId":"57450","inReplyTo":"243e7b0c372c15cc907c838ee74794433aa79858.1645441854.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 1/7] rebase --apply: remove duplicated code","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2022-04-07T13:35:47Z","receivedAt":"2022-04-07T13:36:49Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Tue, Feb 22, 2022 at 6:34 AM Phillip Wood via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> When we are reattaching HEAD after a fast-forward we can use\n> move_to_original_branch() rather than open coding a copy of that\n> code.\n\nNit: maybe \"rebase --apply: reuse move_to_original_branch()\" would be\na better subject for this patch, as it's more specific.\n\n> The old code appears to handle the case where the rebase is\n> started from a detached HEAD but in fact in that case there is nothing\n> to do as we have already updated HEAD.\n>\n> Note that the removal of \"strbuf_release(&msg)\" is safe as there is an\n> identical call just above this hunk.\n\nIt looks like the removed call is using strbuf_reset(), not strbuf_release().\n\nActually a call to strbuf_release(&msg) is also removed inside the `if\n(oideq(&merge_base, &options.orig_head)) { ... }` clause, but it\ndoesn't look like you are talking about this one.\n\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  builtin/rebase.c | 11 +----------\n>  1 file changed, 1 insertion(+), 10 deletions(-)\n>\n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index e942c300f8c..4832f16e675 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -1782,19 +1782,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>          * If the onto is a proper descendant of the tip of the branch, then\n>          * we just fast-forwarded.\n>          */\n> -       strbuf_reset(&msg);\n\nYeah, it looks like `msg` isn't used in the function anymore so this\ncall can be removed.\n\n>         if (oideq(&merge_base, &options.orig_head)) {\n>                 printf(_(\"Fast-forwarded %s to %s.\\n\"),\n>                         branch_name, options.onto_name);\n> -               strbuf_addf(&msg, \"rebase finished: %s onto %s\",\n> -                       options.head_name ? options.head_name : \"detached HEAD\",\n> -                       oid_to_hex(&options.onto->object.oid));\n> -               memset(&ropts, 0, sizeof(ropts));\n> -               ropts.branch = options.head_name;\n> -               ropts.flags = RESET_HEAD_REFS_ONLY;\n> -               ropts.head_msg = msg.buf;\n> -               reset_head(the_repository, &ropts);\n> -               strbuf_release(&msg);\n> +               move_to_original_branch(&options);\n>                 ret = finish_rebase(&options);\n>                 goto cleanup;\n>         }\n\nNice cleanup!\n"},{"id":"453261","messageId":"CAP8UFD0+V38FC8HZenFVRUputH+eD5cfXAQUZug3RWWMv==LBw@mail.gmail.com","threadId":"57450","inReplyTo":"493254ffbb8b11f325f5995790341d70198b5c97.1645441854.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 2/7] rebase --merge: fix reflog when continuing","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2022-04-07T13:49:14Z","receivedAt":"2022-04-07T13:49:30Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Tue, Feb 22, 2022 at 6:12 AM Phillip Wood via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> The reflog message for a conflict resolution committed by \"rebase\n> --continue\" looks like\n>\n>         rebase (continue): commit subject line\n>\n> Unfortunately the reflog message each subsequent pick look like\n>\n>         rebase (continue) (pick): commit subject line\n>\n> Fix this by setting the reflog message for \"rebase --continue\" in\n> sequencer_continue() so it does not affect subsequent commits. This\n> introduces a memory leak similar to the one leaking GIT_REFLOG_ACTION\n> in pick_commits(). Both of these will be fixed in a future series that\n> stops the sequencer calling setenv().\n\nYeah, it looks like we will leak only a small string.\n\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  builtin/rebase.c          |   2 -\n>  sequencer.c               |   5 ++\n>  t/t3406-rebase-message.sh | 120 +++++++++++++++++++++++++-------------\n\nThe changes to the test script look a bit involved and aren't\nexplained in the commit message. I wonder if some of those changes\ncould have been made in a preparatory commit.\n\n\n>  3 files changed, 86 insertions(+), 41 deletions(-)\n"},{"id":"453262","messageId":"CAP8UFD3dx_Mv=X1y11LDy6NOcV0eDq5s92PqdC3LnbBFCi1kxg@mail.gmail.com","threadId":"57450","inReplyTo":"58c560d0e19a3fa6dd5de547821c9642089de3fb.1645441854.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 4/7] rebase --apply: respect GIT_REFLOG_ACTION","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2022-04-07T13:59:15Z","receivedAt":"2022-04-07T13:59:44Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Tue, Feb 22, 2022 at 6:41 AM Phillip Wood via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> The reflog messages when finishing a rebase hard code \"rebase\" rather\n> than using GIT_REFLOG_ACTION.\n\nYeah, but GIT_REFLOG_ACTION is something like \"pick\" or \"continue\" ...\n\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  builtin/rebase.c          | 7 ++++---\n>  t/t3406-rebase-message.sh | 2 +-\n>  2 files changed, 5 insertions(+), 4 deletions(-)\n>\n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index 36863117fba..e50361fc2a9 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -580,10 +580,11 @@ static int move_to_original_branch(struct rebase_options *opts)\n>         if (!opts->onto)\n>                 BUG(\"move_to_original_branch without onto\");\n>\n> -       strbuf_addf(&branch_reflog, \"rebase finished: %s onto %s\",\n> +       strbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n> +                   getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n>                     opts->head_name, oid_to_hex(&opts->onto->object.oid));\n\n... so this will say \"pick finished...\" instead of \"rebase\nfinished...\" while it may be better to have something like \"rebase\n(pick) finished...\", or am I missing something?\n\n> -       strbuf_addf(&head_reflog, \"rebase finished: returning to %s\",\n> -                   opts->head_name);\n> +       strbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n> +                   getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n\nIn patch 2/7 GIT_REFLOG_ACTION, instead of\nGIT_REFLOG_ACTION_ENVIRONMENT, is used.\n\nIt looks like GIT_REFLOG_ACTION_ENVIRONMENT is defined in reset.h\nwhile GIT_REFLOG_ACTION is defined in sequencer.c. Maybe we could get\nrid of one of these two, and use the same everywhere?\n\n>         ropts.branch = opts->head_name;\n>         ropts.flags = RESET_HEAD_REFS_ONLY;\n>         ropts.branch_msg = branch_reflog.buf;\n"},{"id":"453263","messageId":"CAP8UFD1B53KDP=XoYzd6XmdKK-BN9Of7C2yxPxG_atPhNtZHGQ@mail.gmail.com","threadId":"57450","inReplyTo":"pull.1150.git.1645441854.gitgitgadget@gmail.com","subject":"Re: [PATCH 0/7] rebase: make reflog messages independent of the backend","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2022-04-07T14:15:56Z","receivedAt":"2022-04-07T14:16:10Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Tue, Feb 22, 2022 at 6:04 AM Phillip Wood via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> This is a series of rebase reflog related patches with the aim of unifying\n> the reflog messages from the two rebase backends.\n\nI took a look but might have been lost or confused in the middle, so I\ndidn't look much at the last patches. I think this has a worthwhile\ngoal though.\n"},{"id":"453707","messageId":"cde32b70-2f01-925c-2456-8f45fa8c5188@gmail.com","threadId":"57450","inReplyTo":"CAP8UFD0+V38FC8HZenFVRUputH+eD5cfXAQUZug3RWWMv==LBw@mail.gmail.com","subject":"Re: [PATCH 2/7] rebase --merge: fix reflog when continuing","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2022-04-15T14:00:55Z","receivedAt":"2022-04-15T14:01:01Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Chirstian\n\nThanks for taking a look at this series\n\nOn 07/04/2022 14:49, Christian Couder wrote:\n> On Tue, Feb 22, 2022 at 6:12 AM Phillip Wood via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>>\n>> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>>\n>> The reflog message for a conflict resolution committed by \"rebase\n>> --continue\" looks like\n>>\n>>          rebase (continue): commit subject line\n>>\n>> Unfortunately the reflog message each subsequent pick look like\n>>\n>>          rebase (continue) (pick): commit subject line\n>>\n>> Fix this by setting the reflog message for \"rebase --continue\" in\n>> sequencer_continue() so it does not affect subsequent commits. This\n>> introduces a memory leak similar to the one leaking GIT_REFLOG_ACTION\n>> in pick_commits(). Both of these will be fixed in a future series that\n>> stops the sequencer calling setenv().\n> \n> Yeah, it looks like we will leak only a small string.\n> \n>> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n>> ---\n>>   builtin/rebase.c          |   2 -\n>>   sequencer.c               |   5 ++\n>>   t/t3406-rebase-message.sh | 120 +++++++++++++++++++++++++-------------\n> \n> The changes to the test script look a bit involved and aren't\n> explained in the commit message. I wonder if some of those changes\n> could have been made in a preparatory commit.\n\nThat's a good point. For some reason when I put the series together I \nthought it would be tricky to do that without the fixes in this commit \nbut that is not actually the case so I'll split the test changes out.\n\nBest Wishes\n\nPhillip\n\n> \n>>   3 files changed, 86 insertions(+), 41 deletions(-)\n"},{"id":"453708","messageId":"ef186379-7d59-36e4-068f-b15375e42789@gmail.com","threadId":"57450","inReplyTo":"CAP8UFD3dx_Mv=X1y11LDy6NOcV0eDq5s92PqdC3LnbBFCi1kxg@mail.gmail.com","subject":"Re: [PATCH 4/7] rebase --apply: respect GIT_REFLOG_ACTION","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2022-04-15T14:03:11Z","receivedAt":"2022-04-15T14:03:17Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Christian\n\nOn 07/04/2022 14:59, Christian Couder wrote:\n> On Tue, Feb 22, 2022 at 6:41 AM Phillip Wood via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>>\n>> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>>\n>> The reflog messages when finishing a rebase hard code \"rebase\" rather\n>> than using GIT_REFLOG_ACTION.\n> \n> Yeah, but GIT_REFLOG_ACTION is something like \"pick\" or \"continue\" ...\n\nGIT_REFLOG_ACTION can be set in the environment by the user (or more \nlikely a script) to change the command name in reflog messages created \nby rebase. At the moment we respect that for all the messages apart from \nthe ones being changed here.\n\nBest Wishes\n\nPhillip\n\n>> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n>> ---\n>>   builtin/rebase.c          | 7 ++++---\n>>   t/t3406-rebase-message.sh | 2 +-\n>>   2 files changed, 5 insertions(+), 4 deletions(-)\n>>\n>> diff --git a/builtin/rebase.c b/builtin/rebase.c\n>> index 36863117fba..e50361fc2a9 100644\n>> --- a/builtin/rebase.c\n>> +++ b/builtin/rebase.c\n>> @@ -580,10 +580,11 @@ static int move_to_original_branch(struct rebase_options *opts)\n>>          if (!opts->onto)\n>>                  BUG(\"move_to_original_branch without onto\");\n>>\n>> -       strbuf_addf(&branch_reflog, \"rebase finished: %s onto %s\",\n>> +       strbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n>> +                   getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n>>                      opts->head_name, oid_to_hex(&opts->onto->object.oid));\n> \n> ... so this will say \"pick finished...\" instead of \"rebase\n> finished...\" while it may be better to have something like \"rebase\n> (pick) finished...\", or am I missing something?\n> \n>> -       strbuf_addf(&head_reflog, \"rebase finished: returning to %s\",\n>> -                   opts->head_name);\n>> +       strbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n>> +                   getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n> \n> In patch 2/7 GIT_REFLOG_ACTION, instead of\n> GIT_REFLOG_ACTION_ENVIRONMENT, is used.\n> \n> It looks like GIT_REFLOG_ACTION_ENVIRONMENT is defined in reset.h\n> while GIT_REFLOG_ACTION is defined in sequencer.c. Maybe we could get\n> rid of one of these two, and use the same everywhere?\n> \n>>          ropts.branch = opts->head_name;\n>>          ropts.flags = RESET_HEAD_REFS_ONLY;\n>>          ropts.branch_msg = branch_reflog.buf;\n"},{"id":"453781","messageId":"CABPp-BEX1SJwtxLh8f-Mpc_YeaEs5UJSAZ0+P+Y0ZYKNN=vHAQ@mail.gmail.com","threadId":"57450","inReplyTo":"cde32b70-2f01-925c-2456-8f45fa8c5188@gmail.com","subject":"Re: [PATCH 2/7] rebase --merge: fix reflog when continuing","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-04-17T01:57:26Z","receivedAt":"2022-04-17T01:57:42Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Apr 15, 2022 at 5:23 PM Phillip Wood <phillip.wood123@gmail.com> wrote:\n>\n> Hi Chirstian\n>\n> Thanks for taking a look at this series\n>\n> On 07/04/2022 14:49, Christian Couder wrote:\n> > On Tue, Feb 22, 2022 at 6:12 AM Phillip Wood via GitGitGadget\n> > <gitgitgadget@gmail.com> wrote:\n> >>\n> >> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n> >>\n> >> The reflog message for a conflict resolution committed by \"rebase\n> >> --continue\" looks like\n> >>\n> >>          rebase (continue): commit subject line\n> >>\n> >> Unfortunately the reflog message each subsequent pick look like\n> >>\n> >>          rebase (continue) (pick): commit subject line\n> >>\n> >> Fix this by setting the reflog message for \"rebase --continue\" in\n> >> sequencer_continue() so it does not affect subsequent commits. This\n> >> introduces a memory leak similar to the one leaking GIT_REFLOG_ACTION\n> >> in pick_commits(). Both of these will be fixed in a future series that\n> >> stops the sequencer calling setenv().\n> >\n> > Yeah, it looks like we will leak only a small string.\n> >\n> >> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> >> ---\n> >>   builtin/rebase.c          |   2 -\n> >>   sequencer.c               |   5 ++\n> >>   t/t3406-rebase-message.sh | 120 +++++++++++++++++++++++++-------------\n> >\n> > The changes to the test script look a bit involved and aren't\n> > explained in the commit message. I wonder if some of those changes\n> > could have been made in a preparatory commit.\n>\n> That's a good point. For some reason when I put the series together I\n> thought it would be tricky to do that without the fixes in this commit\n> but that is not actually the case so I'll split the test changes out.\n\nThat would be very nice; I'd like to see it split out too.\n"},{"id":"453782","messageId":"CABPp-BF2p54rcR9xLyZ34-HBPDw6ip08=0rGs3uH=qqSsn0cRA@mail.gmail.com","threadId":"57450","inReplyTo":"CAP8UFD25KjNYuMoVb72N2kGmo3yJ0qGgfJn78axc562Z+YhAGQ@mail.gmail.com","subject":"Re: [PATCH 1/7] rebase --apply: remove duplicated code","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-04-17T01:56:09Z","receivedAt":"2022-04-17T01:57:42Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Apr 7, 2022 at 1:30 PM Christian Couder\n<christian.couder@gmail.com> wrote:\n>\n> On Tue, Feb 22, 2022 at 6:34 AM Phillip Wood via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n> >\n> > From: Phillip Wood <phillip.wood@dunelm.org.uk>\n> >\n> > When we are reattaching HEAD after a fast-forward we can use\n> > move_to_original_branch() rather than open coding a copy of that\n> > code.\n>\n> Nit: maybe \"rebase --apply: reuse move_to_original_branch()\" would be\n> a better subject for this patch, as it's more specific.\n>\n> > The old code appears to handle the case where the rebase is\n> > started from a detached HEAD but in fact in that case there is nothing\n> > to do as we have already updated HEAD.\n> >\n> > Note that the removal of \"strbuf_release(&msg)\" is safe as there is an\n> > identical call just above this hunk.\n>\n> It looks like the removed call is using strbuf_reset(), not strbuf_release().\n>\n> Actually a call to strbuf_release(&msg) is also removed inside the `if\n> (oideq(&merge_base, &options.orig_head)) { ... }` clause, but it\n> doesn't look like you are talking about this one.\n\nI think he is talking about that one and specifying why it's okay to\ndrop that one, and omitted why it was okay to drop the strbuf_reset()\nbecause that one seemed more obvious.\n\n> > Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> > ---\n> >  builtin/rebase.c | 11 +----------\n> >  1 file changed, 1 insertion(+), 10 deletions(-)\n> >\n> > diff --git a/builtin/rebase.c b/builtin/rebase.c\n> > index e942c300f8c..4832f16e675 100644\n> > --- a/builtin/rebase.c\n> > +++ b/builtin/rebase.c\n> > @@ -1782,19 +1782,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n> >          * If the onto is a proper descendant of the tip of the branch, then\n> >          * we just fast-forwarded.\n> >          */\n> > -       strbuf_reset(&msg);\n>\n> Yeah, it looks like `msg` isn't used in the function anymore so this\n> call can be removed.\n>\n> >         if (oideq(&merge_base, &options.orig_head)) {\n> >                 printf(_(\"Fast-forwarded %s to %s.\\n\"),\n> >                         branch_name, options.onto_name);\n> > -               strbuf_addf(&msg, \"rebase finished: %s onto %s\",\n> > -                       options.head_name ? options.head_name : \"detached HEAD\",\n> > -                       oid_to_hex(&options.onto->object.oid));\n> > -               memset(&ropts, 0, sizeof(ropts));\n> > -               ropts.branch = options.head_name;\n> > -               ropts.flags = RESET_HEAD_REFS_ONLY;\n> > -               ropts.head_msg = msg.buf;\n> > -               reset_head(the_repository, &ropts);\n> > -               strbuf_release(&msg);\n> > +               move_to_original_branch(&options);\n> >                 ret = finish_rebase(&options);\n> >                 goto cleanup;\n> >         }\n>\n> Nice cleanup!\n\nAgreed.\n"},{"id":"453783","messageId":"CABPp-BFQhTPoBmB9i0K70DggpQgiB1P+=KPScaEXYeBikkd1uw@mail.gmail.com","threadId":"57450","inReplyTo":"f4e6e94bc2c894f369546d16d147d970b71554e7.1645441854.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 3/7] rebase --merge: fix reflog message after skipping","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-04-17T01:58:52Z","receivedAt":"2022-04-17T01:59:09Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Mon, Feb 21, 2022 at 3:19 PM Phillip Wood via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> The reflog message for every pick after running \"rebase --skip\" looks\n> like\n>\n>         rebase (skip) (pick): commit subject line\n>\n> Fix this by not appending \" (skip)\" to the reflog action.\n\nNice catch, and cool that the fix was so simple.\n\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  builtin/rebase.c          |  2 --\n>  t/t3406-rebase-message.sh | 24 ++++++++++++++++++++++++\n>  2 files changed, 24 insertions(+), 2 deletions(-)\n>\n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index cd9a4f3e2f1..36863117fba 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -1273,8 +1273,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>                 struct string_list merge_rr = STRING_LIST_INIT_DUP;\n>\n>                 options.action = \"skip\";\n> -               set_reflog_action(&options);\n> -\n>                 rerere_clear(the_repository, &merge_rr);\n>                 string_list_clear(&merge_rr, 1);\n>                 ropts.flags = RESET_HEAD_HARD;\n> diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\n> index 3ca2fbb0d59..8aa6a79acc1 100755\n> --- a/t/t3406-rebase-message.sh\n> +++ b/t/t3406-rebase-message.sh\n> @@ -163,6 +163,30 @@ test_reflog () {\n>         # check there is only one new entry in the branch reflog\n>         test_cmp_rev fast-forward@{1} X\n>         '\n> +\n> +       test_expect_success \"rebase $mode --skip reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n> +       git checkout conflicts &&\n> +       test_when_finished \"git reset --hard Q\" &&\n> +\n> +       (\n> +               if test -n \"$reflog_action\"\n> +               then\n> +                       GIT_REFLOG_ACTION=\"$reflog_action\" &&\n> +                       export GIT_REFLOG_ACTION\n> +               fi &&\n> +               test_must_fail git rebase $mode main &&\n> +               git rebase --skip\n> +       ) &&\n> +\n> +       git log -g --format=%gs -4 >actual &&\n> +       write_reflog_expect <<-EOF &&\n> +       ${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n> +       ${reflog_action:-rebase} (pick): Q\n> +       ${reflog_action:-rebase} (pick): P\n> +       ${reflog_action:-rebase} (start): checkout main\n> +       EOF\n> +       test_cmp expect actual\n> +       '\n>  }\n>\n>  test_reflog --merge\n> --\n> gitgitgadget\n>\n"},{"id":"453784","messageId":"CABPp-BEqjv8BVe3G5x=3wRbL9GH8GeWe4Yv2wiUse4vjWcd58w@mail.gmail.com","threadId":"57450","inReplyTo":"1c3ec1654225ff090c194fa646f974082bd9c944.1645441854.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 5/7] rebase --apply: make reflog messages match rebase --merge","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-04-17T02:03:35Z","receivedAt":"2022-04-17T02:03:52Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Mon, Feb 21, 2022 at 3:19 PM Phillip Wood via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> The apply backend creates slightly different reflog messages to the\n> merge backend when starting and finishing a rebase and when picking\n> commits. The choice of backend is really an implementation detail so\n> it is confusing to have the same command create different messages\n> depending on which backend is selected. Change the apply backend so\n> the reflog messages from the two backends match as closely as\n> possible. Note that there is still a difference when committing a\n> conflict resolution - the merge backend will use \"(continue)\" rather\n> than \"(pick)\" in that case as it does not know which command created\n> the conflict that it is committing.\n\nI've always been slightly annoyed by the various differences in these\nbackends; it's nice to see another one disappearing.\n\n>\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  builtin/rebase.c          | 9 +++++----\n>  t/t3406-rebase-message.sh | 2 +-\n>  2 files changed, 6 insertions(+), 5 deletions(-)\n>\n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index e50361fc2a9..678339c7bf7 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -580,10 +580,10 @@ static int move_to_original_branch(struct rebase_options *opts)\n>         if (!opts->onto)\n>                 BUG(\"move_to_original_branch without onto\");\n>\n> -       strbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n> +       strbuf_addf(&branch_reflog, \"%s (finish): %s onto %s\",\n>                     getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n>                     opts->head_name, oid_to_hex(&opts->onto->object.oid));\n> -       strbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n> +       strbuf_addf(&head_reflog, \"%s (finish): returning to %s\",\n>                     getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n>         ropts.branch = opts->head_name;\n>         ropts.flags = RESET_HEAD_REFS_ONLY;\n> @@ -613,7 +613,8 @@ static int run_am(struct rebase_options *opts)\n>\n>         am.git_cmd = 1;\n>         strvec_push(&am.args, \"am\");\n> -\n> +       strvec_pushf(&am.env_array, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n> +                    getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n\nKinda sad that we're still forking subprocesses and passing things via\nenvironment variable, but that's outside the scope of this series.\nFix looks fine.\n\n>         if (opts->action && !strcmp(\"continue\", opts->action)) {\n>                 strvec_push(&am.args, \"--resolved\");\n>                 strvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n> @@ -1763,7 +1764,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>                 printf(_(\"First, rewinding head to replay your work on top of \"\n>                          \"it...\\n\"));\n>\n> -       strbuf_addf(&msg, \"%s: checkout %s\",\n> +       strbuf_addf(&msg, \"%s (start): checkout %s\",\n>                     getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);\n>         ropts.oid = &options.onto->object.oid;\n>         ropts.orig_head = &options.orig_head,\n> diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\n> index bb2a4949abc..5c6cd9af3bc 100755\n> --- a/t/t3406-rebase-message.sh\n> +++ b/t/t3406-rebase-message.sh\n> @@ -88,7 +88,7 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n>  write_reflog_expect () {\n>         if test $mode = --apply\n>         then\n> -               sed 's/(finish)/finished/; s/ ([^)]*)//'\n> +               sed 's/(continue)/(pick)/'\n>         else\n>                 cat\n>         fi >expect\n> --\n> gitgitgadget\n"},{"id":"453785","messageId":"CABPp-BFZgtNNjSF-WS67_vZd5d3Hg0YvimhKFY6X=gNnX8FC-Q@mail.gmail.com","threadId":"57450","inReplyTo":"c863cebbdc8485225af40593cf2952c933f4ea8d.1645441854.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 6/7] rebase --abort: improve reflog message","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-04-17T02:07:10Z","receivedAt":"2022-04-17T02:07:28Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Mon, Feb 21, 2022 at 3:19 PM Phillip Wood via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> When aborting a rebase the reflog message looks like\n>\n>         rebase (abort): updating HEAD\n>\n> which is not very informative. Improve the message by mentioning the\n> branch that we are returning to as we do at the end of a successful\n> rebase so it looks like.\n>\n>         rebase (abort): returning to refs/heads/topic\n\nThat is _so_ much nicer.\n\n> If GIT_REFLOG_ACTION is set in the environment we no longer omit\n> \"(abort)\" from the reflog message. We don't omit \"(start)\" and\n> \"(finish)\" when starting and finishing a rebase in that case so we\n> shouldn't omit \"(abort)\".\n\nI agree.\n\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  builtin/rebase.c          | 28 ++++++---------------\n>  t/t3406-rebase-message.sh | 51 +++++++++++++++++++++++++++++++++++++++\n>  2 files changed, 59 insertions(+), 20 deletions(-)\n>\n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index 678339c7bf7..70426e17b40 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -992,23 +992,6 @@ static void NORETURN error_on_missing_default_upstream(void)\n>         exit(1);\n>  }\n>\n> -static void set_reflog_action(struct rebase_options *options)\n> -{\n> -       const char *env;\n> -       struct strbuf buf = STRBUF_INIT;\n> -\n> -       if (!is_merge(options))\n> -               return;\n> -\n> -       env = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);\n> -       if (env && strcmp(\"rebase\", env))\n> -               return; /* only override it if it is \"rebase\" */\n> -\n> -       strbuf_addf(&buf, \"rebase (%s)\", options->action);\n> -       setenv(GIT_REFLOG_ACTION_ENVIRONMENT, buf.buf, 1);\n> -       strbuf_release(&buf);\n> -}\n> -\n>  static int check_exec_cmd(const char *cmd)\n>  {\n>         if (strchr(cmd, '\\n'))\n> @@ -1287,18 +1270,23 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>         }\n>         case ACTION_ABORT: {\n>                 struct string_list merge_rr = STRING_LIST_INIT_DUP;\n> -               options.action = \"abort\";\n> -               set_reflog_action(&options);\n> +               struct strbuf head_msg = STRBUF_INIT;\n>\n> +               options.action = \"abort\";\n>                 rerere_clear(the_repository, &merge_rr);\n>                 string_list_clear(&merge_rr, 1);\n>\n>                 if (read_basic_state(&options))\n>                         exit(1);\n> +\n> +               strbuf_addf(&head_msg, \"%s (abort): returning to %s\",\n> +                           getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n> +                           options.head_name ? options.head_name\n> +                                             : oid_to_hex(&options.orig_head));\n>                 ropts.oid = &options.orig_head;\n> +               ropts.head_msg = head_msg.buf;\n>                 ropts.branch = options.head_name;\n>                 ropts.flags = RESET_HEAD_HARD;\n> -               ropts.default_reflog_action = DEFAULT_REFLOG_ACTION;\n>                 if (reset_head(the_repository, &ropts) < 0)\n>                         die(_(\"could not move back to %s\"),\n>                             oid_to_hex(&options.orig_head));\n> diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\n> index 5c6cd9af3bc..ceca1600053 100755\n> --- a/t/t3406-rebase-message.sh\n> +++ b/t/t3406-rebase-message.sh\n> @@ -187,6 +187,57 @@ test_reflog () {\n>         EOF\n>         test_cmp expect actual\n>         '\n> +\n> +       test_expect_success \"rebase $mode --abort reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n> +       git checkout conflicts &&\n> +       test_when_finished \"git reset --hard Q\" &&\n> +\n> +       git log -g -1 conflicts >branch-expect &&\n> +       (\n> +               if test -n \"$reflog_action\"\n> +               then\n> +                       GIT_REFLOG_ACTION=\"$reflog_action\" &&\n> +                       export GIT_REFLOG_ACTION\n> +               fi &&\n> +               test_must_fail git rebase $mode main &&\n> +               git rebase --abort\n> +       ) &&\n> +\n> +       git log -g --format=%gs -3 >actual &&\n> +       write_reflog_expect <<-EOF &&\n> +       ${reflog_action:-rebase} (abort): returning to refs/heads/conflicts\n> +       ${reflog_action:-rebase} (pick): P\n> +       ${reflog_action:-rebase} (start): checkout main\n> +       EOF\n> +       test_cmp expect actual &&\n\nI was confused by the ordering at first, before I realized that `git\nlog -g` is going to give you reflogs from newest to oldest instead of\nvice-versa.  Looks good.\n\n> +\n> +       # check branch reflog is unchanged\n> +       git log -g -1 conflicts >branch-actual &&\n> +       test_cmp branch-expect branch-actual\n> +       '\n> +\n> +       test_expect_success \"rebase $mode --abort detached HEAD reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n> +       git checkout Q &&\n> +       test_when_finished \"git reset --hard Q\" &&\n> +\n> +       (\n> +               if test -n \"$reflog_action\"\n> +               then\n> +                       GIT_REFLOG_ACTION=\"$reflog_action\" &&\n> +                       export GIT_REFLOG_ACTION\n> +               fi &&\n> +               test_must_fail git rebase $mode main &&\n> +               git rebase --abort\n> +       ) &&\n> +\n> +       git log -g --format=%gs -3 >actual &&\n> +       write_reflog_expect <<-EOF &&\n> +       ${reflog_action:-rebase} (abort): returning to $(git rev-parse Q)\n> +       ${reflog_action:-rebase} (pick): P\n> +       ${reflog_action:-rebase} (start): checkout main\n> +       EOF\n> +       test_cmp expect actual\n> +       '\n>  }\n\nAnd thanks for checking the detached HEAD case too.\n"},{"id":"453786","messageId":"CABPp-BEiqc3-6zXtuVd=ELfptgy==BU28DW1+87ernjdzpW4-A@mail.gmail.com","threadId":"57450","inReplyTo":"d26a221a79d2e0b5ec0cee46a68a3b2caa195842.1645441854.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 7/7] rebase: cleanup action handling","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-04-17T02:07:53Z","receivedAt":"2022-04-17T02:08:12Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Mon, Feb 21, 2022 at 9:35 PM Phillip Wood via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> Treating the action as a string is a hang over from the scripted\n> rebase. The last commit removed the only remaining use of the action\n> that required a string so lets convert the other action users to use\n> the existing action enum instead. If we ever need the action name as a\n> string in the future the action_names array exists exactly for that\n> purpose.\n>\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  builtin/rebase.c | 91 +++++++++++++++++++++++-------------------------\n>  1 file changed, 43 insertions(+), 48 deletions(-)\n>\n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index 70426e17b40..323f5154092 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -58,6 +58,26 @@ enum empty_type {\n>         EMPTY_ASK\n>  };\n>\n> +enum action {\n> +       ACTION_NONE = 0,\n> +       ACTION_CONTINUE,\n> +       ACTION_SKIP,\n> +       ACTION_ABORT,\n> +       ACTION_QUIT,\n> +       ACTION_EDIT_TODO,\n> +       ACTION_SHOW_CURRENT_PATCH\n> +};\n> +\n> +static const char *action_names[] = {\n> +       \"undefined\",\n> +       \"continue\",\n> +       \"skip\",\n> +       \"abort\",\n> +       \"quit\",\n> +       \"edit_todo\",\n> +       \"show_current_patch\"\n> +};\n> +\n>  struct rebase_options {\n>         enum rebase_type type;\n>         enum empty_type empty;\n> @@ -84,7 +104,7 @@ struct rebase_options {\n>                 REBASE_INTERACTIVE_EXPLICIT = 1<<4,\n>         } flags;\n>         struct strvec git_am_opts;\n> -       const char *action;\n> +       enum action action;\n>         int signoff;\n>         int allow_rerere_autoupdate;\n>         int keep_empty;\n> @@ -155,24 +175,6 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)\n>         return replay;\n>  }\n>\n> -enum action {\n> -       ACTION_NONE = 0,\n> -       ACTION_CONTINUE,\n> -       ACTION_SKIP,\n> -       ACTION_ABORT,\n> -       ACTION_QUIT,\n> -       ACTION_EDIT_TODO,\n> -       ACTION_SHOW_CURRENT_PATCH\n> -};\n> -\n> -static const char *action_names[] = { \"undefined\",\n> -                                     \"continue\",\n> -                                     \"skip\",\n> -                                     \"abort\",\n> -                                     \"quit\",\n> -                                     \"edit_todo\",\n> -                                     \"show_current_patch\" };\n> -\n>  static int edit_todo_file(unsigned flags)\n>  {\n>         const char *todo_file = rebase_path_todo();\n> @@ -309,8 +311,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)\n>         return ret;\n>  }\n>\n> -static int run_sequencer_rebase(struct rebase_options *opts,\n> -                                 enum action command)\n> +static int run_sequencer_rebase(struct rebase_options *opts)\n>  {\n>         unsigned flags = 0;\n>         int abbreviate_commands = 0, ret = 0;\n> @@ -325,7 +326,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n>         flags |= opts->reapply_cherry_picks ? TODO_LIST_REAPPLY_CHERRY_PICKS : 0;\n>         flags |= opts->flags & REBASE_NO_QUIET ? TODO_LIST_WARN_SKIPPED_CHERRY_PICKS : 0;\n>\n> -       switch (command) {\n> +       switch (opts->action) {\n>         case ACTION_NONE: {\n>                 if (!opts->onto && !opts->upstream)\n>                         die(_(\"a base commit must be provided with --upstream or --onto\"));\n> @@ -358,7 +359,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n>                 break;\n>         }\n>         default:\n> -               BUG(\"invalid command '%d'\", command);\n> +               BUG(\"invalid command '%d'\", opts->action);\n>         }\n>\n>         return ret;\n> @@ -615,7 +616,7 @@ static int run_am(struct rebase_options *opts)\n>         strvec_push(&am.args, \"am\");\n>         strvec_pushf(&am.env_array, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n>                      getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n> -       if (opts->action && !strcmp(\"continue\", opts->action)) {\n> +       if (opts->action == ACTION_CONTINUE) {\n>                 strvec_push(&am.args, \"--resolved\");\n>                 strvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n>                 if (opts->gpg_sign_opt)\n> @@ -626,7 +627,7 @@ static int run_am(struct rebase_options *opts)\n>\n>                 return move_to_original_branch(opts);\n>         }\n> -       if (opts->action && !strcmp(\"skip\", opts->action)) {\n> +       if (opts->action == ACTION_SKIP) {\n>                 strvec_push(&am.args, \"--skip\");\n>                 strvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n>                 status = run_command(&am);\n> @@ -635,7 +636,7 @@ static int run_am(struct rebase_options *opts)\n>\n>                 return move_to_original_branch(opts);\n>         }\n> -       if (opts->action && !strcmp(\"show-current-patch\", opts->action)) {\n> +       if (opts->action == ACTION_SHOW_CURRENT_PATCH) {\n>                 strvec_push(&am.args, \"--show-current-patch\");\n>                 return run_command(&am);\n>         }\n> @@ -728,7 +729,7 @@ static int run_am(struct rebase_options *opts)\n>         return status;\n>  }\n>\n> -static int run_specific_rebase(struct rebase_options *opts, enum action action)\n> +static int run_specific_rebase(struct rebase_options *opts)\n>  {\n>         int status;\n>\n> @@ -746,7 +747,7 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n>                         opts->gpg_sign_opt = tmp;\n>                 }\n>\n> -               status = run_sequencer_rebase(opts, action);\n> +               status = run_sequencer_rebase(opts);\n>         } else if (opts->type == REBASE_APPLY)\n>                 status = run_am(opts);\n>         else\n> @@ -1016,7 +1017,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>         struct strbuf buf = STRBUF_INIT;\n>         struct object_id merge_base;\n>         int ignore_whitespace = 0;\n> -       enum action action = ACTION_NONE;\n>         const char *gpg_sign = NULL;\n>         struct string_list exec = STRING_LIST_INIT_NODUP;\n>         const char *rebase_merges = NULL;\n> @@ -1065,18 +1065,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>                 OPT_BIT(0, \"no-ff\", &options.flags,\n>                         N_(\"cherry-pick all commits, even if unchanged\"),\n>                         REBASE_FORCE),\n> -               OPT_CMDMODE(0, \"continue\", &action, N_(\"continue\"),\n> +               OPT_CMDMODE(0, \"continue\", &options.action, N_(\"continue\"),\n>                             ACTION_CONTINUE),\n> -               OPT_CMDMODE(0, \"skip\", &action,\n> +               OPT_CMDMODE(0, \"skip\", &options.action,\n>                             N_(\"skip current patch and continue\"), ACTION_SKIP),\n> -               OPT_CMDMODE(0, \"abort\", &action,\n> +               OPT_CMDMODE(0, \"abort\", &options.action,\n>                             N_(\"abort and check out the original branch\"),\n>                             ACTION_ABORT),\n> -               OPT_CMDMODE(0, \"quit\", &action,\n> +               OPT_CMDMODE(0, \"quit\", &options.action,\n>                             N_(\"abort but keep HEAD where it is\"), ACTION_QUIT),\n> -               OPT_CMDMODE(0, \"edit-todo\", &action, N_(\"edit the todo list \"\n> +               OPT_CMDMODE(0, \"edit-todo\", &options.action, N_(\"edit the todo list \"\n>                             \"during an interactive rebase\"), ACTION_EDIT_TODO),\n> -               OPT_CMDMODE(0, \"show-current-patch\", &action,\n> +               OPT_CMDMODE(0, \"show-current-patch\", &options.action,\n>                             N_(\"show the patch file being applied or merged\"),\n>                             ACTION_SHOW_CURRENT_PATCH),\n>                 OPT_CALLBACK_F(0, \"apply\", &options, NULL,\n> @@ -1189,7 +1189,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>         if (preserve_merges_selected)\n>                 die(_(\"--preserve-merges was replaced by --rebase-merges\"));\n>\n> -       if (action != ACTION_NONE && total_argc != 2) {\n> +       if (options.action != ACTION_NONE && total_argc != 2) {\n>                 usage_with_options(builtin_rebase_usage,\n>                                    builtin_rebase_options);\n>         }\n> @@ -1208,11 +1208,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>         if (options.root && options.fork_point > 0)\n>                 die(_(\"cannot combine '--root' with '--fork-point'\"));\n>\n> -       if (action != ACTION_NONE && !in_progress)\n> +       if (options.action != ACTION_NONE && !in_progress)\n>                 die(_(\"No rebase in progress?\"));\n>         setenv(GIT_REFLOG_ACTION_ENVIRONMENT, \"rebase\", 0);\n>\n> -       if (action == ACTION_EDIT_TODO && !is_merge(&options))\n> +       if (options.action == ACTION_EDIT_TODO && !is_merge(&options))\n>                 die(_(\"The --edit-todo action can only be used during \"\n>                       \"interactive rebase.\"));\n>\n> @@ -1222,16 +1222,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>                 else if (exec.nr)\n>                         trace2_cmd_mode(\"interactive-exec\");\n>                 else\n> -                       trace2_cmd_mode(action_names[action]);\n> +                       trace2_cmd_mode(action_names[options.action]);\n>         }\n>\n> -       switch (action) {\n> +       switch (options.action) {\n>         case ACTION_CONTINUE: {\n>                 struct object_id head;\n>                 struct lock_file lock_file = LOCK_INIT;\n>                 int fd;\n>\n> -               options.action = \"continue\";\n>                 /* Sanity check */\n>                 if (get_oid(\"HEAD\", &head))\n>                         die(_(\"Cannot read HEAD\"));\n> @@ -1257,7 +1256,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>         case ACTION_SKIP: {\n>                 struct string_list merge_rr = STRING_LIST_INIT_DUP;\n>\n> -               options.action = \"skip\";\n>                 rerere_clear(the_repository, &merge_rr);\n>                 string_list_clear(&merge_rr, 1);\n>                 ropts.flags = RESET_HEAD_HARD;\n> @@ -1272,7 +1270,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>                 struct string_list merge_rr = STRING_LIST_INIT_DUP;\n>                 struct strbuf head_msg = STRBUF_INIT;\n>\n> -               options.action = \"abort\";\n>                 rerere_clear(the_repository, &merge_rr);\n>                 string_list_clear(&merge_rr, 1);\n>\n> @@ -1312,17 +1309,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>                 goto cleanup;\n>         }\n>         case ACTION_EDIT_TODO:\n> -               options.action = \"edit-todo\";\n>                 options.dont_finish_rebase = 1;\n>                 goto run_rebase;\n>         case ACTION_SHOW_CURRENT_PATCH:\n> -               options.action = \"show-current-patch\";\n>                 options.dont_finish_rebase = 1;\n>                 goto run_rebase;\n>         case ACTION_NONE:\n>                 break;\n>         default:\n> -               BUG(\"action: %d\", action);\n> +               BUG(\"action: %d\", options.action);\n>         }\n>\n>         /* Make sure no rebase is in progress */\n> @@ -1346,7 +1341,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>         }\n>\n>         if ((options.flags & REBASE_INTERACTIVE_EXPLICIT) ||\n> -           (action != ACTION_NONE) ||\n> +           (options.action != ACTION_NONE) ||\n>             (exec.nr > 0) ||\n>             options.autosquash) {\n>                 allow_preemptive_ff = 0;\n> @@ -1786,7 +1781,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>         options.revisions = revisions.buf;\n>\n>  run_rebase:\n> -       ret = run_specific_rebase(&options, action);\n> +       ret = run_specific_rebase(&options);\n>\n>  cleanup:\n>         strbuf_release(&buf);\n> --\n> gitgitgadget\n\nThanks for the nice cleanup!\n"},{"id":"453787","messageId":"CABPp-BEXqXAje-GmMkhaowbewoPiuFCKZ01g_i+ygN1epT9ByA@mail.gmail.com","threadId":"57450","inReplyTo":"pull.1150.git.1645441854.gitgitgadget@gmail.com","subject":"Re: [PATCH 0/7] rebase: make reflog messages independent of the backend","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-04-17T02:09:41Z","receivedAt":"2022-04-17T02:09:59Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Mon, Feb 21, 2022 at 9:04 PM Phillip Wood via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> This is a series of rebase reflog related patches with the aim of unifying\n> the reflog messages from the two rebase backends.\n>\n>  * improve rebase reflog test coverage\n>  * rebase --merge: fix reflog messages for --continue and --skip\n>  * rebase --apply: respect GIT_REFLOG_ACTION\n>  * rebase --abort: improve reflog message\n>  * unify reflog messages between the two rebase backends\n>\n> This series is based on pw/use-inprocess-checkout-in-rebase\n>\n> Phillip Wood (7):\n>   rebase --apply: remove duplicated code\n>   rebase --merge: fix reflog when continuing\n>   rebase --merge: fix reflog message after skipping\n>   rebase --apply: respect GIT_REFLOG_ACTION\n>   rebase --apply: make reflog messages match rebase --merge\n>   rebase --abort: improve reflog message\n>   rebase: cleanup action handling\n>\n>  builtin/rebase.c          | 144 ++++++++++++-----------------\n>  sequencer.c               |   5 ++\n>  t/t3406-rebase-message.sh | 185 +++++++++++++++++++++++++++++++-------\n>  3 files changed, 214 insertions(+), 120 deletions(-)\n>\n>\n> base-commit: 38c541ce94048cf72aa4f465be9314423a57f445\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1150%2Fphillipwood%2Fwip%2Frebase-reflog-fixes-v1\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1150/phillipwood/wip/rebase-reflog-fixes-v1\n> Pull-Request: https://github.com/gitgitgadget/git/pull/1150\n\nI read through the seven patches, then went back and commented on all\nof them.  Hard to find problems really, looks nicely written.  I would\nsecond Christian's request to have the second patch split with a\npreparatory testcase cleanup, which it appears you already plan to do.\nOther than patch, the series looks good to me.\n"},{"id":"453788","messageId":"CABPp-BGyesv-0upHdipLg+VrA08FV3cD7NrVK9xm4iVgn8iqHQ@mail.gmail.com","threadId":"57450","inReplyTo":"64cae3bc-e1b9-d118-2d78-208dc772f74a@gmail.com","subject":"Re: Review Request (was Re: [PATCH 0/7] rebase: make reflog messages independent of the backend)","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-04-17T02:13:08Z","receivedAt":"2022-04-17T02:13:26Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Mon, Apr 4, 2022 at 8:34 AM Phillip Wood <phillip.wood123@gmail.com> wrote:\n>\n> If anyone has time to review these patches I'd be very grateful. I've\n> cc'd this message to some list regulars who have reviewed rebase patches\n> before but if anyone else fancies taking a look at them that would be great.\n\nI apologize for the delay here...especially when it came after you had\nalready waited a month and a half.  (This is the first git thing I've\ndone in over a month, sadly.)  Anyway, I just read through the series\nand left some comments; mostly looks good but I second the request to\nsplit up one of the patches.\n\n\n> On 21/02/2022 11:10, Phillip Wood via GitGitGadget wrote:\n> > This is a series of rebase reflog related patches with the aim of unifying\n> > the reflog messages from the two rebase backends.\n> >\n> >   * improve rebase reflog test coverage\n> >   * rebase --merge: fix reflog messages for --continue and --skip\n> >   * rebase --apply: respect GIT_REFLOG_ACTION\n> >   * rebase --abort: improve reflog message\n> >   * unify reflog messages between the two rebase backends\n> >\n> > This series is based on pw/use-inprocess-checkout-in-rebase\n> >\n> > Phillip Wood (7):\n> >    rebase --apply: remove duplicated code\n> >    rebase --merge: fix reflog when continuing\n> >    rebase --merge: fix reflog message after skipping\n> >    rebase --apply: respect GIT_REFLOG_ACTION\n> >    rebase --apply: make reflog messages match rebase --merge\n> >    rebase --abort: improve reflog message\n> >    rebase: cleanup action handling\n> >\n> >   builtin/rebase.c          | 144 ++++++++++++-----------------\n> >   sequencer.c               |   5 ++\n> >   t/t3406-rebase-message.sh | 185 +++++++++++++++++++++++++++++++-------\n> >   3 files changed, 214 insertions(+), 120 deletions(-)\n> >\n> >\n> > base-commit: 38c541ce94048cf72aa4f465be9314423a57f445\n> > Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1150%2Fphillipwood%2Fwip%2Frebase-reflog-fixes-v1\n> > Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1150/phillipwood/wip/rebase-reflog-fixes-v1\n> > Pull-Request: https://github.com/gitgitgadget/git/pull/1150\n"},{"id":"453906","messageId":"0c9c1b37-24eb-3074-18c2-62185af27d43@gmail.com","threadId":"57450","inReplyTo":"CABPp-BGyesv-0upHdipLg+VrA08FV3cD7NrVK9xm4iVgn8iqHQ@mail.gmail.com","subject":"Re: Review Request (was Re: [PATCH 0/7] rebase: make reflog messages independent of the backend)","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2022-04-18T18:56:53Z","receivedAt":"2022-04-18T18:57:00Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Elijah\n\nOn 17/04/2022 03:13, Elijah Newren wrote:\n> On Mon, Apr 4, 2022 at 8:34 AM Phillip Wood <phillip.wood123@gmail.com> wrote:\n>>\n>> If anyone has time to review these patches I'd be very grateful. I've\n>> cc'd this message to some list regulars who have reviewed rebase patches\n>> before but if anyone else fancies taking a look at them that would be great.\n> \n> I apologize for the delay here...especially when it came after you had\n> already waited a month and a half.  (This is the first git thing I've\n> done in over a month, sadly.)  Anyway, I just read through the series\n> and left some comments; mostly looks good but I second the request to\n> split up one of the patches.\n\nThere's no need to apologize, I'm very grateful for you comments. I'll \nre-roll with that patch split up.\n\nThanks\n\nPhillip\n\n> \n>> On 21/02/2022 11:10, Phillip Wood via GitGitGadget wrote:\n>>> This is a series of rebase reflog related patches with the aim of unifying\n>>> the reflog messages from the two rebase backends.\n>>>\n>>>    * improve rebase reflog test coverage\n>>>    * rebase --merge: fix reflog messages for --continue and --skip\n>>>    * rebase --apply: respect GIT_REFLOG_ACTION\n>>>    * rebase --abort: improve reflog message\n>>>    * unify reflog messages between the two rebase backends\n>>>\n>>> This series is based on pw/use-inprocess-checkout-in-rebase\n>>>\n>>> Phillip Wood (7):\n>>>     rebase --apply: remove duplicated code\n>>>     rebase --merge: fix reflog when continuing\n>>>     rebase --merge: fix reflog message after skipping\n>>>     rebase --apply: respect GIT_REFLOG_ACTION\n>>>     rebase --apply: make reflog messages match rebase --merge\n>>>     rebase --abort: improve reflog message\n>>>     rebase: cleanup action handling\n>>>\n>>>    builtin/rebase.c          | 144 ++++++++++++-----------------\n>>>    sequencer.c               |   5 ++\n>>>    t/t3406-rebase-message.sh | 185 +++++++++++++++++++++++++++++++-------\n>>>    3 files changed, 214 insertions(+), 120 deletions(-)\n>>>\n>>>\n>>> base-commit: 38c541ce94048cf72aa4f465be9314423a57f445\n>>> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1150%2Fphillipwood%2Fwip%2Frebase-reflog-fixes-v1\n>>> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1150/phillipwood/wip/rebase-reflog-fixes-v1\n>>> Pull-Request: https://github.com/gitgitgadget/git/pull/1150\n"},{"id":"453957","messageId":"0904b50a377ce3ac242f9594a635f9ae7cffc687.1650448612.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v2.git.1650448612.gitgitgadget@gmail.com","subject":"[PATCH v2 2/8] t3406: rework rebase reflog tests","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-04-20T09:56:45Z","receivedAt":"2022-04-20T09:57:03Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nRefactor the tests in preparation for adding more tests in the next\nfew commits. The reworked tests use the same function for testing both\nthe \"merge\" and \"apply\" backends. The test coverage for the \"apply\"\nbackend now includes setting GIT_REFLOG_ACTION.\n\nNote that rebasing the \"conflicts\" branch does not create any\nconflicts yet. A commit to do that will be added in the next commit\nand the diff ends up smaller if we have don't rename the branch when\nit is added.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n t/t3406-rebase-message.sh | 115 +++++++++++++++++++++++++-------------\n 1 file changed, 76 insertions(+), 39 deletions(-)\n\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex d17b450e811..5253dd1551d 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -10,10 +10,15 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n test_expect_success 'setup' '\n \ttest_commit O fileO &&\n \ttest_commit X fileX &&\n+\tgit branch fast-forward &&\n \ttest_commit A fileA &&\n \ttest_commit B fileB &&\n \ttest_commit Y fileY &&\n \n+\tgit checkout -b conflicts O &&\n+\ttest_commit P &&\n+\ttest_commit Q &&\n+\n \tgit checkout -b topic O &&\n \tgit cherry-pick A B &&\n \ttest_commit Z fileZ &&\n@@ -79,54 +84,86 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n \ttest_i18ngrep \"Invalid whitespace option\" err\n '\n \n-test_expect_success 'GIT_REFLOG_ACTION' '\n-\tgit checkout start &&\n-\ttest_commit reflog-onto &&\n-\tgit checkout -b reflog-topic start &&\n-\ttest_commit reflog-to-rebase &&\n-\n-\tgit rebase reflog-onto &&\n-\tgit log -g --format=%gs -3 >actual &&\n-\tcat >expect <<-\\EOF &&\n-\trebase (finish): returning to refs/heads/reflog-topic\n-\trebase (pick): reflog-to-rebase\n-\trebase (start): checkout reflog-onto\n+write_reflog_expect () {\n+\tif test $mode = --apply\n+\tthen\n+\t\tsed 's/.*(finish)/rebase finished/; s/ ([^)]*)//'\n+\telse\n+\t\tcat\n+\tfi >expect\n+}\n+\n+test_reflog () {\n+\tmode=$1\n+\treflog_action=\"$2\"\n+\n+\ttest_expect_success \"rebase $mode reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout conflicts &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\tgit rebase $mode main\n+\t) &&\n+\n+\tgit log -g --format=%gs -4 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n+\t${reflog_action:-rebase} (pick): Q\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n \tEOF\n \ttest_cmp expect actual &&\n \n-\tgit checkout -b reflog-prefix reflog-to-rebase &&\n-\tGIT_REFLOG_ACTION=change-the-reflog git rebase reflog-onto &&\n-\tgit log -g --format=%gs -3 >actual &&\n-\tcat >expect <<-\\EOF &&\n-\tchange-the-reflog (finish): returning to refs/heads/reflog-prefix\n-\tchange-the-reflog (pick): reflog-to-rebase\n-\tchange-the-reflog (start): checkout reflog-onto\n+\tgit log -g --format=%gs -1 conflicts >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): refs/heads/conflicts onto $(git rev-parse main)\n \tEOF\n-\ttest_cmp expect actual\n-'\n-\n-test_expect_success 'rebase --apply reflog' '\n-\tgit checkout -b reflog-apply start &&\n-\told_head_reflog=\"$(git log -g --format=%gs -1 HEAD)\" &&\n-\n-\tgit rebase --apply Y &&\n+\ttest_cmp expect actual &&\n \n-\tgit log -g --format=%gs -4 HEAD >actual &&\n-\tcat >expect <<-EOF &&\n-\trebase finished: returning to refs/heads/reflog-apply\n-\trebase: Z\n-\trebase: checkout Y\n-\t$old_head_reflog\n+\t# check there is only one new entry in the branch reflog\n+\ttest_cmp_rev conflicts@{1} Q\n+\t'\n+\n+\ttest_expect_success \"rebase $mode fast-forward reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout fast-forward &&\n+\ttest_when_finished \"git reset --hard X\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\tgit rebase $mode main\n+\t) &&\n+\n+\tgit log -g --format=%gs -2 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): returning to refs/heads/fast-forward\n+\t${reflog_action:-rebase} (start): checkout main\n \tEOF\n \ttest_cmp expect actual &&\n \n-\tgit log -g --format=%gs -2 reflog-apply >actual &&\n-\tcat >expect <<-EOF &&\n-\trebase finished: refs/heads/reflog-apply onto $(git rev-parse Y)\n-\tbranch: Created from start\n+\tgit log -g --format=%gs -1 fast-forward >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): refs/heads/fast-forward onto $(git rev-parse main)\n \tEOF\n-\ttest_cmp expect actual\n-'\n+\ttest_cmp expect actual &&\n+\n+\t# check there is only one new entry in the branch reflog\n+\ttest_cmp_rev fast-forward@{1} X\n+\t'\n+}\n+\n+test_reflog --merge\n+test_reflog --merge my-reflog-action\n+test_reflog --apply\n+test_reflog --apply my-reflog-action\n \n test_expect_success 'rebase -i onto unrelated history' '\n \tgit init unrelated &&\n-- \ngitgitgadget\n\n"},{"id":"453958","messageId":"a4320f2fcf35f180e1c585be4105194f1555a874.1650448612.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v2.git.1650448612.gitgitgadget@gmail.com","subject":"[PATCH v2 1/8] rebase --apply: remove duplicated code","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-04-20T09:56:44Z","receivedAt":"2022-04-20T09:57:07Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nWhen we are reattaching HEAD after a fast-forward we can use\nmove_to_original_branch() rather than open coding a copy of that\ncode. The old code appears to handle the case where the rebase is\nstarted from a detached HEAD but in fact in that case there is nothing\nto do as we have already updated HEAD.\n\nNote that the removal of \"strbuf_release(&msg)\" is safe as there is an\nidentical call just above this hunk which can be seen by viewing the\ndiff with -U6.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c | 11 +----------\n 1 file changed, 1 insertion(+), 10 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex e942c300f8c..4832f16e675 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1782,19 +1782,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t * If the onto is a proper descendant of the tip of the branch, then\n \t * we just fast-forwarded.\n \t */\n-\tstrbuf_reset(&msg);\n \tif (oideq(&merge_base, &options.orig_head)) {\n \t\tprintf(_(\"Fast-forwarded %s to %s.\\n\"),\n \t\t\tbranch_name, options.onto_name);\n-\t\tstrbuf_addf(&msg, \"rebase finished: %s onto %s\",\n-\t\t\toptions.head_name ? options.head_name : \"detached HEAD\",\n-\t\t\toid_to_hex(&options.onto->object.oid));\n-\t\tmemset(&ropts, 0, sizeof(ropts));\n-\t\tropts.branch = options.head_name;\n-\t\tropts.flags = RESET_HEAD_REFS_ONLY;\n-\t\tropts.head_msg = msg.buf;\n-\t\treset_head(the_repository, &ropts);\n-\t\tstrbuf_release(&msg);\n+\t\tmove_to_original_branch(&options);\n \t\tret = finish_rebase(&options);\n \t\tgoto cleanup;\n \t}\n-- \ngitgitgadget\n\n"},{"id":"453959","messageId":"pull.1150.v2.git.1650448612.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.git.1645441854.gitgitgadget@gmail.com","subject":"[PATCH v2 0/8] rebase: make reflog messages independent of the backend","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-04-20T09:56:43Z","receivedAt":"2022-04-20T09:57:09Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Thanks to Christian and Elijah for their comments on V1.\n\nI've updated commit message for patch 1 to try and be clearer about the\nremoval of a call to strbuf_release() and spilt out the test changes from\nthe old patch 2 into a separate preparatory patch.\n\nV1 Cover Letter:\n\nThis is a series of rebase reflog related patches with the aim of unifying\nthe reflog messages from the two rebase backends.\n\n * improve rebase reflog test coverage\n * rebase --merge: fix reflog messages for --continue and --skip\n * rebase --apply: respect GIT_REFLOG_ACTION\n * rebase --abort: improve reflog message\n * unify reflog messages between the two rebase backends\n\nThis series is based on pw/use-inprocess-checkout-in-rebase\n\nPhillip Wood (8):\n  rebase --apply: remove duplicated code\n  t3406: rework rebase reflog tests\n  rebase --merge: fix reflog when continuing\n  rebase --merge: fix reflog message after skipping\n  rebase --apply: respect GIT_REFLOG_ACTION\n  rebase --apply: make reflog messages match rebase --merge\n  rebase --abort: improve reflog message\n  rebase: cleanup action handling\n\n builtin/rebase.c          | 144 ++++++++++++-----------------\n sequencer.c               |   5 ++\n t/t3406-rebase-message.sh | 185 +++++++++++++++++++++++++++++++-------\n 3 files changed, 214 insertions(+), 120 deletions(-)\n\n\nbase-commit: 38c541ce94048cf72aa4f465be9314423a57f445\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1150%2Fphillipwood%2Fwip%2Frebase-reflog-fixes-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1150/phillipwood/wip/rebase-reflog-fixes-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/1150\n\nRange-diff vs v1:\n\n 1:  243e7b0c372 ! 1:  a4320f2fcf3 rebase --apply: remove duplicated code\n     @@ Commit message\n          to do as we have already updated HEAD.\n      \n          Note that the removal of \"strbuf_release(&msg)\" is safe as there is an\n     -    identical call just above this hunk.\n     +    identical call just above this hunk which can be seen by viewing the\n     +    diff with -U6.\n      \n          Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n      \n 2:  493254ffbb8 ! 2:  0904b50a377 rebase --merge: fix reflog when continuing\n     @@ Metadata\n      Author: Phillip Wood <phillip.wood@dunelm.org.uk>\n      \n       ## Commit message ##\n     -    rebase --merge: fix reflog when continuing\n     +    t3406: rework rebase reflog tests\n      \n     -    The reflog message for a conflict resolution committed by \"rebase\n     -    --continue\" looks like\n     +    Refactor the tests in preparation for adding more tests in the next\n     +    few commits. The reworked tests use the same function for testing both\n     +    the \"merge\" and \"apply\" backends. The test coverage for the \"apply\"\n     +    backend now includes setting GIT_REFLOG_ACTION.\n      \n     -            rebase (continue): commit subject line\n     -\n     -    Unfortunately the reflog message each subsequent pick look like\n     -\n     -            rebase (continue) (pick): commit subject line\n     -\n     -    Fix this by setting the reflog message for \"rebase --continue\" in\n     -    sequencer_continue() so it does not affect subsequent commits. This\n     -    introduces a memory leak similar to the one leaking GIT_REFLOG_ACTION\n     -    in pick_commits(). Both of these will be fixed in a future series that\n     -    stops the sequencer calling setenv().\n     +    Note that rebasing the \"conflicts\" branch does not create any\n     +    conflicts yet. A commit to do that will be added in the next commit\n     +    and the diff ends up smaller if we have don't rename the branch when\n     +    it is added.\n      \n          Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n      \n     - ## builtin/rebase.c ##\n     -@@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n     - \t\tint fd;\n     - \n     - \t\toptions.action = \"continue\";\n     --\t\tset_reflog_action(&options);\n     --\n     - \t\t/* Sanity check */\n     - \t\tif (get_oid(\"HEAD\", &head))\n     - \t\t\tdie(_(\"Cannot read HEAD\"));\n     -\n     - ## sequencer.c ##\n     -@@ sequencer.c: int sequencer_continue(struct repository *r, struct replay_opts *opts)\n     - \tif (read_populate_opts(opts))\n     - \t\treturn -1;\n     - \tif (is_rebase_i(opts)) {\n     -+\t\tchar *previous_reflog_action;\n     -+\n     - \t\tif ((res = read_populate_todo(r, &todo_list, opts)))\n     - \t\t\tgoto release_todo_list;\n     - \n     -@@ sequencer.c: int sequencer_continue(struct repository *r, struct replay_opts *opts)\n     - \t\t\tunlink(rebase_path_dropped());\n     - \t\t}\n     - \n     -+\t\tprevious_reflog_action = xstrdup(getenv(GIT_REFLOG_ACTION));\n     -+\t\tsetenv(GIT_REFLOG_ACTION, reflog_message(opts, \"continue\", NULL), 1);\n     - \t\tif (commit_staged_changes(r, opts, &todo_list)) {\n     - \t\t\tres = -1;\n     - \t\t\tgoto release_todo_list;\n     - \t\t}\n     -+\t\tsetenv(GIT_REFLOG_ACTION, previous_reflog_action, 1);\n     - \t} else if (!file_exists(get_todo_path(opts)))\n     - \t\treturn continue_single_pick(r, opts);\n     - \telse if ((res = read_populate_todo(r, &todo_list, opts)))\n     -\n       ## t/t3406-rebase-message.sh ##\n      @@ t/t3406-rebase-message.sh: export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n       test_expect_success 'setup' '\n     @@ t/t3406-rebase-message.sh: export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n       \n      +\tgit checkout -b conflicts O &&\n      +\ttest_commit P &&\n     -+\ttest_commit conflict-X fileX &&\n      +\ttest_commit Q &&\n      +\n       \tgit checkout -b topic O &&\n     @@ t/t3406-rebase-message.sh: test_expect_success 'error out early upon -C<n> or --\n      +\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n      +\t\t\texport GIT_REFLOG_ACTION\n      +\t\tfi &&\n     -+\t\ttest_must_fail git rebase $mode main &&\n     -+\t\techo resolved >fileX &&\n     -+\t\tgit add fileX &&\n     -+\t\tgit rebase --continue\n     ++\t\tgit rebase $mode main\n      +\t) &&\n      +\n     -+\tgit log -g --format=%gs -5 >actual &&\n     ++\tgit log -g --format=%gs -4 >actual &&\n      +\twrite_reflog_expect <<-EOF &&\n      +\t${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n      +\t${reflog_action:-rebase} (pick): Q\n     -+\t${reflog_action:-rebase} (continue): conflict-X\n      +\t${reflog_action:-rebase} (pick): P\n      +\t${reflog_action:-rebase} (start): checkout main\n       \tEOF\n -:  ----------- > 3:  6c15f00e170 rebase --merge: fix reflog when continuing\n 3:  f4e6e94bc2c = 4:  d3afa85ffc5 rebase --merge: fix reflog message after skipping\n 4:  58c560d0e19 = 5:  afa67abe01a rebase --apply: respect GIT_REFLOG_ACTION\n 5:  1c3ec165422 = 6:  95161f21e00 rebase --apply: make reflog messages match rebase --merge\n 6:  c863cebbdc8 = 7:  d2c1dfbcd5e rebase --abort: improve reflog message\n 7:  d26a221a79d = 8:  b0d21affa78 rebase: cleanup action handling\n\n-- \ngitgitgadget\n"},{"id":"453960","messageId":"6c15f00e17064a356ceb2b638e89ee7ea21aff24.1650448612.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v2.git.1650448612.gitgitgadget@gmail.com","subject":"[PATCH v2 3/8] rebase --merge: fix reflog when continuing","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-04-20T09:56:46Z","receivedAt":"2022-04-20T09:57:11Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe reflog message for a conflict resolution committed by \"rebase\n--continue\" looks like\n\n\trebase (continue): commit subject line\n\nUnfortunately the reflog message each subsequent pick look like\n\n\trebase (continue) (pick): commit subject line\n\nFix this by setting the reflog message for \"rebase --continue\" in\nsequencer_continue() so it does not affect subsequent commits. This\nintroduces a memory leak similar to the one leaking GIT_REFLOG_ACTION\nin pick_commits(). Both of these will be fixed in a future series that\nstops the sequencer calling setenv().\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 2 --\n sequencer.c               | 5 +++++\n t/t3406-rebase-message.sh | 9 +++++++--\n 3 files changed, 12 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 4832f16e675..cd9a4f3e2f1 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1247,8 +1247,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tint fd;\n \n \t\toptions.action = \"continue\";\n-\t\tset_reflog_action(&options);\n-\n \t\t/* Sanity check */\n \t\tif (get_oid(\"HEAD\", &head))\n \t\t\tdie(_(\"Cannot read HEAD\"));\ndiff --git a/sequencer.c b/sequencer.c\nindex bdd66b4b67a..3634ad5baa9 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -4777,6 +4777,8 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \tif (read_populate_opts(opts))\n \t\treturn -1;\n \tif (is_rebase_i(opts)) {\n+\t\tchar *previous_reflog_action;\n+\n \t\tif ((res = read_populate_todo(r, &todo_list, opts)))\n \t\t\tgoto release_todo_list;\n \n@@ -4787,10 +4789,13 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \t\t\tunlink(rebase_path_dropped());\n \t\t}\n \n+\t\tprevious_reflog_action = xstrdup(getenv(GIT_REFLOG_ACTION));\n+\t\tsetenv(GIT_REFLOG_ACTION, reflog_message(opts, \"continue\", NULL), 1);\n \t\tif (commit_staged_changes(r, opts, &todo_list)) {\n \t\t\tres = -1;\n \t\t\tgoto release_todo_list;\n \t\t}\n+\t\tsetenv(GIT_REFLOG_ACTION, previous_reflog_action, 1);\n \t} else if (!file_exists(get_todo_path(opts)))\n \t\treturn continue_single_pick(r, opts);\n \telse if ((res = read_populate_todo(r, &todo_list, opts)))\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 5253dd1551d..3ca2fbb0d59 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -17,6 +17,7 @@ test_expect_success 'setup' '\n \n \tgit checkout -b conflicts O &&\n \ttest_commit P &&\n+\ttest_commit conflict-X fileX &&\n \ttest_commit Q &&\n \n \tgit checkout -b topic O &&\n@@ -107,13 +108,17 @@ test_reflog () {\n \t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n \t\t\texport GIT_REFLOG_ACTION\n \t\tfi &&\n-\t\tgit rebase $mode main\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\techo resolved >fileX &&\n+\t\tgit add fileX &&\n+\t\tgit rebase --continue\n \t) &&\n \n-\tgit log -g --format=%gs -4 >actual &&\n+\tgit log -g --format=%gs -5 >actual &&\n \twrite_reflog_expect <<-EOF &&\n \t${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n \t${reflog_action:-rebase} (pick): Q\n+\t${reflog_action:-rebase} (continue): conflict-X\n \t${reflog_action:-rebase} (pick): P\n \t${reflog_action:-rebase} (start): checkout main\n \tEOF\n-- \ngitgitgadget\n\n"},{"id":"453961","messageId":"d3afa85ffc5f67722859b739eff3c91959482e48.1650448612.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v2.git.1650448612.gitgitgadget@gmail.com","subject":"[PATCH v2 4/8] rebase --merge: fix reflog message after skipping","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-04-20T09:56:47Z","receivedAt":"2022-04-20T09:57:13Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe reflog message for every pick after running \"rebase --skip\" looks\nlike\n\n\trebase (skip) (pick): commit subject line\n\nFix this by not appending \" (skip)\" to the reflog action.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          |  2 --\n t/t3406-rebase-message.sh | 24 ++++++++++++++++++++++++\n 2 files changed, 24 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex cd9a4f3e2f1..36863117fba 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1273,8 +1273,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n \n \t\toptions.action = \"skip\";\n-\t\tset_reflog_action(&options);\n-\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \t\tropts.flags = RESET_HEAD_HARD;\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 3ca2fbb0d59..8aa6a79acc1 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -163,6 +163,30 @@ test_reflog () {\n \t# check there is only one new entry in the branch reflog\n \ttest_cmp_rev fast-forward@{1} X\n \t'\n+\n+\ttest_expect_success \"rebase $mode --skip reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout conflicts &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\tgit rebase --skip\n+\t) &&\n+\n+\tgit log -g --format=%gs -4 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n+\t${reflog_action:-rebase} (pick): Q\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n+\tEOF\n+\ttest_cmp expect actual\n+\t'\n }\n \n test_reflog --merge\n-- \ngitgitgadget\n\n"},{"id":"453962","messageId":"afa67abe01aed2a403a4f53d95347b1d2a6eac8b.1650448612.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v2.git.1650448612.gitgitgadget@gmail.com","subject":"[PATCH v2 5/8] rebase --apply: respect GIT_REFLOG_ACTION","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-04-20T09:56:48Z","receivedAt":"2022-04-20T09:57:15Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe reflog messages when finishing a rebase hard code \"rebase\" rather\nthan using GIT_REFLOG_ACTION.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 7 ++++---\n t/t3406-rebase-message.sh | 2 +-\n 2 files changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 36863117fba..e50361fc2a9 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -580,10 +580,11 @@ static int move_to_original_branch(struct rebase_options *opts)\n \tif (!opts->onto)\n \t\tBUG(\"move_to_original_branch without onto\");\n \n-\tstrbuf_addf(&branch_reflog, \"rebase finished: %s onto %s\",\n+\tstrbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n+\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n \t\t    opts->head_name, oid_to_hex(&opts->onto->object.oid));\n-\tstrbuf_addf(&head_reflog, \"rebase finished: returning to %s\",\n-\t\t    opts->head_name);\n+\tstrbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n+\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n \tropts.branch = opts->head_name;\n \tropts.flags = RESET_HEAD_REFS_ONLY;\n \tropts.branch_msg = branch_reflog.buf;\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 8aa6a79acc1..bb2a4949abc 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -88,7 +88,7 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n write_reflog_expect () {\n \tif test $mode = --apply\n \tthen\n-\t\tsed 's/.*(finish)/rebase finished/; s/ ([^)]*)//'\n+\t\tsed 's/(finish)/finished/; s/ ([^)]*)//'\n \telse\n \t\tcat\n \tfi >expect\n-- \ngitgitgadget\n\n"},{"id":"453963","messageId":"95161f21e0004cff1bb0915aa39200b286e592e5.1650448612.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v2.git.1650448612.gitgitgadget@gmail.com","subject":"[PATCH v2 6/8] rebase --apply: make reflog messages match rebase --merge","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-04-20T09:56:49Z","receivedAt":"2022-04-20T09:57:25Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe apply backend creates slightly different reflog messages to the\nmerge backend when starting and finishing a rebase and when picking\ncommits. The choice of backend is really an implementation detail so\nit is confusing to have the same command create different messages\ndepending on which backend is selected. Change the apply backend so\nthe reflog messages from the two backends match as closely as\npossible. Note that there is still a difference when committing a\nconflict resolution - the merge backend will use \"(continue)\" rather\nthan \"(pick)\" in that case as it does not know which command created\nthe conflict that it is committing.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 9 +++++----\n t/t3406-rebase-message.sh | 2 +-\n 2 files changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex e50361fc2a9..678339c7bf7 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -580,10 +580,10 @@ static int move_to_original_branch(struct rebase_options *opts)\n \tif (!opts->onto)\n \t\tBUG(\"move_to_original_branch without onto\");\n \n-\tstrbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n+\tstrbuf_addf(&branch_reflog, \"%s (finish): %s onto %s\",\n \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n \t\t    opts->head_name, oid_to_hex(&opts->onto->object.oid));\n-\tstrbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n+\tstrbuf_addf(&head_reflog, \"%s (finish): returning to %s\",\n \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n \tropts.branch = opts->head_name;\n \tropts.flags = RESET_HEAD_REFS_ONLY;\n@@ -613,7 +613,8 @@ static int run_am(struct rebase_options *opts)\n \n \tam.git_cmd = 1;\n \tstrvec_push(&am.args, \"am\");\n-\n+\tstrvec_pushf(&am.env_array, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n+\t\t     getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n \t\tstrvec_push(&am.args, \"--resolved\");\n \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n@@ -1763,7 +1764,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tprintf(_(\"First, rewinding head to replay your work on top of \"\n \t\t\t \"it...\\n\"));\n \n-\tstrbuf_addf(&msg, \"%s: checkout %s\",\n+\tstrbuf_addf(&msg, \"%s (start): checkout %s\",\n \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);\n \tropts.oid = &options.onto->object.oid;\n \tropts.orig_head = &options.orig_head,\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex bb2a4949abc..5c6cd9af3bc 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -88,7 +88,7 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n write_reflog_expect () {\n \tif test $mode = --apply\n \tthen\n-\t\tsed 's/(finish)/finished/; s/ ([^)]*)//'\n+\t\tsed 's/(continue)/(pick)/'\n \telse\n \t\tcat\n \tfi >expect\n-- \ngitgitgadget\n\n"},{"id":"453964","messageId":"d2c1dfbcd5e52bcc3f6040da088fc86b7a506579.1650448612.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v2.git.1650448612.gitgitgadget@gmail.com","subject":"[PATCH v2 7/8] rebase --abort: improve reflog message","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-04-20T09:56:50Z","receivedAt":"2022-04-20T09:57:28Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nWhen aborting a rebase the reflog message looks like\n\n\trebase (abort): updating HEAD\n\nwhich is not very informative. Improve the message by mentioning the\nbranch that we are returning to as we do at the end of a successful\nrebase so it looks like.\n\n\trebase (abort): returning to refs/heads/topic\n\nIf GIT_REFLOG_ACTION is set in the environment we no longer omit\n\"(abort)\" from the reflog message. We don't omit \"(start)\" and\n\"(finish)\" when starting and finishing a rebase in that case so we\nshouldn't omit \"(abort)\".\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 28 ++++++---------------\n t/t3406-rebase-message.sh | 51 +++++++++++++++++++++++++++++++++++++++\n 2 files changed, 59 insertions(+), 20 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 678339c7bf7..70426e17b40 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -992,23 +992,6 @@ static void NORETURN error_on_missing_default_upstream(void)\n \texit(1);\n }\n \n-static void set_reflog_action(struct rebase_options *options)\n-{\n-\tconst char *env;\n-\tstruct strbuf buf = STRBUF_INIT;\n-\n-\tif (!is_merge(options))\n-\t\treturn;\n-\n-\tenv = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);\n-\tif (env && strcmp(\"rebase\", env))\n-\t\treturn; /* only override it if it is \"rebase\" */\n-\n-\tstrbuf_addf(&buf, \"rebase (%s)\", options->action);\n-\tsetenv(GIT_REFLOG_ACTION_ENVIRONMENT, buf.buf, 1);\n-\tstrbuf_release(&buf);\n-}\n-\n static int check_exec_cmd(const char *cmd)\n {\n \tif (strchr(cmd, '\\n'))\n@@ -1287,18 +1270,23 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t}\n \tcase ACTION_ABORT: {\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n-\t\toptions.action = \"abort\";\n-\t\tset_reflog_action(&options);\n+\t\tstruct strbuf head_msg = STRBUF_INIT;\n \n+\t\toptions.action = \"abort\";\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \n \t\tif (read_basic_state(&options))\n \t\t\texit(1);\n+\n+\t\tstrbuf_addf(&head_msg, \"%s (abort): returning to %s\",\n+\t\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n+\t\t\t    options.head_name ? options.head_name\n+\t\t\t\t\t      : oid_to_hex(&options.orig_head));\n \t\tropts.oid = &options.orig_head;\n+\t\tropts.head_msg = head_msg.buf;\n \t\tropts.branch = options.head_name;\n \t\tropts.flags = RESET_HEAD_HARD;\n-\t\tropts.default_reflog_action = DEFAULT_REFLOG_ACTION;\n \t\tif (reset_head(the_repository, &ropts) < 0)\n \t\t\tdie(_(\"could not move back to %s\"),\n \t\t\t    oid_to_hex(&options.orig_head));\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 5c6cd9af3bc..ceca1600053 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -187,6 +187,57 @@ test_reflog () {\n \tEOF\n \ttest_cmp expect actual\n \t'\n+\n+\ttest_expect_success \"rebase $mode --abort reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout conflicts &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\tgit log -g -1 conflicts >branch-expect &&\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\tgit rebase --abort\n+\t) &&\n+\n+\tgit log -g --format=%gs -3 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (abort): returning to refs/heads/conflicts\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n+\tEOF\n+\ttest_cmp expect actual &&\n+\n+\t# check branch reflog is unchanged\n+\tgit log -g -1 conflicts >branch-actual &&\n+\ttest_cmp branch-expect branch-actual\n+\t'\n+\n+\ttest_expect_success \"rebase $mode --abort detached HEAD reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout Q &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\tgit rebase --abort\n+\t) &&\n+\n+\tgit log -g --format=%gs -3 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (abort): returning to $(git rev-parse Q)\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n+\tEOF\n+\ttest_cmp expect actual\n+\t'\n }\n \n test_reflog --merge\n-- \ngitgitgadget\n\n"},{"id":"453965","messageId":"b0d21affa788c5ac953617c3f006b19a28f85d79.1650448612.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v2.git.1650448612.gitgitgadget@gmail.com","subject":"[PATCH v2 8/8] rebase: cleanup action handling","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-04-20T09:56:51Z","receivedAt":"2022-04-20T09:57:34Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nTreating the action as a string is a hang over from the scripted\nrebase. The last commit removed the only remaining use of the action\nthat required a string so lets convert the other action users to use\nthe existing action enum instead. If we ever need the action name as a\nstring in the future the action_names array exists exactly for that\npurpose.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c | 91 +++++++++++++++++++++++-------------------------\n 1 file changed, 43 insertions(+), 48 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 70426e17b40..323f5154092 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -58,6 +58,26 @@ enum empty_type {\n \tEMPTY_ASK\n };\n \n+enum action {\n+\tACTION_NONE = 0,\n+\tACTION_CONTINUE,\n+\tACTION_SKIP,\n+\tACTION_ABORT,\n+\tACTION_QUIT,\n+\tACTION_EDIT_TODO,\n+\tACTION_SHOW_CURRENT_PATCH\n+};\n+\n+static const char *action_names[] = {\n+\t\"undefined\",\n+\t\"continue\",\n+\t\"skip\",\n+\t\"abort\",\n+\t\"quit\",\n+\t\"edit_todo\",\n+\t\"show_current_patch\"\n+};\n+\n struct rebase_options {\n \tenum rebase_type type;\n \tenum empty_type empty;\n@@ -84,7 +104,7 @@ struct rebase_options {\n \t\tREBASE_INTERACTIVE_EXPLICIT = 1<<4,\n \t} flags;\n \tstruct strvec git_am_opts;\n-\tconst char *action;\n+\tenum action action;\n \tint signoff;\n \tint allow_rerere_autoupdate;\n \tint keep_empty;\n@@ -155,24 +175,6 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)\n \treturn replay;\n }\n \n-enum action {\n-\tACTION_NONE = 0,\n-\tACTION_CONTINUE,\n-\tACTION_SKIP,\n-\tACTION_ABORT,\n-\tACTION_QUIT,\n-\tACTION_EDIT_TODO,\n-\tACTION_SHOW_CURRENT_PATCH\n-};\n-\n-static const char *action_names[] = { \"undefined\",\n-\t\t\t\t      \"continue\",\n-\t\t\t\t      \"skip\",\n-\t\t\t\t      \"abort\",\n-\t\t\t\t      \"quit\",\n-\t\t\t\t      \"edit_todo\",\n-\t\t\t\t      \"show_current_patch\" };\n-\n static int edit_todo_file(unsigned flags)\n {\n \tconst char *todo_file = rebase_path_todo();\n@@ -309,8 +311,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)\n \treturn ret;\n }\n \n-static int run_sequencer_rebase(struct rebase_options *opts,\n-\t\t\t\t  enum action command)\n+static int run_sequencer_rebase(struct rebase_options *opts)\n {\n \tunsigned flags = 0;\n \tint abbreviate_commands = 0, ret = 0;\n@@ -325,7 +326,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n \tflags |= opts->reapply_cherry_picks ? TODO_LIST_REAPPLY_CHERRY_PICKS : 0;\n \tflags |= opts->flags & REBASE_NO_QUIET ? TODO_LIST_WARN_SKIPPED_CHERRY_PICKS : 0;\n \n-\tswitch (command) {\n+\tswitch (opts->action) {\n \tcase ACTION_NONE: {\n \t\tif (!opts->onto && !opts->upstream)\n \t\t\tdie(_(\"a base commit must be provided with --upstream or --onto\"));\n@@ -358,7 +359,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n \t\tbreak;\n \t}\n \tdefault:\n-\t\tBUG(\"invalid command '%d'\", command);\n+\t\tBUG(\"invalid command '%d'\", opts->action);\n \t}\n \n \treturn ret;\n@@ -615,7 +616,7 @@ static int run_am(struct rebase_options *opts)\n \tstrvec_push(&am.args, \"am\");\n \tstrvec_pushf(&am.env_array, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n \t\t     getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n-\tif (opts->action && !strcmp(\"continue\", opts->action)) {\n+\tif (opts->action == ACTION_CONTINUE) {\n \t\tstrvec_push(&am.args, \"--resolved\");\n \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n \t\tif (opts->gpg_sign_opt)\n@@ -626,7 +627,7 @@ static int run_am(struct rebase_options *opts)\n \n \t\treturn move_to_original_branch(opts);\n \t}\n-\tif (opts->action && !strcmp(\"skip\", opts->action)) {\n+\tif (opts->action == ACTION_SKIP) {\n \t\tstrvec_push(&am.args, \"--skip\");\n \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n \t\tstatus = run_command(&am);\n@@ -635,7 +636,7 @@ static int run_am(struct rebase_options *opts)\n \n \t\treturn move_to_original_branch(opts);\n \t}\n-\tif (opts->action && !strcmp(\"show-current-patch\", opts->action)) {\n+\tif (opts->action == ACTION_SHOW_CURRENT_PATCH) {\n \t\tstrvec_push(&am.args, \"--show-current-patch\");\n \t\treturn run_command(&am);\n \t}\n@@ -728,7 +729,7 @@ static int run_am(struct rebase_options *opts)\n \treturn status;\n }\n \n-static int run_specific_rebase(struct rebase_options *opts, enum action action)\n+static int run_specific_rebase(struct rebase_options *opts)\n {\n \tint status;\n \n@@ -746,7 +747,7 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n \t\t\topts->gpg_sign_opt = tmp;\n \t\t}\n \n-\t\tstatus = run_sequencer_rebase(opts, action);\n+\t\tstatus = run_sequencer_rebase(opts);\n \t} else if (opts->type == REBASE_APPLY)\n \t\tstatus = run_am(opts);\n \telse\n@@ -1016,7 +1017,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct object_id merge_base;\n \tint ignore_whitespace = 0;\n-\tenum action action = ACTION_NONE;\n \tconst char *gpg_sign = NULL;\n \tstruct string_list exec = STRING_LIST_INIT_NODUP;\n \tconst char *rebase_merges = NULL;\n@@ -1065,18 +1065,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tOPT_BIT(0, \"no-ff\", &options.flags,\n \t\t\tN_(\"cherry-pick all commits, even if unchanged\"),\n \t\t\tREBASE_FORCE),\n-\t\tOPT_CMDMODE(0, \"continue\", &action, N_(\"continue\"),\n+\t\tOPT_CMDMODE(0, \"continue\", &options.action, N_(\"continue\"),\n \t\t\t    ACTION_CONTINUE),\n-\t\tOPT_CMDMODE(0, \"skip\", &action,\n+\t\tOPT_CMDMODE(0, \"skip\", &options.action,\n \t\t\t    N_(\"skip current patch and continue\"), ACTION_SKIP),\n-\t\tOPT_CMDMODE(0, \"abort\", &action,\n+\t\tOPT_CMDMODE(0, \"abort\", &options.action,\n \t\t\t    N_(\"abort and check out the original branch\"),\n \t\t\t    ACTION_ABORT),\n-\t\tOPT_CMDMODE(0, \"quit\", &action,\n+\t\tOPT_CMDMODE(0, \"quit\", &options.action,\n \t\t\t    N_(\"abort but keep HEAD where it is\"), ACTION_QUIT),\n-\t\tOPT_CMDMODE(0, \"edit-todo\", &action, N_(\"edit the todo list \"\n+\t\tOPT_CMDMODE(0, \"edit-todo\", &options.action, N_(\"edit the todo list \"\n \t\t\t    \"during an interactive rebase\"), ACTION_EDIT_TODO),\n-\t\tOPT_CMDMODE(0, \"show-current-patch\", &action,\n+\t\tOPT_CMDMODE(0, \"show-current-patch\", &options.action,\n \t\t\t    N_(\"show the patch file being applied or merged\"),\n \t\t\t    ACTION_SHOW_CURRENT_PATCH),\n \t\tOPT_CALLBACK_F(0, \"apply\", &options, NULL,\n@@ -1189,7 +1189,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tif (preserve_merges_selected)\n \t\tdie(_(\"--preserve-merges was replaced by --rebase-merges\"));\n \n-\tif (action != ACTION_NONE && total_argc != 2) {\n+\tif (options.action != ACTION_NONE && total_argc != 2) {\n \t\tusage_with_options(builtin_rebase_usage,\n \t\t\t\t   builtin_rebase_options);\n \t}\n@@ -1208,11 +1208,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tif (options.root && options.fork_point > 0)\n \t\tdie(_(\"cannot combine '--root' with '--fork-point'\"));\n \n-\tif (action != ACTION_NONE && !in_progress)\n+\tif (options.action != ACTION_NONE && !in_progress)\n \t\tdie(_(\"No rebase in progress?\"));\n \tsetenv(GIT_REFLOG_ACTION_ENVIRONMENT, \"rebase\", 0);\n \n-\tif (action == ACTION_EDIT_TODO && !is_merge(&options))\n+\tif (options.action == ACTION_EDIT_TODO && !is_merge(&options))\n \t\tdie(_(\"The --edit-todo action can only be used during \"\n \t\t      \"interactive rebase.\"));\n \n@@ -1222,16 +1222,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\telse if (exec.nr)\n \t\t\ttrace2_cmd_mode(\"interactive-exec\");\n \t\telse\n-\t\t\ttrace2_cmd_mode(action_names[action]);\n+\t\t\ttrace2_cmd_mode(action_names[options.action]);\n \t}\n \n-\tswitch (action) {\n+\tswitch (options.action) {\n \tcase ACTION_CONTINUE: {\n \t\tstruct object_id head;\n \t\tstruct lock_file lock_file = LOCK_INIT;\n \t\tint fd;\n \n-\t\toptions.action = \"continue\";\n \t\t/* Sanity check */\n \t\tif (get_oid(\"HEAD\", &head))\n \t\t\tdie(_(\"Cannot read HEAD\"));\n@@ -1257,7 +1256,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tcase ACTION_SKIP: {\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n \n-\t\toptions.action = \"skip\";\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \t\tropts.flags = RESET_HEAD_HARD;\n@@ -1272,7 +1270,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n \t\tstruct strbuf head_msg = STRBUF_INIT;\n \n-\t\toptions.action = \"abort\";\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \n@@ -1312,17 +1309,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tgoto cleanup;\n \t}\n \tcase ACTION_EDIT_TODO:\n-\t\toptions.action = \"edit-todo\";\n \t\toptions.dont_finish_rebase = 1;\n \t\tgoto run_rebase;\n \tcase ACTION_SHOW_CURRENT_PATCH:\n-\t\toptions.action = \"show-current-patch\";\n \t\toptions.dont_finish_rebase = 1;\n \t\tgoto run_rebase;\n \tcase ACTION_NONE:\n \t\tbreak;\n \tdefault:\n-\t\tBUG(\"action: %d\", action);\n+\t\tBUG(\"action: %d\", options.action);\n \t}\n \n \t/* Make sure no rebase is in progress */\n@@ -1346,7 +1341,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif ((options.flags & REBASE_INTERACTIVE_EXPLICIT) ||\n-\t    (action != ACTION_NONE) ||\n+\t    (options.action != ACTION_NONE) ||\n \t    (exec.nr > 0) ||\n \t    options.autosquash) {\n \t\tallow_preemptive_ff = 0;\n@@ -1786,7 +1781,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \toptions.revisions = revisions.buf;\n \n run_rebase:\n-\tret = run_specific_rebase(&options, action);\n+\tret = run_specific_rebase(&options);\n \n cleanup:\n \tstrbuf_release(&buf);\n-- \ngitgitgadget\n"},{"id":"453968","messageId":"220420.86a6cg83b0.gmgdl@evledraar.gmail.com","threadId":"57450","inReplyTo":"a4320f2fcf35f180e1c585be4105194f1555a874.1650448612.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 1/8] rebase --apply: remove duplicated code","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-04-20T10:10:54Z","receivedAt":"2022-04-20T10:20:01Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Apr 20 2022, Phillip Wood via GitGitGadget wrote:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> When we are reattaching HEAD after a fast-forward we can use\n> move_to_original_branch() rather than open coding a copy of that\n> code. The old code appears to handle the case where the rebase is\n> started from a detached HEAD but in fact in that case there is nothing\n> to do as we have already updated HEAD.\n>\n> Note that the removal of \"strbuf_release(&msg)\" is safe as there is an\n> identical call just above this hunk which can be seen by viewing the\n> diff with -U6.\n\nInstead of assuring the reader that this is OK, perhaps just squash this\nin:\n\t\n\tdiff --git a/builtin/rebase.c b/builtin/rebase.c\n\tindex 4a664964c30..5108679e816 100644\n\t--- a/builtin/rebase.c\n\t+++ b/builtin/rebase.c\n\t@@ -1029,7 +1029,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n\t \tint ret, flags, total_argc, in_progress = 0;\n\t \tint keep_base = 0;\n\t \tint ok_to_skip_pre_rebase = 0;\n\t-\tstruct strbuf msg = STRBUF_INIT;\n\t \tstruct strbuf revisions = STRBUF_INIT;\n\t \tstruct strbuf buf = STRBUF_INIT;\n\t \tstruct object_id merge_base;\n\t@@ -1769,17 +1768,22 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n\t \t\tprintf(_(\"First, rewinding head to replay your work on top of \"\n\t \t\t\t \"it...\\n\"));\n\t \n\t-\tstrbuf_addf(&msg, \"%s: checkout %s\",\n\t-\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);\n\t-\tropts.oid = &options.onto->object.oid;\n\t-\tropts.orig_head = &options.orig_head,\n\t-\tropts.flags = RESET_HEAD_DETACH | RESET_ORIG_HEAD |\n\t+\t{\n\t+\t\tstruct strbuf msg = STRBUF_INIT;\n\t+\n\t+\t\tstrbuf_addf(&msg, \"%s: checkout %s\",\n\t+\t\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n\t+\t\t\t    options.onto_name);\n\t+\t\tropts.oid = &options.onto->object.oid;\n\t+\t\tropts.orig_head = &options.orig_head,\n\t+\t\t\tropts.flags = RESET_HEAD_DETACH | RESET_ORIG_HEAD |\n\t \t\t\tRESET_HEAD_RUN_POST_CHECKOUT_HOOK;\n\t-\tropts.head_msg = msg.buf;\n\t-\tropts.default_reflog_action = DEFAULT_REFLOG_ACTION;\n\t-\tif (reset_head(the_repository, &ropts))\n\t-\t\tdie(_(\"Could not detach HEAD\"));\n\t-\tstrbuf_release(&msg);\n\t+\t\tropts.head_msg = msg.buf;\n\t+\t\tropts.default_reflog_action = DEFAULT_REFLOG_ACTION;\n\t+\t\tif (reset_head(the_repository, &ropts))\n\t+\t\t\tdie(_(\"Could not detach HEAD\"));\n\t+\t\tstrbuf_release(&msg);\n\t+\t}\n\t \n\t \t/*\n\t \t * If the onto is a proper descendant of the tip of the branch, then\n\nThat's a 2-line change (aside from the scope addition) if viewed with\n-w. I.e. before your change below we needed &msg in two places, now that\nwe only need it in one it seems better just to move the variable to be\nscoped with its only user.\n\nAnd maybe it's getting too much into unrelated cleanup, but this change\nalso leaves the loose end that the \"ropts\" variable no longer needs to\nbe shared. You added it in 6ae8086161d (reset_head(): take struct\nrebase_head_opts, 2022-01-26) along whith the memset() removed here, but\n(on top of the proposed squash) we could also do this:\n\n\t\n\tdiff --git a/builtin/rebase.c b/builtin/rebase.c\n\tindex 5108679e816..8e2dc74c834 100644\n\t--- a/builtin/rebase.c\n\t+++ b/builtin/rebase.c\n\t@@ -1043,7 +1043,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n\t \tint reschedule_failed_exec = -1;\n\t \tint allow_preemptive_ff = 1;\n\t \tint preserve_merges_selected = 0;\n\t-\tstruct reset_head_opts ropts = { 0 };\n\t \tstruct option builtin_rebase_options[] = {\n\t \t\tOPT_STRING(0, \"onto\", &options.onto_name,\n\t \t\t\t   N_(\"revision\"),\n\t@@ -1275,7 +1274,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n\t \t}\n\t \tcase ACTION_SKIP: {\n\t \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n\t-\n\t+\t\tstruct reset_head_opts ropts = { 0 };\n\t+\t\n\t \t\toptions.action = \"skip\";\n\t \t\tset_reflog_action(&options);\n\t \n\t@@ -1291,6 +1291,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n\t \t}\n\t \tcase ACTION_ABORT: {\n\t \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n\t+\t\tstruct reset_head_opts ropts = { 0 };\n\t+\n\t \t\toptions.action = \"abort\";\n\t \t\tset_reflog_action(&options);\n\t \n\t@@ -1770,6 +1772,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n\t \n\t \t{\n\t \t\tstruct strbuf msg = STRBUF_INIT;\n\t+\t\tstruct reset_head_opts ropts = { 0 };\n\t \n\t \t\tstrbuf_addf(&msg, \"%s: checkout %s\",\n\t \t\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n\nI.e. the \"ropts\" earlier in the function wasn't shared with the code\nbelow, we'd \"goto\" past it...\n>\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  builtin/rebase.c | 11 +----------\n>  1 file changed, 1 insertion(+), 10 deletions(-)\n>\n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index e942c300f8c..4832f16e675 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -1782,19 +1782,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>  \t * If the onto is a proper descendant of the tip of the branch, then\n>  \t * we just fast-forwarded.\n>  \t */\n> -\tstrbuf_reset(&msg);\n>  \tif (oideq(&merge_base, &options.orig_head)) {\n>  \t\tprintf(_(\"Fast-forwarded %s to %s.\\n\"),\n>  \t\t\tbranch_name, options.onto_name);\n> -\t\tstrbuf_addf(&msg, \"rebase finished: %s onto %s\",\n> -\t\t\toptions.head_name ? options.head_name : \"detached HEAD\",\n> -\t\t\toid_to_hex(&options.onto->object.oid));\n> -\t\tmemset(&ropts, 0, sizeof(ropts));\n> -\t\tropts.branch = options.head_name;\n> -\t\tropts.flags = RESET_HEAD_REFS_ONLY;\n> -\t\tropts.head_msg = msg.buf;\n> -\t\treset_head(the_repository, &ropts);\n> -\t\tstrbuf_release(&msg);\n> +\t\tmove_to_original_branch(&options);\n>  \t\tret = finish_rebase(&options);\n>  \t\tgoto cleanup;\n>  \t}\n\n"},{"id":"453969","messageId":"220420.865yn4833u.gmgdl@evledraar.gmail.com","threadId":"57450","inReplyTo":"95161f21e0004cff1bb0915aa39200b286e592e5.1650448612.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 6/8] rebase --apply: make reflog messages match rebase --merge","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-04-20T10:22:54Z","receivedAt":"2022-04-20T10:24:12Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Apr 20 2022, Phillip Wood via GitGitGadget wrote:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> The apply backend creates slightly different reflog messages to the\n> merge backend when starting and finishing a rebase and when picking\n> commits. The choice of backend is really an implementation detail so\n> it is confusing to have the same command create different messages\n> depending on which backend is selected. Change the apply backend so\n> the reflog messages from the two backends match as closely as\n> possible. Note that there is still a difference when committing a\n> conflict resolution - the merge backend will use \"(continue)\" rather\n> than \"(pick)\" in that case as it does not know which command created\n> the conflict that it is committing.\n>\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  builtin/rebase.c          | 9 +++++----\n>  t/t3406-rebase-message.sh | 2 +-\n>  2 files changed, 6 insertions(+), 5 deletions(-)\n>\n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index e50361fc2a9..678339c7bf7 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -580,10 +580,10 @@ static int move_to_original_branch(struct rebase_options *opts)\n>  \tif (!opts->onto)\n>  \t\tBUG(\"move_to_original_branch without onto\");\n>  \n> -\tstrbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n> +\tstrbuf_addf(&branch_reflog, \"%s (finish): %s onto %s\",\n>  \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n>  \t\t    opts->head_name, oid_to_hex(&opts->onto->object.oid));\n> -\tstrbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n> +\tstrbuf_addf(&head_reflog, \"%s (finish): returning to %s\",\n>  \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n>  \tropts.branch = opts->head_name;\n>  \tropts.flags = RESET_HEAD_REFS_ONLY;\n> @@ -613,7 +613,8 @@ static int run_am(struct rebase_options *opts)\n>  \n>  \tam.git_cmd = 1;\n>  \tstrvec_push(&am.args, \"am\");\n> -\n> +\tstrvec_pushf(&am.env_array, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n> +\t\t     getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n>  \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n>  \t\tstrvec_push(&am.args, \"--resolved\");\n>  \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n> @@ -1763,7 +1764,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>  \t\tprintf(_(\"First, rewinding head to replay your work on top of \"\n>  \t\t\t \"it...\\n\"));\n>  \n> -\tstrbuf_addf(&msg, \"%s: checkout %s\",\n> +\tstrbuf_addf(&msg, \"%s (start): checkout %s\",\n>  \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);\n>  \tropts.oid = &options.onto->object.oid;\n>  \tropts.orig_head = &options.orig_head,\n> diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\n> index bb2a4949abc..5c6cd9af3bc 100755\n> --- a/t/t3406-rebase-message.sh\n> +++ b/t/t3406-rebase-message.sh\n> @@ -88,7 +88,7 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n>  write_reflog_expect () {\n>  \tif test $mode = --apply\n>  \tthen\n> -\t\tsed 's/(finish)/finished/; s/ ([^)]*)//'\n> +\t\tsed 's/(continue)/(pick)/'\n>  \telse\n>  \t\tcat\n>  \tfi >expect\n\nI like the new message better, but I wonder given that the old message\nhas been with us since 6fd2f5e60d4 (rebase: operate on a detached HEAD,\n2007-11-08) whether this will break anything in the wild.\n"},{"id":"453970","messageId":"220420.861qxs82gl.gmgdl@evledraar.gmail.com","threadId":"57450","inReplyTo":"b0d21affa788c5ac953617c3f006b19a28f85d79.1650448612.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 8/8] rebase: cleanup action handling","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-04-20T10:34:15Z","receivedAt":"2022-04-20T10:38:12Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Apr 20 2022, Phillip Wood via GitGitGadget wrote:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> Treating the action as a string is a hang over from the scripted\n> rebase. The last commit removed the only remaining use of the action\n> that required a string so lets convert the other action users to use\n> the existing action enum instead. If we ever need the action name as a\n> string in the future the action_names array exists exactly for that\n> purpose.\n\nThis is very much an existing issue, just noting this since I read this\nover: We really should just carry that \"action_names\" in the \"switch\"\nstatement immediately below the trace2_cmd_mode() call, see \"git grep\ntrace2_cmd_mode\". I.e. usually we do it in the \"callback\".\n\nOr actually just add a OPT_CMDMODE_TRACE2(), which would be an\nOPT_CALLBACK (see parse_opt_show_current_patch for such an example for a\ncmdmode callback) that would take the \"--continue\" string, log\n\"continue\" etc (do we really need to munge \"edit-todo\" to \"edit_todo\").\n\nBut I digress, this code looks fine, thanks.\n"},{"id":"453994","messageId":"xmqq35i7r4rj.fsf@gitster.g","threadId":"57450","inReplyTo":"a4320f2fcf35f180e1c585be4105194f1555a874.1650448612.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 1/8] rebase --apply: remove duplicated code","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-04-20T18:25:36Z","receivedAt":"2022-04-20T18:25:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> -\tstrbuf_reset(&msg);\n\nThis is unnecessary, because we have released immediately before.\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> When we are reattaching HEAD after a fast-forward we can use\n> move_to_original_branch() rather than open coding a copy of that\n> code. The old code appears to handle the case where the rebase is\n> started from a detached HEAD but in fact in that case there is nothing\n> to do as we have already updated HEAD.\n\nAt the beginning of move_to_original_branch(), there is an early\nreturn to do nothing when the head is detached.  But the code before\nthe pre-context of the hunk already detached the head at the \"onto\",\nand the fast-forward case wants to leave the detached head pointing\nat that \"onto\" commit, so the early return without doing anything is\nexactly what we want to see.\n\nDoes that mean that the original code had left two reflog entries\nfor HEAD, one to detach at the \"onto\" commit, and then in this block\nto say \"rebase finished\" here?  With the new code, because we return\nearly from move_to_original_branch(), we no longer leave the \"rebase\nfinished\" record in the reflog of HEAD?\n\nIs it done deliberately as an improvement, or an oversight that led\nto a possible regression?\n\nOr do we still add the reflog entry for HEAD that says \"rebase finished\"\nsomewhere else when we trigger the early return and I am misreading\nthe code?\n\n> >  \tif (oideq(&merge_base, &options.orig_head)) {\n>  \t\tprintf(_(\"Fast-forwarded %s to %s.\\n\"),\n>  \t\t\tbranch_name, options.onto_name);\n> -\t\tstrbuf_addf(&msg, \"rebase finished: %s onto %s\",\n> -\t\t\toptions.head_name ? options.head_name : \"detached HEAD\",\n> -\t\t\toid_to_hex(&options.onto->object.oid));\n> -\t\tmemset(&ropts, 0, sizeof(ropts));\n> -\t\tropts.branch = options.head_name;\n> -\t\tropts.flags = RESET_HEAD_REFS_ONLY;\n> -\t\tropts.head_msg = msg.buf;\n> -\t\treset_head(the_repository, &ropts);\n> -\t\tstrbuf_release(&msg);\n> +\t\tmove_to_original_branch(&options);\n>  \t\tret = finish_rebase(&options);\n>  \t\tgoto cleanup;\n>  \t}\n\n"},{"id":"453995","messageId":"xmqqwnfjppk1.fsf@gitster.g","threadId":"57450","inReplyTo":"xmqq35i7r4rj.fsf@gitster.g","subject":"Re: [PATCH v2 1/8] rebase --apply: remove duplicated code","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-04-20T18:39:26Z","receivedAt":"2022-04-20T18:39:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> \"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>\n>> -\tstrbuf_reset(&msg);\n>\n> This is unnecessary, because we have released immediately before.\n\nSorry. I meant \"reset is unnecessary and it is the right thing to\nremove it here\", but I just realized it can be misread to say \"this\nchange is unnecessary\".\n"},{"id":"453999","messageId":"xmqqzgkfo6gy.fsf@gitster.g","threadId":"57450","inReplyTo":"0904b50a377ce3ac242f9594a635f9ae7cffc687.1650448612.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 2/8] t3406: rework rebase reflog tests","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-04-20T20:17:01Z","receivedAt":"2022-04-20T20:17:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> Refactor the tests in preparation for adding more tests in the next\n> few commits. The reworked tests use the same function for testing both\n> the \"merge\" and \"apply\" backends. The test coverage for the \"apply\"\n> backend now includes setting GIT_REFLOG_ACTION.\n>\n> Note that rebasing the \"conflicts\" branch does not create any\n> conflicts yet. A commit to do that will be added in the next commit\n> and the diff ends up smaller if we have don't rename the branch when\n> it is added.\n\n\"if we have don't rename\"?  Ecannotparse.\n\n>\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  t/t3406-rebase-message.sh | 115 +++++++++++++++++++++++++-------------\n>  1 file changed, 76 insertions(+), 39 deletions(-)\n>\n> diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\n> index d17b450e811..5253dd1551d 100755\n> --- a/t/t3406-rebase-message.sh\n> +++ b/t/t3406-rebase-message.sh\n> @@ -10,10 +10,15 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>  test_expect_success 'setup' '\n>  \ttest_commit O fileO &&\n>  \ttest_commit X fileX &&\n> +\tgit branch fast-forward &&\n>  \ttest_commit A fileA &&\n>  \ttest_commit B fileB &&\n>  \ttest_commit Y fileY &&\n>  \n> +\tgit checkout -b conflicts O &&\n> +\ttest_commit P &&\n> +\ttest_commit Q &&\n> +\n>  \tgit checkout -b topic O &&\n>  \tgit cherry-pick A B &&\n>  \ttest_commit Z fileZ &&\n\nSo, we'd create\n\n\tO---X---A---B---Y (main)\n        |\\\n        | P---Q (conflicts)\n        \\\n         A'--B'--Z (topic)\n\nwith the above.  The \"fast-forward\" branch is not yet used.\n\nWithout reading the rest of this patch (or the series), especially\nbecause you said you'll test multiple rebase strategies (and\npresumably make sure they result in the same state), my gut says\nthat it may not buy us much to create such an unused branch.  If we\nsuccessfully run a fast-forward test on the branch for one strategy,\nwe have to rewind the result before testing another strategy anyway,\nso forking a branch to be tested at X when we start testing each\nrebase strategy would be fine.  But we'll see.\n\n> @@ -79,54 +84,86 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n>  \ttest_i18ngrep \"Invalid whitespace option\" err\n>  '\n>  \n> -test_expect_success 'GIT_REFLOG_ACTION' '\n> -\tgit checkout start &&\n> -\ttest_commit reflog-onto &&\n> -\tgit checkout -b reflog-topic start &&\n> -\ttest_commit reflog-to-rebase &&\n> -\n> -\tgit rebase reflog-onto &&\n> -\tgit log -g --format=%gs -3 >actual &&\n> -\tcat >expect <<-\\EOF &&\n> -\trebase (finish): returning to refs/heads/reflog-topic\n> -\trebase (pick): reflog-to-rebase\n> -\trebase (start): checkout reflog-onto\n> +write_reflog_expect () {\n> +\tif test $mode = --apply\n> +\tthen\n> +\t\tsed 's/.*(finish)/rebase finished/; s/ ([^)]*)//'\n> +\telse\n> +\t\tcat\n> +\tfi >expect\n> +}\n> +\n> +test_reflog () {\n> +\tmode=$1\n> +\treflog_action=\"$2\"\n\n$1 being left unquoted while $2 being quoted makes them look\nincoherent.  It is not wrong to enclose $2 in double quotes, but it\nis not necessary.\n\n> +\ttest_expect_success \"rebase $mode reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n> +\tgit checkout conflicts &&\n> +\ttest_when_finished \"git reset --hard Q\" &&\n> +\n> +\t(\n> +\t\tif test -n \"$reflog_action\"\n> +\t\tthen\n> +\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n> +\t\t\texport GIT_REFLOG_ACTION\n> +\t\tfi &&\n> +\t\tgit rebase $mode main\n> +\t) &&\n\nIs the subshell because you may want to export the envirohnment, or\nis there anything more subtle going on?\n\n> +\tgit log -g --format=%gs -4 >actual &&\n> +\twrite_reflog_expect <<-EOF &&\n> +\t${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n> +\t${reflog_action:-rebase} (pick): Q\n> +\t${reflog_action:-rebase} (pick): P\n> +\t${reflog_action:-rebase} (start): checkout main\n>  \tEOF\n>  \ttest_cmp expect actual &&\n\nWe reset to Q and rebase it onto main, which would mean that we'd\nreplay P and then Q on top of Y.  The 4 most recent events on HEAD\nare that we start at 'main', picking P and Q and then updating the\nconflicts branch with the result.  OK.\n\nIt is not what we used to test, but with reference to Q that was\nestablished at the beginning, though.\n\n> -\tgit checkout -b reflog-prefix reflog-to-rebase &&\n> -\tGIT_REFLOG_ACTION=change-the-reflog git rebase reflog-onto &&\n> -\tgit log -g --format=%gs -3 >actual &&\n> -\tcat >expect <<-\\EOF &&\n> -\tchange-the-reflog (finish): returning to refs/heads/reflog-prefix\n> -\tchange-the-reflog (pick): reflog-to-rebase\n> -\tchange-the-reflog (start): checkout reflog-onto\n> +\tgit log -g --format=%gs -1 conflicts >actual &&\n> +\twrite_reflog_expect <<-EOF &&\n> +\t${reflog_action:-rebase} (finish): refs/heads/conflicts onto $(git rev-parse main)\n>  \tEOF\n\nAnd after doing that, there only is one reflog entry for the\nconflicts branch itself, i.e. record of finishing to rebase.\n\nFor both of the above two tests, I wonder if we want to make sure\nthese four and one entries are the ONLY entries added by the\noperation.  I.e. take the topmost reflog entry _before_ starting to\nrun rebase for both conflicts branch and HEAD, grab five and two\nreflog entries after the operation from conflicts and HEAD and make\nsure the four and one are the truly new entries added by the\noperation, or something like that.  Even easier would be to merely\ncount the number of reflog entries of HEAD and conflicts before\nrebasing, and count them after.  We can do subtraction in the shell\njust fine.\n\n> +\ttest_cmp expect actual &&\n>  \n> +\t# check there is only one new entry in the branch reflog\n\nIt is a valid thing to try verifying, but ...\n\n> +\ttest_cmp_rev conflicts@{1} Q\n\n... it is unclear how this can count the new reflog entries.  If we\nadded two reflog entries, one pointing at Y (i.e. tip of main),\nanother that points at Q (i.e. tip of conflicts before the rebasing),\nconflicts@{1} would be the same as Q.\n\n> +\t'\n> +\n> +\ttest_expect_success \"rebase $mode fast-forward reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n> +\tgit checkout fast-forward &&\n> +\ttest_when_finished \"git reset --hard X\" &&\n> +\n> +\t(\n> +\t\tif test -n \"$reflog_action\"\n> +\t\tthen\n> +\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n> +\t\t\texport GIT_REFLOG_ACTION\n> +\t\tfi &&\n> +\t\tgit rebase $mode main\n> +\t) &&\n> +\n> +\tgit log -g --format=%gs -2 >actual &&\n> +\twrite_reflog_expect <<-EOF &&\n> +\t${reflog_action:-rebase} (finish): returning to refs/heads/fast-forward\n> +\t${reflog_action:-rebase} (start): checkout main\n>  \tEOF\n>  \ttest_cmp expect actual &&\n\nLikewise.  This only makes sure that the topmost two are what you\nexpect without checking if it added anything extra before these two.\nActually counting the entries would give you an easy fix.\n\n> -\tgit log -g --format=%gs -2 reflog-apply >actual &&\n> -\tcat >expect <<-EOF &&\n> -\trebase finished: refs/heads/reflog-apply onto $(git rev-parse Y)\n> -\tbranch: Created from start\n> +\tgit log -g --format=%gs -1 fast-forward >actual &&\n> +\twrite_reflog_expect <<-EOF &&\n> +\t${reflog_action:-rebase} (finish): refs/heads/fast-forward onto $(git rev-parse main)\n>  \tEOF\n> -\ttest_cmp expect actual\n> -'\n> +\ttest_cmp expect actual &&\n> +\n> +\t# check there is only one new entry in the branch reflog\n> +\ttest_cmp_rev fast-forward@{1} X\n\nThe same.  This does not ensure there is only one new entry.  It\nmerely says that the set of entries you cared about (which is a set\nof one) is preceded by an entry that happened to point at X.\n\n> +\t'\n> +}\n> +\n> +test_reflog --merge\n> +test_reflog --merge my-reflog-action\n> +test_reflog --apply\n> +test_reflog --apply my-reflog-action\n>  \n>  test_expect_success 'rebase -i onto unrelated history' '\n>  \tgit init unrelated &&\n\nThanks.\n"},{"id":"454038","messageId":"xmqq4k2nmmeg.fsf@gitster.g","threadId":"57450","inReplyTo":"95161f21e0004cff1bb0915aa39200b286e592e5.1650448612.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 6/8] rebase --apply: make reflog messages match rebase --merge","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-04-20T22:15:51Z","receivedAt":"2022-04-20T22:15:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> The apply backend creates slightly different reflog messages to the\n> merge backend when starting and finishing a rebase and when picking\n> commits. The choice of backend is really an implementation detail so\n> it is confusing to have the same command create different messages\n> depending on which backend is selected. Change the apply backend so\n> the reflog messages from the two backends match as closely as\n> possible.\n\nI do not agree with that line of thought.\n\nWhen choosing backend, the user clearly cares which one is used to\ndo the job, so it is far from an \"implementation detail\" that is\nbetter hidden from the users.  In other words, the message being\ndifferent is not source of confusion in this case.  Producing\ndifferent messages depending on the version of Git may create worse\nconfusion, though.\n\n> Note that there is still a difference when committing a\n> conflict resolution - the merge backend will use \"(continue)\" rather\n> than \"(pick)\" in that case as it does not know which command created\n> the conflict that it is committing.\n\nThat is OK, unless we can teach the backend to produce a more proper\none (if 'continue' is considered less proper, that is, than 'pick';\nI do not think I would personally care between the two words too\nmuch).\n\n> -\tstrbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n> +\tstrbuf_addf(&branch_reflog, \"%s (finish): %s onto %s\",\n>  \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n>  \t\t    opts->head_name, oid_to_hex(&opts->onto->object.oid));\n> -\tstrbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n> +\tstrbuf_addf(&head_reflog, \"%s (finish): returning to %s\",\n>  \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n>  \tropts.branch = opts->head_name;\n>  \tropts.flags = RESET_HEAD_REFS_ONLY;\n\nThese convey the same information so it is \"Meh---I do not care too\nstrongly about them\" kind of change, unless the justification is\n\"let's show the (word) in parehtheses consistently in these reflog\nentries\", in which case they are welcome change.\n\nOverall, I'd rather see us not to apply this patch at this point in\ntime, especially ...\n\n> +\tstrvec_pushf(&am.env_array, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n\n... this new use of .env_array member semantically conflicts with\nthe removal of .env member from the structure being proposed in\nanother topic in flight.\n\n> +\t\t     getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n>  \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n>  \t\tstrvec_push(&am.args, \"--resolved\");\n>  \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n> @@ -1763,7 +1764,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>  \t\tprintf(_(\"First, rewinding head to replay your work on top of \"\n>  \t\t\t \"it...\\n\"));\n>  \n> -\tstrbuf_addf(&msg, \"%s: checkout %s\",\n> +\tstrbuf_addf(&msg, \"%s (start): checkout %s\",\n>  \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);\n\nI think this one is a strict improvement with or without () around\nthe word that tells us what phase of the rebase operation we are at,\nand if it happens to match what the other backend produces, that\nwould be a tolerable small regression, even though it makes it hard\nto tell them apart.\n"},{"id":"464684","messageId":"a84cf971a753e294555ca8f2b7eaa4c75a8fa491.1665567312.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v3.git.1665567312.gitgitgadget@gmail.com","subject":"[PATCH v3 1/8] rebase --apply: remove duplicated code","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-12T09:35:05Z","receivedAt":"2022-10-12T09:35:22Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nUse move_to_original_branch() when reattaching HEAD after a fast-forward\nrather than open coding a copy of that code. move_to_original_branch()\ndoes not call reset_head() if head_name is NULL but there should be no\nuser visible changes even though we currently call reset_head() in that\ncase. The reason for this is that the reset_head() call does not add a\nmessage to the reflog because we're not changing the commit that HEAD\npoints to and so lock_ref_for_update() elides the update. When head_name\nis not NULL then reset_head() behaves like \"git symbolic-ref\" and so the\nreflog is updated.\n\nNote that the removal of \"strbuf_release(&msg)\" is safe as there is an\nidentical call just above this hunk which can be seen by viewing the\ndiff with -U6.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c | 11 +----------\n 1 file changed, 1 insertion(+), 10 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex a2ca66b54be..51accb4fd61 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1808,19 +1808,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t * If the onto is a proper descendant of the tip of the branch, then\n \t * we just fast-forwarded.\n \t */\n-\tstrbuf_reset(&msg);\n \tif (oideq(&branch_base, &options.orig_head->object.oid)) {\n \t\tprintf(_(\"Fast-forwarded %s to %s.\\n\"),\n \t\t\tbranch_name, options.onto_name);\n-\t\tstrbuf_addf(&msg, \"rebase finished: %s onto %s\",\n-\t\t\toptions.head_name ? options.head_name : \"detached HEAD\",\n-\t\t\toid_to_hex(&options.onto->object.oid));\n-\t\tmemset(&ropts, 0, sizeof(ropts));\n-\t\tropts.branch = options.head_name;\n-\t\tropts.flags = RESET_HEAD_REFS_ONLY;\n-\t\tropts.head_msg = msg.buf;\n-\t\treset_head(the_repository, &ropts);\n-\t\tstrbuf_release(&msg);\n+\t\tmove_to_original_branch(&options);\n \t\tret = finish_rebase(&options);\n \t\tgoto cleanup;\n \t}\n-- \ngitgitgadget\n\n"},{"id":"464685","messageId":"pull.1150.v3.git.1665567312.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v2.git.1650448612.gitgitgadget@gmail.com","subject":"[PATCH v3 0/8] rebase: make reflog messages independent of the backend","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-12T09:35:04Z","receivedAt":"2022-10-12T09:35:23Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"This series fixes some bugs in the reflog messages when rebasing and changes\nthe reflog messages of \"rebase --apply\" to match \"rebase --merge\" with the\naim of making the reflog easier to parse.\n\nThanks to everyone who commented on V2, I've added the review club\nparticipants that I've got address for to the cc list. I've rebased onto\npw/rebase-keep-base-fixes.\n\nChange since V2:\n\n * Patch 1: Reworded the commit message to address the concerns in [1,2]\n   about the behavior when head_name is NULL. There is also a small change\n   due to being rebased.\n\n * Patch 2: Unchanged. There wasn't much love for parameterized tests in\n   review club but we want to ensure both backends produce the same messages\n   I think this is the safest way to achieve that. Using separate tests\n   makes it too easy to introduce subtle differences in the testing of the\n   two backends.\n\n * Patch 3: Added a note to the commit message to address the concerns in\n   [1] about not resetting GIT_REFLOG_ACTION when we return early.\n\n * Patches 4 & 5: Unchanged.\n\n * Patch 6: Reworded the commit message to make a stronger argument for this\n   change. There are concerns about backwards compatibility in [1,3,4] but\n   (i) we have made similar changes in the past without complaints and (ii)\n   we're changing the message to an existing format. There is also a small\n   change due to being rebased.\n\n * Patches 7 & 8: Small changes due to rebase.\n\n[1]\nhttps://docs.google.com/document/d/14L8BAumGTpsXpjDY8VzZ4rRtpAjuGrFSRqn3stCuS_w/edit?pli=1#heading=h.t6g5l2t5ibzw\n[2] https://lore.kernel.org/git/xmqq35i7r4rj.fsf@gitster.g/ [3]\nhttps://lore.kernel.org/git/xmqq4k2nmmeg.fsf@gitster.g/ [4]\nhttps://lore.kernel.org/git/220420.865yn4833u.gmgdl@evledraar.gmail.com/\n\nV2 Cover Letter:\n\nThanks to Christian and Elijah for their comments on V1.\n\nI've updated commit message for patch 1 to try and be clearer about the\nremoval of a call to strbuf_release() and spilt out the test changes from\nthe old patch 2 into a separate preparatory patch.\n\nV1 Cover Letter:\n\nThis is a series of rebase reflog related patches with the aim of unifying\nthe reflog messages from the two rebase backends.\n\n * improve rebase reflog test coverage\n * rebase --merge: fix reflog messages for --continue and --skip\n * rebase --apply: respect GIT_REFLOG_ACTION\n * rebase --abort: improve reflog message\n * unify reflog messages between the two rebase backends\n\nThis series is based on pw/use-inprocess-checkout-in-rebase\n\nPhillip Wood (8):\n  rebase --apply: remove duplicated code\n  t3406: rework rebase reflog tests\n  rebase --merge: fix reflog when continuing\n  rebase --merge: fix reflog message after skipping\n  rebase --apply: respect GIT_REFLOG_ACTION\n  rebase --apply: make reflog messages match rebase --merge\n  rebase --abort: improve reflog message\n  rebase: cleanup action handling\n\n builtin/rebase.c          | 146 ++++++++++++------------------\n sequencer.c               |   5 ++\n t/t3406-rebase-message.sh | 185 +++++++++++++++++++++++++++++++-------\n 3 files changed, 215 insertions(+), 121 deletions(-)\n\n\nbase-commit: 0203c679871112c78adc6428a8ed6c04c30ccad9\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1150%2Fphillipwood%2Fwip%2Frebase-reflog-fixes-v3\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1150/phillipwood/wip/rebase-reflog-fixes-v3\nPull-Request: https://github.com/gitgitgadget/git/pull/1150\n\nRange-diff vs v2:\n\n 1:  a4320f2fcf3 ! 1:  a84cf971a75 rebase --apply: remove duplicated code\n     @@ Metadata\n       ## Commit message ##\n          rebase --apply: remove duplicated code\n      \n     -    When we are reattaching HEAD after a fast-forward we can use\n     -    move_to_original_branch() rather than open coding a copy of that\n     -    code. The old code appears to handle the case where the rebase is\n     -    started from a detached HEAD but in fact in that case there is nothing\n     -    to do as we have already updated HEAD.\n     +    Use move_to_original_branch() when reattaching HEAD after a fast-forward\n     +    rather than open coding a copy of that code. move_to_original_branch()\n     +    does not call reset_head() if head_name is NULL but there should be no\n     +    user visible changes even though we currently call reset_head() in that\n     +    case. The reason for this is that the reset_head() call does not add a\n     +    message to the reflog because we're not changing the commit that HEAD\n     +    points to and so lock_ref_for_update() elides the update. When head_name\n     +    is not NULL then reset_head() behaves like \"git symbolic-ref\" and so the\n     +    reflog is updated.\n      \n          Note that the removal of \"strbuf_release(&msg)\" is safe as there is an\n          identical call just above this hunk which can be seen by viewing the\n     @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix\n       \t * we just fast-forwarded.\n       \t */\n      -\tstrbuf_reset(&msg);\n     - \tif (oideq(&merge_base, &options.orig_head)) {\n     + \tif (oideq(&branch_base, &options.orig_head->object.oid)) {\n       \t\tprintf(_(\"Fast-forwarded %s to %s.\\n\"),\n       \t\t\tbranch_name, options.onto_name);\n      -\t\tstrbuf_addf(&msg, \"rebase finished: %s onto %s\",\n 2:  0904b50a377 = 2:  b9255ad35d2 t3406: rework rebase reflog tests\n 3:  6c15f00e170 ! 3:  ea4da25a19c rebase --merge: fix reflog when continuing\n     @@ Commit message\n          in pick_commits(). Both of these will be fixed in a future series that\n          stops the sequencer calling setenv().\n      \n     +    If we fail to commit the staged changes then we error out so\n     +    GIT_REFLOG_ACTION does not need to be reset in that case.\n     +\n          Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n      \n       ## builtin/rebase.c ##\n 4:  d3afa85ffc5 = 4:  225ff4baef7 rebase --merge: fix reflog message after skipping\n 5:  afa67abe01a = 5:  1094681eb11 rebase --apply: respect GIT_REFLOG_ACTION\n 6:  95161f21e00 ! 6:  a5338e6bdd8 rebase --apply: make reflog messages match rebase --merge\n     @@ Commit message\n          rebase --apply: make reflog messages match rebase --merge\n      \n          The apply backend creates slightly different reflog messages to the\n     -    merge backend when starting and finishing a rebase and when picking\n     -    commits. The choice of backend is really an implementation detail so\n     -    it is confusing to have the same command create different messages\n     -    depending on which backend is selected. Change the apply backend so\n     -    the reflog messages from the two backends match as closely as\n     -    possible. Note that there is still a difference when committing a\n     -    conflict resolution - the merge backend will use \"(continue)\" rather\n     -    than \"(pick)\" in that case as it does not know which command created\n     -    the conflict that it is committing.\n     +    merge backend when starting or finishing a rebase and when picking\n     +    commits. These differences make it harder than it needs to be to parse\n     +    the reflog (I have a script that reads the finishing messages from\n     +    rebase and it is a pain to have to accommodate two different message\n     +    formats). While it is possible to determine the backend used for a\n     +    rebase from the reflog messages, the differences are not designed for\n     +    that purpose. c2417d3af7 (rebase: drop '-i' from the reflog for\n     +    interactive-based rebases, 2020-02-15) removed the clear distinction\n     +    between the reflog messages of the two backends without complaint.\n     +\n     +    As the merge backend is the default it is likely to be the format most\n     +    common in existing reflogs. For that reason the apply backend is changed\n     +    to format its reflog messages to match the merge backend as closely as\n     +    possible. Note that there is still a difference as when committing a\n     +    conflict resolution the apply backend will use \"(pick)\" rather than\n     +    \"(continue)\" because it is not currently possible to change the message\n     +    for a single commit.\n     +\n     +    In addition to c2417d3af7 we also changed the reflog messages in\n     +    68aa495b59 (rebase: implement --merge via the interactive machinery,\n     +    2018-12-11) and 2ac0d6273f (rebase: change the default backend from \"am\"\n     +    to \"merge\", 2020-02-15). This commit makes the same change to \"git\n     +    rebase --apply\" that 2ac0d6273f made to \"git rebase\" without any backend\n     +    specific options. As the messages are changed to use an existing format\n     +    any scripts that can parse the reflog messages of the default rebase\n     +    backend should be unaffected by this change.\n     +\n     +    There are existing tests for the messages from both backends which are\n     +    adjusted to ensure that they do not get out of sync in the future.\n      \n          Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n      \n     @@ builtin/rebase.c: static int run_am(struct rebase_options *opts)\n       \tam.git_cmd = 1;\n       \tstrvec_push(&am.args, \"am\");\n      -\n     -+\tstrvec_pushf(&am.env_array, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n     ++\tstrvec_pushf(&am.env, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n      +\t\t     getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n       \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n       \t\tstrvec_push(&am.args, \"--resolved\");\n     @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix\n      +\tstrbuf_addf(&msg, \"%s (start): checkout %s\",\n       \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);\n       \tropts.oid = &options.onto->object.oid;\n     - \tropts.orig_head = &options.orig_head,\n     + \tropts.orig_head = &options.orig_head->object.oid,\n      \n       ## t/t3406-rebase-message.sh ##\n      @@ t/t3406-rebase-message.sh: test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n 7:  d2c1dfbcd5e ! 7:  aa808725fb8 rebase --abort: improve reflog message\n     @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix\n      +\t\tstrbuf_addf(&head_msg, \"%s (abort): returning to %s\",\n      +\t\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n      +\t\t\t    options.head_name ? options.head_name\n     -+\t\t\t\t\t      : oid_to_hex(&options.orig_head));\n     - \t\tropts.oid = &options.orig_head;\n     ++\t\t\t\t\t      : oid_to_hex(&options.orig_head->object.oid));\n     + \t\tropts.oid = &options.orig_head->object.oid;\n      +\t\tropts.head_msg = head_msg.buf;\n       \t\tropts.branch = options.head_name;\n       \t\tropts.flags = RESET_HEAD_HARD;\n      -\t\tropts.default_reflog_action = DEFAULT_REFLOG_ACTION;\n       \t\tif (reset_head(the_repository, &ropts) < 0)\n       \t\t\tdie(_(\"could not move back to %s\"),\n     - \t\t\t    oid_to_hex(&options.orig_head));\n     + \t\t\t    oid_to_hex(&options.orig_head->object.oid));\n      \n       ## t/t3406-rebase-message.sh ##\n      @@ t/t3406-rebase-message.sh: test_reflog () {\n 8:  b0d21affa78 ! 8:  f9c8664b883 rebase: cleanup action handling\n     @@ builtin/rebase.c: static int run_sequencer_rebase(struct rebase_options *opts,\n       \treturn ret;\n      @@ builtin/rebase.c: static int run_am(struct rebase_options *opts)\n       \tstrvec_push(&am.args, \"am\");\n     - \tstrvec_pushf(&am.env_array, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n     + \tstrvec_pushf(&am.env, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n       \t\t     getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n      -\tif (opts->action && !strcmp(\"continue\", opts->action)) {\n      +\tif (opts->action == ACTION_CONTINUE) {\n     @@ builtin/rebase.c: static int run_specific_rebase(struct rebase_options *opts, en\n       \telse\n      @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n       \tstruct strbuf buf = STRBUF_INIT;\n     - \tstruct object_id merge_base;\n     + \tstruct object_id branch_base;\n       \tint ignore_whitespace = 0;\n      -\tenum action action = ACTION_NONE;\n       \tconst char *gpg_sign = NULL;\n     @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix\n       \t\t\t    ACTION_SHOW_CURRENT_PATCH),\n       \t\tOPT_CALLBACK_F(0, \"apply\", &options, NULL,\n      @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n     - \tif (preserve_merges_selected)\n     - \t\tdie(_(\"--preserve-merges was replaced by --rebase-merges\"));\n     + \t} else if (is_directory(merge_dir())) {\n     + \t\tstrbuf_reset(&buf);\n     + \t\tstrbuf_addf(&buf, \"%s/rewritten\", merge_dir());\n     +-\t\tif (!(action == ACTION_ABORT) && is_directory(buf.buf)) {\n     ++\t\tif (!(options.action == ACTION_ABORT) && is_directory(buf.buf)) {\n     + \t\t\tdie(_(\"`rebase --preserve-merges` (-p) is no longer supported.\\n\"\n     + \t\t\t\"Use `git rebase --abort` to terminate current rebase.\\n\"\n     + \t\t\t\"Or downgrade to v2.33, or earlier, to complete the rebase.\"));\n     +@@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n     + \t\t\t\"Note: Your `pull.rebase` configuration may also be set to 'preserve',\\n\"\n     + \t\t\t\"which is no longer supported; use 'merges' instead\"));\n       \n      -\tif (action != ACTION_NONE && total_argc != 2) {\n      +\tif (options.action != ACTION_NONE && total_argc != 2) {\n     @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix\n       \t}\n      @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n       \tif (options.root && options.fork_point > 0)\n     - \t\tdie(_(\"cannot combine '--root' with '--fork-point'\"));\n     + \t\tdie(_(\"options '%s' and '%s' cannot be used together\"), \"--root\", \"--fork-point\");\n       \n      -\tif (action != ACTION_NONE && !in_progress)\n      +\tif (options.action != ACTION_NONE && !in_progress)\n\n-- \ngitgitgadget\n"},{"id":"464686","messageId":"b9255ad35d2590df81c4b7629a00002c82fc9bf4.1665567312.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v3.git.1665567312.gitgitgadget@gmail.com","subject":"[PATCH v3 2/8] t3406: rework rebase reflog tests","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-12T09:35:06Z","receivedAt":"2022-10-12T09:35:25Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nRefactor the tests in preparation for adding more tests in the next\nfew commits. The reworked tests use the same function for testing both\nthe \"merge\" and \"apply\" backends. The test coverage for the \"apply\"\nbackend now includes setting GIT_REFLOG_ACTION.\n\nNote that rebasing the \"conflicts\" branch does not create any\nconflicts yet. A commit to do that will be added in the next commit\nand the diff ends up smaller if we have don't rename the branch when\nit is added.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n t/t3406-rebase-message.sh | 115 +++++++++++++++++++++++++-------------\n 1 file changed, 76 insertions(+), 39 deletions(-)\n\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex d17b450e811..5253dd1551d 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -10,10 +10,15 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n test_expect_success 'setup' '\n \ttest_commit O fileO &&\n \ttest_commit X fileX &&\n+\tgit branch fast-forward &&\n \ttest_commit A fileA &&\n \ttest_commit B fileB &&\n \ttest_commit Y fileY &&\n \n+\tgit checkout -b conflicts O &&\n+\ttest_commit P &&\n+\ttest_commit Q &&\n+\n \tgit checkout -b topic O &&\n \tgit cherry-pick A B &&\n \ttest_commit Z fileZ &&\n@@ -79,54 +84,86 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n \ttest_i18ngrep \"Invalid whitespace option\" err\n '\n \n-test_expect_success 'GIT_REFLOG_ACTION' '\n-\tgit checkout start &&\n-\ttest_commit reflog-onto &&\n-\tgit checkout -b reflog-topic start &&\n-\ttest_commit reflog-to-rebase &&\n-\n-\tgit rebase reflog-onto &&\n-\tgit log -g --format=%gs -3 >actual &&\n-\tcat >expect <<-\\EOF &&\n-\trebase (finish): returning to refs/heads/reflog-topic\n-\trebase (pick): reflog-to-rebase\n-\trebase (start): checkout reflog-onto\n+write_reflog_expect () {\n+\tif test $mode = --apply\n+\tthen\n+\t\tsed 's/.*(finish)/rebase finished/; s/ ([^)]*)//'\n+\telse\n+\t\tcat\n+\tfi >expect\n+}\n+\n+test_reflog () {\n+\tmode=$1\n+\treflog_action=\"$2\"\n+\n+\ttest_expect_success \"rebase $mode reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout conflicts &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\tgit rebase $mode main\n+\t) &&\n+\n+\tgit log -g --format=%gs -4 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n+\t${reflog_action:-rebase} (pick): Q\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n \tEOF\n \ttest_cmp expect actual &&\n \n-\tgit checkout -b reflog-prefix reflog-to-rebase &&\n-\tGIT_REFLOG_ACTION=change-the-reflog git rebase reflog-onto &&\n-\tgit log -g --format=%gs -3 >actual &&\n-\tcat >expect <<-\\EOF &&\n-\tchange-the-reflog (finish): returning to refs/heads/reflog-prefix\n-\tchange-the-reflog (pick): reflog-to-rebase\n-\tchange-the-reflog (start): checkout reflog-onto\n+\tgit log -g --format=%gs -1 conflicts >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): refs/heads/conflicts onto $(git rev-parse main)\n \tEOF\n-\ttest_cmp expect actual\n-'\n-\n-test_expect_success 'rebase --apply reflog' '\n-\tgit checkout -b reflog-apply start &&\n-\told_head_reflog=\"$(git log -g --format=%gs -1 HEAD)\" &&\n-\n-\tgit rebase --apply Y &&\n+\ttest_cmp expect actual &&\n \n-\tgit log -g --format=%gs -4 HEAD >actual &&\n-\tcat >expect <<-EOF &&\n-\trebase finished: returning to refs/heads/reflog-apply\n-\trebase: Z\n-\trebase: checkout Y\n-\t$old_head_reflog\n+\t# check there is only one new entry in the branch reflog\n+\ttest_cmp_rev conflicts@{1} Q\n+\t'\n+\n+\ttest_expect_success \"rebase $mode fast-forward reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout fast-forward &&\n+\ttest_when_finished \"git reset --hard X\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\tgit rebase $mode main\n+\t) &&\n+\n+\tgit log -g --format=%gs -2 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): returning to refs/heads/fast-forward\n+\t${reflog_action:-rebase} (start): checkout main\n \tEOF\n \ttest_cmp expect actual &&\n \n-\tgit log -g --format=%gs -2 reflog-apply >actual &&\n-\tcat >expect <<-EOF &&\n-\trebase finished: refs/heads/reflog-apply onto $(git rev-parse Y)\n-\tbranch: Created from start\n+\tgit log -g --format=%gs -1 fast-forward >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): refs/heads/fast-forward onto $(git rev-parse main)\n \tEOF\n-\ttest_cmp expect actual\n-'\n+\ttest_cmp expect actual &&\n+\n+\t# check there is only one new entry in the branch reflog\n+\ttest_cmp_rev fast-forward@{1} X\n+\t'\n+}\n+\n+test_reflog --merge\n+test_reflog --merge my-reflog-action\n+test_reflog --apply\n+test_reflog --apply my-reflog-action\n \n test_expect_success 'rebase -i onto unrelated history' '\n \tgit init unrelated &&\n-- \ngitgitgadget\n\n"},{"id":"464687","messageId":"ea4da25a19cca80f04fb6b88d46937056406c5b7.1665567312.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v3.git.1665567312.gitgitgadget@gmail.com","subject":"[PATCH v3 3/8] rebase --merge: fix reflog when continuing","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-12T09:35:07Z","receivedAt":"2022-10-12T09:35:27Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe reflog message for a conflict resolution committed by \"rebase\n--continue\" looks like\n\n\trebase (continue): commit subject line\n\nUnfortunately the reflog message each subsequent pick look like\n\n\trebase (continue) (pick): commit subject line\n\nFix this by setting the reflog message for \"rebase --continue\" in\nsequencer_continue() so it does not affect subsequent commits. This\nintroduces a memory leak similar to the one leaking GIT_REFLOG_ACTION\nin pick_commits(). Both of these will be fixed in a future series that\nstops the sequencer calling setenv().\n\nIf we fail to commit the staged changes then we error out so\nGIT_REFLOG_ACTION does not need to be reset in that case.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 2 --\n sequencer.c               | 5 +++++\n t/t3406-rebase-message.sh | 9 +++++++--\n 3 files changed, 12 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 51accb4fd61..488e6bdfd3e 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1271,8 +1271,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tint fd;\n \n \t\toptions.action = \"continue\";\n-\t\tset_reflog_action(&options);\n-\n \t\t/* Sanity check */\n \t\tif (get_oid(\"HEAD\", &head))\n \t\t\tdie(_(\"Cannot read HEAD\"));\ndiff --git a/sequencer.c b/sequencer.c\nindex 61a8e0020d5..5790b35d763 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -4785,6 +4785,8 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \tif (read_populate_opts(opts))\n \t\treturn -1;\n \tif (is_rebase_i(opts)) {\n+\t\tchar *previous_reflog_action;\n+\n \t\tif ((res = read_populate_todo(r, &todo_list, opts)))\n \t\t\tgoto release_todo_list;\n \n@@ -4795,10 +4797,13 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \t\t\tunlink(rebase_path_dropped());\n \t\t}\n \n+\t\tprevious_reflog_action = xstrdup(getenv(GIT_REFLOG_ACTION));\n+\t\tsetenv(GIT_REFLOG_ACTION, reflog_message(opts, \"continue\", NULL), 1);\n \t\tif (commit_staged_changes(r, opts, &todo_list)) {\n \t\t\tres = -1;\n \t\t\tgoto release_todo_list;\n \t\t}\n+\t\tsetenv(GIT_REFLOG_ACTION, previous_reflog_action, 1);\n \t} else if (!file_exists(get_todo_path(opts)))\n \t\treturn continue_single_pick(r, opts);\n \telse if ((res = read_populate_todo(r, &todo_list, opts)))\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 5253dd1551d..3ca2fbb0d59 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -17,6 +17,7 @@ test_expect_success 'setup' '\n \n \tgit checkout -b conflicts O &&\n \ttest_commit P &&\n+\ttest_commit conflict-X fileX &&\n \ttest_commit Q &&\n \n \tgit checkout -b topic O &&\n@@ -107,13 +108,17 @@ test_reflog () {\n \t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n \t\t\texport GIT_REFLOG_ACTION\n \t\tfi &&\n-\t\tgit rebase $mode main\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\techo resolved >fileX &&\n+\t\tgit add fileX &&\n+\t\tgit rebase --continue\n \t) &&\n \n-\tgit log -g --format=%gs -4 >actual &&\n+\tgit log -g --format=%gs -5 >actual &&\n \twrite_reflog_expect <<-EOF &&\n \t${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n \t${reflog_action:-rebase} (pick): Q\n+\t${reflog_action:-rebase} (continue): conflict-X\n \t${reflog_action:-rebase} (pick): P\n \t${reflog_action:-rebase} (start): checkout main\n \tEOF\n-- \ngitgitgadget\n\n"},{"id":"464688","messageId":"225ff4baef75e5a8429608d174cde8ff6edb0ccc.1665567312.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v3.git.1665567312.gitgitgadget@gmail.com","subject":"[PATCH v3 4/8] rebase --merge: fix reflog message after skipping","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-12T09:35:08Z","receivedAt":"2022-10-12T09:35:29Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe reflog message for every pick after running \"rebase --skip\" looks\nlike\n\n\trebase (skip) (pick): commit subject line\n\nFix this by not appending \" (skip)\" to the reflog action.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          |  2 --\n t/t3406-rebase-message.sh | 24 ++++++++++++++++++++++++\n 2 files changed, 24 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 488e6bdfd3e..9a40a5e27f8 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1297,8 +1297,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n \n \t\toptions.action = \"skip\";\n-\t\tset_reflog_action(&options);\n-\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \t\tropts.flags = RESET_HEAD_HARD;\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 3ca2fbb0d59..8aa6a79acc1 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -163,6 +163,30 @@ test_reflog () {\n \t# check there is only one new entry in the branch reflog\n \ttest_cmp_rev fast-forward@{1} X\n \t'\n+\n+\ttest_expect_success \"rebase $mode --skip reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout conflicts &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\tgit rebase --skip\n+\t) &&\n+\n+\tgit log -g --format=%gs -4 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n+\t${reflog_action:-rebase} (pick): Q\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n+\tEOF\n+\ttest_cmp expect actual\n+\t'\n }\n \n test_reflog --merge\n-- \ngitgitgadget\n\n"},{"id":"464689","messageId":"1094681eb115edd5a40b85790179b6d44a0fc521.1665567312.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v3.git.1665567312.gitgitgadget@gmail.com","subject":"[PATCH v3 5/8] rebase --apply: respect GIT_REFLOG_ACTION","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-12T09:35:09Z","receivedAt":"2022-10-12T09:35:31Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe reflog messages when finishing a rebase hard code \"rebase\" rather\nthan using GIT_REFLOG_ACTION.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 7 ++++---\n t/t3406-rebase-message.sh | 2 +-\n 2 files changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 9a40a5e27f8..f7b00efeb92 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -582,10 +582,11 @@ static int move_to_original_branch(struct rebase_options *opts)\n \tif (!opts->onto)\n \t\tBUG(\"move_to_original_branch without onto\");\n \n-\tstrbuf_addf(&branch_reflog, \"rebase finished: %s onto %s\",\n+\tstrbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n+\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n \t\t    opts->head_name, oid_to_hex(&opts->onto->object.oid));\n-\tstrbuf_addf(&head_reflog, \"rebase finished: returning to %s\",\n-\t\t    opts->head_name);\n+\tstrbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n+\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n \tropts.branch = opts->head_name;\n \tropts.flags = RESET_HEAD_REFS_ONLY;\n \tropts.branch_msg = branch_reflog.buf;\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 8aa6a79acc1..bb2a4949abc 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -88,7 +88,7 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n write_reflog_expect () {\n \tif test $mode = --apply\n \tthen\n-\t\tsed 's/.*(finish)/rebase finished/; s/ ([^)]*)//'\n+\t\tsed 's/(finish)/finished/; s/ ([^)]*)//'\n \telse\n \t\tcat\n \tfi >expect\n-- \ngitgitgadget\n\n"},{"id":"464690","messageId":"a5338e6bdd8cc783f01653cf4b668273bc2abec2.1665567312.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v3.git.1665567312.gitgitgadget@gmail.com","subject":"[PATCH v3 6/8] rebase --apply: make reflog messages match rebase --merge","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-12T09:35:10Z","receivedAt":"2022-10-12T09:35:34Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe apply backend creates slightly different reflog messages to the\nmerge backend when starting or finishing a rebase and when picking\ncommits. These differences make it harder than it needs to be to parse\nthe reflog (I have a script that reads the finishing messages from\nrebase and it is a pain to have to accommodate two different message\nformats). While it is possible to determine the backend used for a\nrebase from the reflog messages, the differences are not designed for\nthat purpose. c2417d3af7 (rebase: drop '-i' from the reflog for\ninteractive-based rebases, 2020-02-15) removed the clear distinction\nbetween the reflog messages of the two backends without complaint.\n\nAs the merge backend is the default it is likely to be the format most\ncommon in existing reflogs. For that reason the apply backend is changed\nto format its reflog messages to match the merge backend as closely as\npossible. Note that there is still a difference as when committing a\nconflict resolution the apply backend will use \"(pick)\" rather than\n\"(continue)\" because it is not currently possible to change the message\nfor a single commit.\n\nIn addition to c2417d3af7 we also changed the reflog messages in\n68aa495b59 (rebase: implement --merge via the interactive machinery,\n2018-12-11) and 2ac0d6273f (rebase: change the default backend from \"am\"\nto \"merge\", 2020-02-15). This commit makes the same change to \"git\nrebase --apply\" that 2ac0d6273f made to \"git rebase\" without any backend\nspecific options. As the messages are changed to use an existing format\nany scripts that can parse the reflog messages of the default rebase\nbackend should be unaffected by this change.\n\nThere are existing tests for the messages from both backends which are\nadjusted to ensure that they do not get out of sync in the future.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 9 +++++----\n t/t3406-rebase-message.sh | 2 +-\n 2 files changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex f7b00efeb92..ed612c2d0c3 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -582,10 +582,10 @@ static int move_to_original_branch(struct rebase_options *opts)\n \tif (!opts->onto)\n \t\tBUG(\"move_to_original_branch without onto\");\n \n-\tstrbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n+\tstrbuf_addf(&branch_reflog, \"%s (finish): %s onto %s\",\n \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n \t\t    opts->head_name, oid_to_hex(&opts->onto->object.oid));\n-\tstrbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n+\tstrbuf_addf(&head_reflog, \"%s (finish): returning to %s\",\n \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n \tropts.branch = opts->head_name;\n \tropts.flags = RESET_HEAD_REFS_ONLY;\n@@ -615,7 +615,8 @@ static int run_am(struct rebase_options *opts)\n \n \tam.git_cmd = 1;\n \tstrvec_push(&am.args, \"am\");\n-\n+\tstrvec_pushf(&am.env, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n+\t\t     getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n \t\tstrvec_push(&am.args, \"--resolved\");\n \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n@@ -1789,7 +1790,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tprintf(_(\"First, rewinding head to replay your work on top of \"\n \t\t\t \"it...\\n\"));\n \n-\tstrbuf_addf(&msg, \"%s: checkout %s\",\n+\tstrbuf_addf(&msg, \"%s (start): checkout %s\",\n \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);\n \tropts.oid = &options.onto->object.oid;\n \tropts.orig_head = &options.orig_head->object.oid,\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex bb2a4949abc..5c6cd9af3bc 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -88,7 +88,7 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n write_reflog_expect () {\n \tif test $mode = --apply\n \tthen\n-\t\tsed 's/(finish)/finished/; s/ ([^)]*)//'\n+\t\tsed 's/(continue)/(pick)/'\n \telse\n \t\tcat\n \tfi >expect\n-- \ngitgitgadget\n\n"},{"id":"464691","messageId":"aa808725fb88f21122d9b0466d9185740e540126.1665567312.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v3.git.1665567312.gitgitgadget@gmail.com","subject":"[PATCH v3 7/8] rebase --abort: improve reflog message","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-12T09:35:11Z","receivedAt":"2022-10-12T09:36:04Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nWhen aborting a rebase the reflog message looks like\n\n\trebase (abort): updating HEAD\n\nwhich is not very informative. Improve the message by mentioning the\nbranch that we are returning to as we do at the end of a successful\nrebase so it looks like.\n\n\trebase (abort): returning to refs/heads/topic\n\nIf GIT_REFLOG_ACTION is set in the environment we no longer omit\n\"(abort)\" from the reflog message. We don't omit \"(start)\" and\n\"(finish)\" when starting and finishing a rebase in that case so we\nshouldn't omit \"(abort)\".\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 28 ++++++---------------\n t/t3406-rebase-message.sh | 51 +++++++++++++++++++++++++++++++++++++++\n 2 files changed, 59 insertions(+), 20 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex ed612c2d0c3..e4620935129 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1001,23 +1001,6 @@ static void NORETURN error_on_missing_default_upstream(void)\n \texit(1);\n }\n \n-static void set_reflog_action(struct rebase_options *options)\n-{\n-\tconst char *env;\n-\tstruct strbuf buf = STRBUF_INIT;\n-\n-\tif (!is_merge(options))\n-\t\treturn;\n-\n-\tenv = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);\n-\tif (env && strcmp(\"rebase\", env))\n-\t\treturn; /* only override it if it is \"rebase\" */\n-\n-\tstrbuf_addf(&buf, \"rebase (%s)\", options->action);\n-\tsetenv(GIT_REFLOG_ACTION_ENVIRONMENT, buf.buf, 1);\n-\tstrbuf_release(&buf);\n-}\n-\n static int check_exec_cmd(const char *cmd)\n {\n \tif (strchr(cmd, '\\n'))\n@@ -1311,18 +1294,23 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t}\n \tcase ACTION_ABORT: {\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n-\t\toptions.action = \"abort\";\n-\t\tset_reflog_action(&options);\n+\t\tstruct strbuf head_msg = STRBUF_INIT;\n \n+\t\toptions.action = \"abort\";\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \n \t\tif (read_basic_state(&options))\n \t\t\texit(1);\n+\n+\t\tstrbuf_addf(&head_msg, \"%s (abort): returning to %s\",\n+\t\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n+\t\t\t    options.head_name ? options.head_name\n+\t\t\t\t\t      : oid_to_hex(&options.orig_head->object.oid));\n \t\tropts.oid = &options.orig_head->object.oid;\n+\t\tropts.head_msg = head_msg.buf;\n \t\tropts.branch = options.head_name;\n \t\tropts.flags = RESET_HEAD_HARD;\n-\t\tropts.default_reflog_action = DEFAULT_REFLOG_ACTION;\n \t\tif (reset_head(the_repository, &ropts) < 0)\n \t\t\tdie(_(\"could not move back to %s\"),\n \t\t\t    oid_to_hex(&options.orig_head->object.oid));\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 5c6cd9af3bc..ceca1600053 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -187,6 +187,57 @@ test_reflog () {\n \tEOF\n \ttest_cmp expect actual\n \t'\n+\n+\ttest_expect_success \"rebase $mode --abort reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout conflicts &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\tgit log -g -1 conflicts >branch-expect &&\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\tgit rebase --abort\n+\t) &&\n+\n+\tgit log -g --format=%gs -3 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (abort): returning to refs/heads/conflicts\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n+\tEOF\n+\ttest_cmp expect actual &&\n+\n+\t# check branch reflog is unchanged\n+\tgit log -g -1 conflicts >branch-actual &&\n+\ttest_cmp branch-expect branch-actual\n+\t'\n+\n+\ttest_expect_success \"rebase $mode --abort detached HEAD reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout Q &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\tgit rebase --abort\n+\t) &&\n+\n+\tgit log -g --format=%gs -3 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (abort): returning to $(git rev-parse Q)\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n+\tEOF\n+\ttest_cmp expect actual\n+\t'\n }\n \n test_reflog --merge\n-- \ngitgitgadget\n\n"},{"id":"464692","messageId":"f9c8664b883d385f022b3c529bd2c336832488b6.1665567312.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v3.git.1665567312.gitgitgadget@gmail.com","subject":"[PATCH v3 8/8] rebase: cleanup action handling","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-12T09:35:12Z","receivedAt":"2022-10-12T09:36:08Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nTreating the action as a string is a hang over from the scripted\nrebase. The last commit removed the only remaining use of the action\nthat required a string so lets convert the other action users to use\nthe existing action enum instead. If we ever need the action name as a\nstring in the future the action_names array exists exactly for that\npurpose.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c | 93 +++++++++++++++++++++++-------------------------\n 1 file changed, 44 insertions(+), 49 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex e4620935129..eb1fb8e3551 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -59,6 +59,26 @@ enum empty_type {\n \tEMPTY_ASK\n };\n \n+enum action {\n+\tACTION_NONE = 0,\n+\tACTION_CONTINUE,\n+\tACTION_SKIP,\n+\tACTION_ABORT,\n+\tACTION_QUIT,\n+\tACTION_EDIT_TODO,\n+\tACTION_SHOW_CURRENT_PATCH\n+};\n+\n+static const char *action_names[] = {\n+\t\"undefined\",\n+\t\"continue\",\n+\t\"skip\",\n+\t\"abort\",\n+\t\"quit\",\n+\t\"edit_todo\",\n+\t\"show_current_patch\"\n+};\n+\n struct rebase_options {\n \tenum rebase_type type;\n \tenum empty_type empty;\n@@ -85,7 +105,7 @@ struct rebase_options {\n \t\tREBASE_INTERACTIVE_EXPLICIT = 1<<4,\n \t} flags;\n \tstruct strvec git_am_opts;\n-\tconst char *action;\n+\tenum action action;\n \tint signoff;\n \tint allow_rerere_autoupdate;\n \tint keep_empty;\n@@ -156,24 +176,6 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)\n \treturn replay;\n }\n \n-enum action {\n-\tACTION_NONE = 0,\n-\tACTION_CONTINUE,\n-\tACTION_SKIP,\n-\tACTION_ABORT,\n-\tACTION_QUIT,\n-\tACTION_EDIT_TODO,\n-\tACTION_SHOW_CURRENT_PATCH\n-};\n-\n-static const char *action_names[] = { \"undefined\",\n-\t\t\t\t      \"continue\",\n-\t\t\t\t      \"skip\",\n-\t\t\t\t      \"abort\",\n-\t\t\t\t      \"quit\",\n-\t\t\t\t      \"edit_todo\",\n-\t\t\t\t      \"show_current_patch\" };\n-\n static int edit_todo_file(unsigned flags)\n {\n \tconst char *todo_file = rebase_path_todo();\n@@ -310,8 +312,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)\n \treturn ret;\n }\n \n-static int run_sequencer_rebase(struct rebase_options *opts,\n-\t\t\t\t  enum action command)\n+static int run_sequencer_rebase(struct rebase_options *opts)\n {\n \tunsigned flags = 0;\n \tint abbreviate_commands = 0, ret = 0;\n@@ -326,7 +327,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n \tflags |= opts->reapply_cherry_picks ? TODO_LIST_REAPPLY_CHERRY_PICKS : 0;\n \tflags |= opts->flags & REBASE_NO_QUIET ? TODO_LIST_WARN_SKIPPED_CHERRY_PICKS : 0;\n \n-\tswitch (command) {\n+\tswitch (opts->action) {\n \tcase ACTION_NONE: {\n \t\tif (!opts->onto && !opts->upstream)\n \t\t\tdie(_(\"a base commit must be provided with --upstream or --onto\"));\n@@ -359,7 +360,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n \t\tbreak;\n \t}\n \tdefault:\n-\t\tBUG(\"invalid command '%d'\", command);\n+\t\tBUG(\"invalid command '%d'\", opts->action);\n \t}\n \n \treturn ret;\n@@ -617,7 +618,7 @@ static int run_am(struct rebase_options *opts)\n \tstrvec_push(&am.args, \"am\");\n \tstrvec_pushf(&am.env, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n \t\t     getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n-\tif (opts->action && !strcmp(\"continue\", opts->action)) {\n+\tif (opts->action == ACTION_CONTINUE) {\n \t\tstrvec_push(&am.args, \"--resolved\");\n \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n \t\tif (opts->gpg_sign_opt)\n@@ -628,7 +629,7 @@ static int run_am(struct rebase_options *opts)\n \n \t\treturn move_to_original_branch(opts);\n \t}\n-\tif (opts->action && !strcmp(\"skip\", opts->action)) {\n+\tif (opts->action == ACTION_SKIP) {\n \t\tstrvec_push(&am.args, \"--skip\");\n \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n \t\tstatus = run_command(&am);\n@@ -637,7 +638,7 @@ static int run_am(struct rebase_options *opts)\n \n \t\treturn move_to_original_branch(opts);\n \t}\n-\tif (opts->action && !strcmp(\"show-current-patch\", opts->action)) {\n+\tif (opts->action == ACTION_SHOW_CURRENT_PATCH) {\n \t\tstrvec_push(&am.args, \"--show-current-patch\");\n \t\treturn run_command(&am);\n \t}\n@@ -730,7 +731,7 @@ static int run_am(struct rebase_options *opts)\n \treturn status;\n }\n \n-static int run_specific_rebase(struct rebase_options *opts, enum action action)\n+static int run_specific_rebase(struct rebase_options *opts)\n {\n \tint status;\n \n@@ -748,7 +749,7 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n \t\t\topts->gpg_sign_opt = tmp;\n \t\t}\n \n-\t\tstatus = run_sequencer_rebase(opts, action);\n+\t\tstatus = run_sequencer_rebase(opts);\n \t} else if (opts->type == REBASE_APPLY)\n \t\tstatus = run_am(opts);\n \telse\n@@ -1025,7 +1026,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct object_id branch_base;\n \tint ignore_whitespace = 0;\n-\tenum action action = ACTION_NONE;\n \tconst char *gpg_sign = NULL;\n \tstruct string_list exec = STRING_LIST_INIT_NODUP;\n \tconst char *rebase_merges = NULL;\n@@ -1074,18 +1074,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tOPT_BIT(0, \"no-ff\", &options.flags,\n \t\t\tN_(\"cherry-pick all commits, even if unchanged\"),\n \t\t\tREBASE_FORCE),\n-\t\tOPT_CMDMODE(0, \"continue\", &action, N_(\"continue\"),\n+\t\tOPT_CMDMODE(0, \"continue\", &options.action, N_(\"continue\"),\n \t\t\t    ACTION_CONTINUE),\n-\t\tOPT_CMDMODE(0, \"skip\", &action,\n+\t\tOPT_CMDMODE(0, \"skip\", &options.action,\n \t\t\t    N_(\"skip current patch and continue\"), ACTION_SKIP),\n-\t\tOPT_CMDMODE(0, \"abort\", &action,\n+\t\tOPT_CMDMODE(0, \"abort\", &options.action,\n \t\t\t    N_(\"abort and check out the original branch\"),\n \t\t\t    ACTION_ABORT),\n-\t\tOPT_CMDMODE(0, \"quit\", &action,\n+\t\tOPT_CMDMODE(0, \"quit\", &options.action,\n \t\t\t    N_(\"abort but keep HEAD where it is\"), ACTION_QUIT),\n-\t\tOPT_CMDMODE(0, \"edit-todo\", &action, N_(\"edit the todo list \"\n+\t\tOPT_CMDMODE(0, \"edit-todo\", &options.action, N_(\"edit the todo list \"\n \t\t\t    \"during an interactive rebase\"), ACTION_EDIT_TODO),\n-\t\tOPT_CMDMODE(0, \"show-current-patch\", &action,\n+\t\tOPT_CMDMODE(0, \"show-current-patch\", &options.action,\n \t\t\t    N_(\"show the patch file being applied or merged\"),\n \t\t\t    ACTION_SHOW_CURRENT_PATCH),\n \t\tOPT_CALLBACK_F(0, \"apply\", &options, NULL,\n@@ -1174,7 +1174,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t} else if (is_directory(merge_dir())) {\n \t\tstrbuf_reset(&buf);\n \t\tstrbuf_addf(&buf, \"%s/rewritten\", merge_dir());\n-\t\tif (!(action == ACTION_ABORT) && is_directory(buf.buf)) {\n+\t\tif (!(options.action == ACTION_ABORT) && is_directory(buf.buf)) {\n \t\t\tdie(_(\"`rebase --preserve-merges` (-p) is no longer supported.\\n\"\n \t\t\t\"Use `git rebase --abort` to terminate current rebase.\\n\"\n \t\t\t\"Or downgrade to v2.33, or earlier, to complete the rebase.\"));\n@@ -1201,7 +1201,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\t\"Note: Your `pull.rebase` configuration may also be set to 'preserve',\\n\"\n \t\t\t\"which is no longer supported; use 'merges' instead\"));\n \n-\tif (action != ACTION_NONE && total_argc != 2) {\n+\tif (options.action != ACTION_NONE && total_argc != 2) {\n \t\tusage_with_options(builtin_rebase_usage,\n \t\t\t\t   builtin_rebase_options);\n \t}\n@@ -1232,11 +1232,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tif (options.root && options.fork_point > 0)\n \t\tdie(_(\"options '%s' and '%s' cannot be used together\"), \"--root\", \"--fork-point\");\n \n-\tif (action != ACTION_NONE && !in_progress)\n+\tif (options.action != ACTION_NONE && !in_progress)\n \t\tdie(_(\"No rebase in progress?\"));\n \tsetenv(GIT_REFLOG_ACTION_ENVIRONMENT, \"rebase\", 0);\n \n-\tif (action == ACTION_EDIT_TODO && !is_merge(&options))\n+\tif (options.action == ACTION_EDIT_TODO && !is_merge(&options))\n \t\tdie(_(\"The --edit-todo action can only be used during \"\n \t\t      \"interactive rebase.\"));\n \n@@ -1246,16 +1246,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\telse if (exec.nr)\n \t\t\ttrace2_cmd_mode(\"interactive-exec\");\n \t\telse\n-\t\t\ttrace2_cmd_mode(action_names[action]);\n+\t\t\ttrace2_cmd_mode(action_names[options.action]);\n \t}\n \n-\tswitch (action) {\n+\tswitch (options.action) {\n \tcase ACTION_CONTINUE: {\n \t\tstruct object_id head;\n \t\tstruct lock_file lock_file = LOCK_INIT;\n \t\tint fd;\n \n-\t\toptions.action = \"continue\";\n \t\t/* Sanity check */\n \t\tif (get_oid(\"HEAD\", &head))\n \t\t\tdie(_(\"Cannot read HEAD\"));\n@@ -1281,7 +1280,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tcase ACTION_SKIP: {\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n \n-\t\toptions.action = \"skip\";\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \t\tropts.flags = RESET_HEAD_HARD;\n@@ -1296,7 +1294,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n \t\tstruct strbuf head_msg = STRBUF_INIT;\n \n-\t\toptions.action = \"abort\";\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \n@@ -1336,17 +1333,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tgoto cleanup;\n \t}\n \tcase ACTION_EDIT_TODO:\n-\t\toptions.action = \"edit-todo\";\n \t\toptions.dont_finish_rebase = 1;\n \t\tgoto run_rebase;\n \tcase ACTION_SHOW_CURRENT_PATCH:\n-\t\toptions.action = \"show-current-patch\";\n \t\toptions.dont_finish_rebase = 1;\n \t\tgoto run_rebase;\n \tcase ACTION_NONE:\n \t\tbreak;\n \tdefault:\n-\t\tBUG(\"action: %d\", action);\n+\t\tBUG(\"action: %d\", options.action);\n \t}\n \n \t/* Make sure no rebase is in progress */\n@@ -1370,7 +1365,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif ((options.flags & REBASE_INTERACTIVE_EXPLICIT) ||\n-\t    (action != ACTION_NONE) ||\n+\t    (options.action != ACTION_NONE) ||\n \t    (exec.nr > 0) ||\n \t    options.autosquash) {\n \t\tallow_preemptive_ff = 0;\n@@ -1812,7 +1807,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \toptions.revisions = revisions.buf;\n \n run_rebase:\n-\tret = run_specific_rebase(&options, action);\n+\tret = run_specific_rebase(&options);\n \n cleanup:\n \tstrbuf_release(&buf);\n-- \ngitgitgadget\n"},{"id":"464750","messageId":"xmqqedvclqxm.fsf@gitster.g","threadId":"57450","inReplyTo":"a84cf971a753e294555ca8f2b7eaa4c75a8fa491.1665567312.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 1/8] rebase --apply: remove duplicated code","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-10-12T20:36:53Z","receivedAt":"2022-10-12T20:37:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> Use move_to_original_branch() when reattaching HEAD after a fast-forward\n> rather than open coding a copy of that code. move_to_original_branch()\n> does not call reset_head() if head_name is NULL but there should be no\n> user visible changes even though we currently call reset_head() in that\n> case.\n\nmove_to_original_branch() uses both .head_msg and .branch_msg and\nuses different messages for them, but the original code below only\nfeeds .head_msg while .branch_msg leaves NULL, which leads\nreset.c::update_refs() to use the same message as .head_msg when it\nwants to use .branch_msg (i.e. the message recorded in the reflog of\nthe branch).  \n\nDoesn't this difference result in a different behaviour?\n\n> The reason for this is that the reset_head() call does not add a\n> message to the reflog because we're not changing the commit that HEAD\n> points to and so lock_ref_for_update() elides the update. When head_name\n> is not NULL then reset_head() behaves like \"git symbolic-ref\" and so the\n> reflog is updated.\n\n> Note that the removal of \"strbuf_release(&msg)\" is safe as there is an\n\nThe patch is removing strbuf_reset(), not _release(), here, though.\n\nWe have released already so there is no point to reset it again, so\nthe removal is still safe.\n\n> identical call just above this hunk which can be seen by viewing the\n> diff with -U6.\n>\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  builtin/rebase.c | 11 +----------\n>  1 file changed, 1 insertion(+), 10 deletions(-)\n>\n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index a2ca66b54be..51accb4fd61 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -1808,19 +1808,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>  \t * If the onto is a proper descendant of the tip of the branch, then\n>  \t * we just fast-forwarded.\n>  \t */\n> -\tstrbuf_reset(&msg);\n>  \tif (oideq(&branch_base, &options.orig_head->object.oid)) {\n>  \t\tprintf(_(\"Fast-forwarded %s to %s.\\n\"),\n>  \t\t\tbranch_name, options.onto_name);\n> -\t\tstrbuf_addf(&msg, \"rebase finished: %s onto %s\",\n> -\t\t\toptions.head_name ? options.head_name : \"detached HEAD\",\n> -\t\t\toid_to_hex(&options.onto->object.oid));\n> -\t\tmemset(&ropts, 0, sizeof(ropts));\n> -\t\tropts.branch = options.head_name;\n> -\t\tropts.flags = RESET_HEAD_REFS_ONLY;\n> -\t\tropts.head_msg = msg.buf;\n> -\t\treset_head(the_repository, &ropts);\n> -\t\tstrbuf_release(&msg);\n> +\t\tmove_to_original_branch(&options);\n>  \t\tret = finish_rebase(&options);\n>  \t\tgoto cleanup;\n>  \t}\n"},{"id":"464751","messageId":"xmqq7d14lqxc.fsf@gitster.g","threadId":"57450","inReplyTo":"pull.1150.v3.git.1665567312.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 0/8] rebase: make reflog messages independent of the backend","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-10-12T20:37:03Z","receivedAt":"2022-10-12T20:37:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> This series fixes some bugs in the reflog messages when rebasing and changes\n> the reflog messages of \"rebase --apply\" to match \"rebase --merge\" with the\n> aim of making the reflog easier to parse.\n>\n> Thanks to everyone who commented on V2, I've added the review club\n> participants that I've got address for to the cc list. I've rebased onto\n> pw/rebase-keep-base-fixes.\n\nThanks for identifying the base clearly.\n\nIf \"What's cooking\" is correct, the base topic is waiting for an\nupdate?  I'd prefer to see us build new stuff on top of solidified\nground.\n\n\n"},{"id":"464812","messageId":"64155477-827d-6a16-a5fa-7e2cfc78569e@dunelm.org.uk","threadId":"57450","inReplyTo":"xmqq7d14lqxc.fsf@gitster.g","subject":"Re: [PATCH v3 0/8] rebase: make reflog messages independent of the backend","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2022-10-13T08:44:52Z","receivedAt":"2022-10-13T08:45:04Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 12/10/2022 21:37, Junio C Hamano wrote:\n> \"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> \n>> This series fixes some bugs in the reflog messages when rebasing and changes\n>> the reflog messages of \"rebase --apply\" to match \"rebase --merge\" with the\n>> aim of making the reflog easier to parse.\n>>\n>> Thanks to everyone who commented on V2, I've added the review club\n>> participants that I've got address for to the cc list. I've rebased onto\n>> pw/rebase-keep-base-fixes.\n> \n> Thanks for identifying the base clearly.\n> \n> If \"What's cooking\" is correct, the base topic is waiting for an\n> update?  I'd prefer to see us build new stuff on top of solidified\n> ground.\n\nOh sorry, I thought I'd submitted a new version last week but it seems I \npushed it to gitgitgadet, updated the cover letter but forgot to say \n\"/submit\". I'm hoping that will be the final version and provide a \nstable base for this series.\n\nBest Wishes\n\nPhillip\n"},{"id":"464829","messageId":"xmqqh707ivu1.fsf@gitster.g","threadId":"57450","inReplyTo":"64155477-827d-6a16-a5fa-7e2cfc78569e@dunelm.org.uk","subject":"Re: [PATCH v3 0/8] rebase: make reflog messages independent of the backend","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-10-13T15:31:34Z","receivedAt":"2022-10-13T15:31:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> I pushed it to gitgitgadet, updated the cover letter but forgot to say\n> \"/submit\". I'm hoping that will be the final version and provide a\n> stable base for this series.\n\nThanks, will look forward to.\n"},{"id":"464877","messageId":"xmqq35brh9re.fsf@gitster.g","threadId":"57450","inReplyTo":"xmqqedvclqxm.fsf@gitster.g","subject":"Re: [PATCH v3 1/8] rebase --apply: remove duplicated code","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-10-13T18:13:41Z","receivedAt":"2022-10-13T18:36:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> \"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>\n>> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>>\n>> Use move_to_original_branch() when reattaching HEAD after a fast-forward\n>> rather than open coding a copy of that code. move_to_original_branch()\n>> does not call reset_head() if head_name is NULL but there should be no\n>> user visible changes even though we currently call reset_head() in that\n>> case.\n>\n> move_to_original_branch() uses both .head_msg and .branch_msg and\n> uses different messages for them, but the original code below only\n> feeds .head_msg while .branch_msg leaves NULL, which leads\n> reset.c::update_refs() to use the same message as .head_msg when it\n> wants to use .branch_msg (i.e. the message recorded in the reflog of\n> the branch).  \n>\n> Doesn't this difference result in a different behaviour?\n\nI think \"git rebase --apply A B\" when B is already an descendant of\nA with a single strand of pearls would trigger the new logic, and\ninstead of the old \"rebase finished: %s onto %s\" message used for\nboth reflogs, calling move_to_original_branch() will give us \"rebase\nfinished: %s onto %s\" in the branch reflog, while \"rebase finished:\nreturning to %s\" in the HEAD reflog.\n\nNote that I am not saying we should not change the behaviour.\nSaying \"returning to X\" in the reflog of HEAD may arguably be better\nthan using the same \"rebased X onto Y\" for reflogs for both HEAD and\nthe underlying branch.\n\nBut if that is what is going on, we should record it as improving\nthe reflog message, not removing duplicated code.\n\nAlso, it would be good to have a test that demonstrates how the\ncontents of the reflog changes with this change.  It took me some\ntime to figure out how to reach that codepath, even though it was\nrelatively easy to see how the reflog message(s) used before and\nafter the patch are different.\n\n>> The reason for this is that the reset_head() call does not add a\n>> message to the reflog because we're not changing the commit that HEAD\n>> points to and so lock_ref_for_update() elides the update. When head_name\n>> is not NULL then reset_head() behaves like \"git symbolic-ref\" and so the\n>> reflog is updated.\n>\n>> Note that the removal of \"strbuf_release(&msg)\" is safe as there is an\n>\n> The patch is removing strbuf_reset(), not _release(), here, though.\n>\n> We have released already so there is no point to reset it again, so\n> the removal is still safe.\n\nThanks.\n"},{"id":"465284","messageId":"f1d75703-dfea-69ee-59e8-18afaf75cbf8@dunelm.org.uk","threadId":"57450","inReplyTo":"xmqq35brh9re.fsf@gitster.g","subject":"Re: [PATCH v3 1/8] rebase --apply: remove duplicated code","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2022-10-20T09:50:41Z","receivedAt":"2022-10-20T09:51:20Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Junio\n\nOn 13/10/2022 19:13, Junio C Hamano wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n>> \"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>>\n>>> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>>>\n>>> Use move_to_original_branch() when reattaching HEAD after a fast-forward\n>>> rather than open coding a copy of that code. move_to_original_branch()\n>>> does not call reset_head() if head_name is NULL but there should be no\n>>> user visible changes even though we currently call reset_head() in that\n>>> case.\n>>\n>> move_to_original_branch() uses both .head_msg and .branch_msg and\n>> uses different messages for them, but the original code below only\n>> feeds .head_msg while .branch_msg leaves NULL, which leads\n>> reset.c::update_refs() to use the same message as .head_msg when it\n>> wants to use .branch_msg (i.e. the message recorded in the reflog of\n>> the branch).\n>>\n>> Doesn't this difference result in a different behaviour?\n\nYes, you're right\n\n> I think \"git rebase --apply A B\" when B is already an descendant of\n> A with a single strand of pearls would trigger the new logic, and\n> instead of the old \"rebase finished: %s onto %s\" message used for\n> both reflogs, calling move_to_original_branch() will give us \"rebase\n> finished: %s onto %s\" in the branch reflog, while \"rebase finished:\n> returning to %s\" in the HEAD reflog.\n> \n> Note that I am not saying we should not change the behaviour.\n> Saying \"returning to X\" in the reflog of HEAD may arguably be better\n> than using the same \"rebased X onto Y\" for reflogs for both HEAD and\n> the underlying branch.\n> \n> But if that is what is going on, we should record it as improving\n> the reflog message, not removing duplicated code.\n> \n> Also, it would be good to have a test that demonstrates how the\n> contents of the reflog changes with this change.  It took me some\n> time to figure out how to reach that codepath, even though it was\n> relatively easy to see how the reflog message(s) used before and\n> after the patch are different.\n\nI've just checked and the tests added in the next patch do test this \npath (they fail if I revert this commit). I should be able to swap the \ntwo patches round to demonstrate the change in behavior and rework the \ncommit commit message for this patch.\n\nBest Wishes\n\nPhillip\n\n>>> The reason for this is that the reset_head() call does not add a\n>>> message to the reflog because we're not changing the commit that HEAD\n>>> points to and so lock_ref_for_update() elides the update. When head_name\n>>> is not NULL then reset_head() behaves like \"git symbolic-ref\" and so the\n>>> reflog is updated.\n>>\n>>> Note that the removal of \"strbuf_release(&msg)\" is safe as there is an\n>>\n>> The patch is removing strbuf_reset(), not _release(), here, though.\n>>\n>> We have released already so there is no point to reset it again, so\n>> the removal is still safe.\n> \n> Thanks.\n"},{"id":"465432","messageId":"pull.1150.v4.git.1666344108.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v3.git.1665567312.gitgitgadget@gmail.com","subject":"[PATCH v4 0/8] rebase: make reflog messages independent of the backend","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-21T09:21:40Z","receivedAt":"2022-10-21T09:21:58Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"This series fixes some bugs in the reflog messages when rebasing and changes\nthe reflog messages of \"rebase --apply\" to match \"rebase --merge\" with the\naim of making the reflog easier to parse.\n\nThanks to Junio for his comments, here are the changes since V3:\n\n * Patch 1: Swapped with patch 2. Small change to fast-forward tests to make\n   them pass\n * Patch 2: Swapped with patch 1. Reworded commit message and added a change\n   to the fast-forward test to reflect the change in reflog message\n   introduced by this patch\n\nThe rest of the patches are unchanged.\n\nV2 Cover Letter\n\nThanks to everyone who commented on V2, I've added the review club\nparticipants that I've got address for to the cc list. I've rebased onto\npw/rebase-keep-base-fixes.\n\nChange since V2:\n\n * Patch 1: Reworded the commit message to address the concerns in [1,2]\n   about the behavior when head_name is NULL. There is also a small change\n   due to being rebased.\n\n * Patch 2: Unchanged. There wasn't much love for parameterized tests in\n   review club but we want to ensure both backends produce the same messages\n   I think this is the safest way to achieve that. Using separate tests\n   makes it too easy to introduce subtle differences in the testing of the\n   two backends.\n\n * Patch 3: Added a note to the commit message to address the concerns in\n   [1] about not resetting GIT_REFLOG_ACTION when we return early.\n\n * Patches 4 & 5: Unchanged.\n\n * Patch 6: Reworded the commit message to make a stronger argument for this\n   change. There are concerns about backwards compatibility in [1,3,4] but\n   (i) we have made similar changes in the past without complaints and (ii)\n   we're changing the message to an existing format. There is also a small\n   change due to being rebased.\n\n * Patches 7 & 8: Small changes due to rebase.\n\n[1]\nhttps://docs.google.com/document/d/14L8BAumGTpsXpjDY8VzZ4rRtpAjuGrFSRqn3stCuS_w/edit?pli=1#heading=h.t6g5l2t5ibzw\n[2] https://lore.kernel.org/git/xmqq35i7r4rj.fsf@gitster.g/ [3]\nhttps://lore.kernel.org/git/xmqq4k2nmmeg.fsf@gitster.g/ [4]\nhttps://lore.kernel.org/git/220420.865yn4833u.gmgdl@evledraar.gmail.com/\n\nV2 Cover Letter:\n\nThanks to Christian and Elijah for their comments on V1.\n\nI've updated commit message for patch 1 to try and be clearer about the\nremoval of a call to strbuf_release() and spilt out the test changes from\nthe old patch 2 into a separate preparatory patch.\n\nV1 Cover Letter:\n\nThis is a series of rebase reflog related patches with the aim of unifying\nthe reflog messages from the two rebase backends.\n\n * improve rebase reflog test coverage\n * rebase --merge: fix reflog messages for --continue and --skip\n * rebase --apply: respect GIT_REFLOG_ACTION\n * rebase --abort: improve reflog message\n * unify reflog messages between the two rebase backends\n\nThis series is based on pw/use-inprocess-checkout-in-rebase\n\nPhillip Wood (8):\n  t3406: rework rebase reflog tests\n  rebase --apply: improve fast-forward reflog message\n  rebase --merge: fix reflog when continuing\n  rebase --merge: fix reflog message after skipping\n  rebase --apply: respect GIT_REFLOG_ACTION\n  rebase --apply: make reflog messages match rebase --merge\n  rebase --abort: improve reflog message\n  rebase: cleanup action handling\n\n builtin/rebase.c          | 146 ++++++++++++------------------\n sequencer.c               |   5 ++\n t/t3406-rebase-message.sh | 185 +++++++++++++++++++++++++++++++-------\n 3 files changed, 215 insertions(+), 121 deletions(-)\n\n\nbase-commit: aa1df8146d70bb85c63b0999868fe29aebc1173e\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1150%2Fphillipwood%2Fwip%2Frebase-reflog-fixes-v4\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1150/phillipwood/wip/rebase-reflog-fixes-v4\nPull-Request: https://github.com/gitgitgadget/git/pull/1150\n\nRange-diff vs v3:\n\n 2:  b9255ad35d2 ! 1:  8d5ae067ce3 t3406: rework rebase reflog tests\n     @@ Commit message\n          the \"merge\" and \"apply\" backends. The test coverage for the \"apply\"\n          backend now includes setting GIT_REFLOG_ACTION.\n      \n     -    Note that rebasing the \"conflicts\" branch does not create any\n     -    conflicts yet. A commit to do that will be added in the next commit\n     -    and the diff ends up smaller if we have don't rename the branch when\n     -    it is added.\n     +    Note that rebasing the \"conflicts\" branch does not create any conflicts\n     +    yet. A commit to do that will be added shortly and the diff ends up\n     +    smaller if we have don't rename the branch when it is added.\n      \n          Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n      \n     @@ t/t3406-rebase-message.sh: test_expect_success 'error out early upon -C<n> or --\n      +\t) &&\n      +\n      +\tgit log -g --format=%gs -2 >actual &&\n     ++\tif test \"$mode\" = \"--apply\"\n     ++\tthen\n     ++\t\tfinish_msg=\"refs/heads/fast-forward onto $(git rev-parse main)\"\n     ++\telse\n     ++\t\tfinish_msg=\"returning to refs/heads/fast-forward\"\n     ++\tfi &&\n      +\twrite_reflog_expect <<-EOF &&\n     -+\t${reflog_action:-rebase} (finish): returning to refs/heads/fast-forward\n     ++\t${reflog_action:-rebase} (finish): $finish_msg\n      +\t${reflog_action:-rebase} (start): checkout main\n       \tEOF\n       \ttest_cmp expect actual &&\n 1:  a84cf971a75 ! 2:  12701ef7c7c rebase --apply: remove duplicated code\n     @@ Metadata\n      Author: Phillip Wood <phillip.wood@dunelm.org.uk>\n      \n       ## Commit message ##\n     -    rebase --apply: remove duplicated code\n     +    rebase --apply: improve fast-forward reflog message\n      \n     -    Use move_to_original_branch() when reattaching HEAD after a fast-forward\n     -    rather than open coding a copy of that code. move_to_original_branch()\n     -    does not call reset_head() if head_name is NULL but there should be no\n     -    user visible changes even though we currently call reset_head() in that\n     -    case. The reason for this is that the reset_head() call does not add a\n     -    message to the reflog because we're not changing the commit that HEAD\n     -    points to and so lock_ref_for_update() elides the update. When head_name\n     -    is not NULL then reset_head() behaves like \"git symbolic-ref\" and so the\n     -    reflog is updated.\n     +    Using move_to_original_branch() when reattaching HEAD after a\n     +    fast-forward improves HEAD's reflog message when rebasing a branch. This\n     +    is because it uses separate reflog messages for \"HEAD\" and\n     +    \"branch\". HEAD's reflog will now record which branch we're returning to.\n      \n     -    Note that the removal of \"strbuf_release(&msg)\" is safe as there is an\n     -    identical call just above this hunk which can be seen by viewing the\n     -    diff with -U6.\n     +    When rebasing a detached HEAD there is no change in behavior. We\n     +    currently call reset_head() when head_name is NULL but\n     +    move_to_original_branch() does not. However the existing call does not\n     +    add a message to the reflog because we're not changing the commit that\n     +    HEAD points to and so lock_ref_for_update() skips the update.\n      \n     +    Note that the removal of \"strbuf_reset(&msg)\" is safe as there is a call\n     +    to strbuf_release(&msf) just above this hunk which can be seen by\n     +    viewing the diff with -U6.\n     +\n     +    Helped-by: Junio C Hamano <gitster@pobox.com>\n          Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n      \n       ## builtin/rebase.c ##\n     @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix\n       \t\tret = finish_rebase(&options);\n       \t\tgoto cleanup;\n       \t}\n     +\n     + ## t/t3406-rebase-message.sh ##\n     +@@ t/t3406-rebase-message.sh: test_reflog () {\n     + \t) &&\n     + \n     + \tgit log -g --format=%gs -2 >actual &&\n     +-\tif test \"$mode\" = \"--apply\"\n     +-\tthen\n     +-\t\tfinish_msg=\"refs/heads/fast-forward onto $(git rev-parse main)\"\n     +-\telse\n     +-\t\tfinish_msg=\"returning to refs/heads/fast-forward\"\n     +-\tfi &&\n     + \twrite_reflog_expect <<-EOF &&\n     +-\t${reflog_action:-rebase} (finish): $finish_msg\n     ++\t${reflog_action:-rebase} (finish): returning to refs/heads/fast-forward\n     + \t${reflog_action:-rebase} (start): checkout main\n     + \tEOF\n     + \ttest_cmp expect actual &&\n 3:  ea4da25a19c = 3:  2c965f4b97c rebase --merge: fix reflog when continuing\n 4:  225ff4baef7 = 4:  17138d910f0 rebase --merge: fix reflog message after skipping\n 5:  1094681eb11 = 5:  0c71c732904 rebase --apply: respect GIT_REFLOG_ACTION\n 6:  a5338e6bdd8 = 6:  3f6b2e39f40 rebase --apply: make reflog messages match rebase --merge\n 7:  aa808725fb8 = 7:  c8fa57f129d rebase --abort: improve reflog message\n 8:  f9c8664b883 = 8:  ed800844ba1 rebase: cleanup action handling\n\n-- \ngitgitgadget\n"},{"id":"465433","messageId":"8d5ae067ce361f986634b0f218cf09bb0e2ae33f.1666344108.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v4.git.1666344108.gitgitgadget@gmail.com","subject":"[PATCH v4 1/8] t3406: rework rebase reflog tests","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-21T09:21:41Z","receivedAt":"2022-10-21T09:22:00Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nRefactor the tests in preparation for adding more tests in the next\nfew commits. The reworked tests use the same function for testing both\nthe \"merge\" and \"apply\" backends. The test coverage for the \"apply\"\nbackend now includes setting GIT_REFLOG_ACTION.\n\nNote that rebasing the \"conflicts\" branch does not create any conflicts\nyet. A commit to do that will be added shortly and the diff ends up\nsmaller if we have don't rename the branch when it is added.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n t/t3406-rebase-message.sh | 121 ++++++++++++++++++++++++++------------\n 1 file changed, 82 insertions(+), 39 deletions(-)\n\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex d17b450e811..413d6132ea2 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -10,10 +10,15 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n test_expect_success 'setup' '\n \ttest_commit O fileO &&\n \ttest_commit X fileX &&\n+\tgit branch fast-forward &&\n \ttest_commit A fileA &&\n \ttest_commit B fileB &&\n \ttest_commit Y fileY &&\n \n+\tgit checkout -b conflicts O &&\n+\ttest_commit P &&\n+\ttest_commit Q &&\n+\n \tgit checkout -b topic O &&\n \tgit cherry-pick A B &&\n \ttest_commit Z fileZ &&\n@@ -79,54 +84,92 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n \ttest_i18ngrep \"Invalid whitespace option\" err\n '\n \n-test_expect_success 'GIT_REFLOG_ACTION' '\n-\tgit checkout start &&\n-\ttest_commit reflog-onto &&\n-\tgit checkout -b reflog-topic start &&\n-\ttest_commit reflog-to-rebase &&\n-\n-\tgit rebase reflog-onto &&\n-\tgit log -g --format=%gs -3 >actual &&\n-\tcat >expect <<-\\EOF &&\n-\trebase (finish): returning to refs/heads/reflog-topic\n-\trebase (pick): reflog-to-rebase\n-\trebase (start): checkout reflog-onto\n+write_reflog_expect () {\n+\tif test $mode = --apply\n+\tthen\n+\t\tsed 's/.*(finish)/rebase finished/; s/ ([^)]*)//'\n+\telse\n+\t\tcat\n+\tfi >expect\n+}\n+\n+test_reflog () {\n+\tmode=$1\n+\treflog_action=\"$2\"\n+\n+\ttest_expect_success \"rebase $mode reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout conflicts &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\tgit rebase $mode main\n+\t) &&\n+\n+\tgit log -g --format=%gs -4 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n+\t${reflog_action:-rebase} (pick): Q\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n \tEOF\n \ttest_cmp expect actual &&\n \n-\tgit checkout -b reflog-prefix reflog-to-rebase &&\n-\tGIT_REFLOG_ACTION=change-the-reflog git rebase reflog-onto &&\n-\tgit log -g --format=%gs -3 >actual &&\n-\tcat >expect <<-\\EOF &&\n-\tchange-the-reflog (finish): returning to refs/heads/reflog-prefix\n-\tchange-the-reflog (pick): reflog-to-rebase\n-\tchange-the-reflog (start): checkout reflog-onto\n+\tgit log -g --format=%gs -1 conflicts >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): refs/heads/conflicts onto $(git rev-parse main)\n \tEOF\n-\ttest_cmp expect actual\n-'\n-\n-test_expect_success 'rebase --apply reflog' '\n-\tgit checkout -b reflog-apply start &&\n-\told_head_reflog=\"$(git log -g --format=%gs -1 HEAD)\" &&\n-\n-\tgit rebase --apply Y &&\n+\ttest_cmp expect actual &&\n \n-\tgit log -g --format=%gs -4 HEAD >actual &&\n-\tcat >expect <<-EOF &&\n-\trebase finished: returning to refs/heads/reflog-apply\n-\trebase: Z\n-\trebase: checkout Y\n-\t$old_head_reflog\n+\t# check there is only one new entry in the branch reflog\n+\ttest_cmp_rev conflicts@{1} Q\n+\t'\n+\n+\ttest_expect_success \"rebase $mode fast-forward reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout fast-forward &&\n+\ttest_when_finished \"git reset --hard X\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\tgit rebase $mode main\n+\t) &&\n+\n+\tgit log -g --format=%gs -2 >actual &&\n+\tif test \"$mode\" = \"--apply\"\n+\tthen\n+\t\tfinish_msg=\"refs/heads/fast-forward onto $(git rev-parse main)\"\n+\telse\n+\t\tfinish_msg=\"returning to refs/heads/fast-forward\"\n+\tfi &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): $finish_msg\n+\t${reflog_action:-rebase} (start): checkout main\n \tEOF\n \ttest_cmp expect actual &&\n \n-\tgit log -g --format=%gs -2 reflog-apply >actual &&\n-\tcat >expect <<-EOF &&\n-\trebase finished: refs/heads/reflog-apply onto $(git rev-parse Y)\n-\tbranch: Created from start\n+\tgit log -g --format=%gs -1 fast-forward >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): refs/heads/fast-forward onto $(git rev-parse main)\n \tEOF\n-\ttest_cmp expect actual\n-'\n+\ttest_cmp expect actual &&\n+\n+\t# check there is only one new entry in the branch reflog\n+\ttest_cmp_rev fast-forward@{1} X\n+\t'\n+}\n+\n+test_reflog --merge\n+test_reflog --merge my-reflog-action\n+test_reflog --apply\n+test_reflog --apply my-reflog-action\n \n test_expect_success 'rebase -i onto unrelated history' '\n \tgit init unrelated &&\n-- \ngitgitgadget\n\n"},{"id":"465434","messageId":"12701ef7c7cd5a2cde57670db2afa071a5e5622f.1666344108.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v4.git.1666344108.gitgitgadget@gmail.com","subject":"[PATCH v4 2/8] rebase --apply: improve fast-forward reflog message","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-21T09:21:42Z","receivedAt":"2022-10-21T09:22:04Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nUsing move_to_original_branch() when reattaching HEAD after a\nfast-forward improves HEAD's reflog message when rebasing a branch. This\nis because it uses separate reflog messages for \"HEAD\" and\n\"branch\". HEAD's reflog will now record which branch we're returning to.\n\nWhen rebasing a detached HEAD there is no change in behavior. We\ncurrently call reset_head() when head_name is NULL but\nmove_to_original_branch() does not. However the existing call does not\nadd a message to the reflog because we're not changing the commit that\nHEAD points to and so lock_ref_for_update() skips the update.\n\nNote that the removal of \"strbuf_reset(&msg)\" is safe as there is a call\nto strbuf_release(&msf) just above this hunk which can be seen by\nviewing the diff with -U6.\n\nHelped-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 11 +----------\n t/t3406-rebase-message.sh |  8 +-------\n 2 files changed, 2 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex ef520f66fb8..e67020b3586 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1811,19 +1811,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t * If the onto is a proper descendant of the tip of the branch, then\n \t * we just fast-forwarded.\n \t */\n-\tstrbuf_reset(&msg);\n \tif (oideq(&branch_base, &options.orig_head->object.oid)) {\n \t\tprintf(_(\"Fast-forwarded %s to %s.\\n\"),\n \t\t\tbranch_name, options.onto_name);\n-\t\tstrbuf_addf(&msg, \"rebase finished: %s onto %s\",\n-\t\t\toptions.head_name ? options.head_name : \"detached HEAD\",\n-\t\t\toid_to_hex(&options.onto->object.oid));\n-\t\tmemset(&ropts, 0, sizeof(ropts));\n-\t\tropts.branch = options.head_name;\n-\t\tropts.flags = RESET_HEAD_REFS_ONLY;\n-\t\tropts.head_msg = msg.buf;\n-\t\treset_head(the_repository, &ropts);\n-\t\tstrbuf_release(&msg);\n+\t\tmove_to_original_branch(&options);\n \t\tret = finish_rebase(&options);\n \t\tgoto cleanup;\n \t}\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 413d6132ea2..5253dd1551d 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -143,14 +143,8 @@ test_reflog () {\n \t) &&\n \n \tgit log -g --format=%gs -2 >actual &&\n-\tif test \"$mode\" = \"--apply\"\n-\tthen\n-\t\tfinish_msg=\"refs/heads/fast-forward onto $(git rev-parse main)\"\n-\telse\n-\t\tfinish_msg=\"returning to refs/heads/fast-forward\"\n-\tfi &&\n \twrite_reflog_expect <<-EOF &&\n-\t${reflog_action:-rebase} (finish): $finish_msg\n+\t${reflog_action:-rebase} (finish): returning to refs/heads/fast-forward\n \t${reflog_action:-rebase} (start): checkout main\n \tEOF\n \ttest_cmp expect actual &&\n-- \ngitgitgadget\n\n"},{"id":"465435","messageId":"2c965f4b97c1773abc6b844b87fa64c5d6d1524c.1666344108.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v4.git.1666344108.gitgitgadget@gmail.com","subject":"[PATCH v4 3/8] rebase --merge: fix reflog when continuing","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-21T09:21:43Z","receivedAt":"2022-10-21T09:22:07Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe reflog message for a conflict resolution committed by \"rebase\n--continue\" looks like\n\n\trebase (continue): commit subject line\n\nUnfortunately the reflog message each subsequent pick look like\n\n\trebase (continue) (pick): commit subject line\n\nFix this by setting the reflog message for \"rebase --continue\" in\nsequencer_continue() so it does not affect subsequent commits. This\nintroduces a memory leak similar to the one leaking GIT_REFLOG_ACTION\nin pick_commits(). Both of these will be fixed in a future series that\nstops the sequencer calling setenv().\n\nIf we fail to commit the staged changes then we error out so\nGIT_REFLOG_ACTION does not need to be reset in that case.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 2 --\n sequencer.c               | 5 +++++\n t/t3406-rebase-message.sh | 9 +++++++--\n 3 files changed, 12 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex e67020b3586..414526f83a8 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1271,8 +1271,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tint fd;\n \n \t\toptions.action = \"continue\";\n-\t\tset_reflog_action(&options);\n-\n \t\t/* Sanity check */\n \t\tif (get_oid(\"HEAD\", &head))\n \t\t\tdie(_(\"Cannot read HEAD\"));\ndiff --git a/sequencer.c b/sequencer.c\nindex 61a8e0020d5..5790b35d763 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -4785,6 +4785,8 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \tif (read_populate_opts(opts))\n \t\treturn -1;\n \tif (is_rebase_i(opts)) {\n+\t\tchar *previous_reflog_action;\n+\n \t\tif ((res = read_populate_todo(r, &todo_list, opts)))\n \t\t\tgoto release_todo_list;\n \n@@ -4795,10 +4797,13 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)\n \t\t\tunlink(rebase_path_dropped());\n \t\t}\n \n+\t\tprevious_reflog_action = xstrdup(getenv(GIT_REFLOG_ACTION));\n+\t\tsetenv(GIT_REFLOG_ACTION, reflog_message(opts, \"continue\", NULL), 1);\n \t\tif (commit_staged_changes(r, opts, &todo_list)) {\n \t\t\tres = -1;\n \t\t\tgoto release_todo_list;\n \t\t}\n+\t\tsetenv(GIT_REFLOG_ACTION, previous_reflog_action, 1);\n \t} else if (!file_exists(get_todo_path(opts)))\n \t\treturn continue_single_pick(r, opts);\n \telse if ((res = read_populate_todo(r, &todo_list, opts)))\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 5253dd1551d..3ca2fbb0d59 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -17,6 +17,7 @@ test_expect_success 'setup' '\n \n \tgit checkout -b conflicts O &&\n \ttest_commit P &&\n+\ttest_commit conflict-X fileX &&\n \ttest_commit Q &&\n \n \tgit checkout -b topic O &&\n@@ -107,13 +108,17 @@ test_reflog () {\n \t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n \t\t\texport GIT_REFLOG_ACTION\n \t\tfi &&\n-\t\tgit rebase $mode main\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\techo resolved >fileX &&\n+\t\tgit add fileX &&\n+\t\tgit rebase --continue\n \t) &&\n \n-\tgit log -g --format=%gs -4 >actual &&\n+\tgit log -g --format=%gs -5 >actual &&\n \twrite_reflog_expect <<-EOF &&\n \t${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n \t${reflog_action:-rebase} (pick): Q\n+\t${reflog_action:-rebase} (continue): conflict-X\n \t${reflog_action:-rebase} (pick): P\n \t${reflog_action:-rebase} (start): checkout main\n \tEOF\n-- \ngitgitgadget\n\n"},{"id":"465436","messageId":"17138d910f0019927f0e7686c626ab7ccc33be93.1666344108.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v4.git.1666344108.gitgitgadget@gmail.com","subject":"[PATCH v4 4/8] rebase --merge: fix reflog message after skipping","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-21T09:21:44Z","receivedAt":"2022-10-21T09:22:09Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe reflog message for every pick after running \"rebase --skip\" looks\nlike\n\n\trebase (skip) (pick): commit subject line\n\nFix this by not appending \" (skip)\" to the reflog action.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          |  2 --\n t/t3406-rebase-message.sh | 24 ++++++++++++++++++++++++\n 2 files changed, 24 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 414526f83a8..c1e68173b5f 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1297,8 +1297,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n \n \t\toptions.action = \"skip\";\n-\t\tset_reflog_action(&options);\n-\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \t\tropts.flags = RESET_HEAD_HARD;\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 3ca2fbb0d59..8aa6a79acc1 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -163,6 +163,30 @@ test_reflog () {\n \t# check there is only one new entry in the branch reflog\n \ttest_cmp_rev fast-forward@{1} X\n \t'\n+\n+\ttest_expect_success \"rebase $mode --skip reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout conflicts &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\tgit rebase --skip\n+\t) &&\n+\n+\tgit log -g --format=%gs -4 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (finish): returning to refs/heads/conflicts\n+\t${reflog_action:-rebase} (pick): Q\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n+\tEOF\n+\ttest_cmp expect actual\n+\t'\n }\n \n test_reflog --merge\n-- \ngitgitgadget\n\n"},{"id":"465437","messageId":"0c71c73290441b67e2d70809cfaf605a1f3f70ca.1666344108.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v4.git.1666344108.gitgitgadget@gmail.com","subject":"[PATCH v4 5/8] rebase --apply: respect GIT_REFLOG_ACTION","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-21T09:21:45Z","receivedAt":"2022-10-21T09:22:13Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe reflog messages when finishing a rebase hard code \"rebase\" rather\nthan using GIT_REFLOG_ACTION.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 7 ++++---\n t/t3406-rebase-message.sh | 2 +-\n 2 files changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex c1e68173b5f..ea246c6bb3a 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -582,10 +582,11 @@ static int move_to_original_branch(struct rebase_options *opts)\n \tif (!opts->onto)\n \t\tBUG(\"move_to_original_branch without onto\");\n \n-\tstrbuf_addf(&branch_reflog, \"rebase finished: %s onto %s\",\n+\tstrbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n+\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n \t\t    opts->head_name, oid_to_hex(&opts->onto->object.oid));\n-\tstrbuf_addf(&head_reflog, \"rebase finished: returning to %s\",\n-\t\t    opts->head_name);\n+\tstrbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n+\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n \tropts.branch = opts->head_name;\n \tropts.flags = RESET_HEAD_REFS_ONLY;\n \tropts.branch_msg = branch_reflog.buf;\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 8aa6a79acc1..bb2a4949abc 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -88,7 +88,7 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n write_reflog_expect () {\n \tif test $mode = --apply\n \tthen\n-\t\tsed 's/.*(finish)/rebase finished/; s/ ([^)]*)//'\n+\t\tsed 's/(finish)/finished/; s/ ([^)]*)//'\n \telse\n \t\tcat\n \tfi >expect\n-- \ngitgitgadget\n\n"},{"id":"465438","messageId":"3f6b2e39f4091e891f3ab83da7944a0c497ec300.1666344108.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v4.git.1666344108.gitgitgadget@gmail.com","subject":"[PATCH v4 6/8] rebase --apply: make reflog messages match rebase --merge","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-21T09:21:46Z","receivedAt":"2022-10-21T09:22:14Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe apply backend creates slightly different reflog messages to the\nmerge backend when starting or finishing a rebase and when picking\ncommits. These differences make it harder than it needs to be to parse\nthe reflog (I have a script that reads the finishing messages from\nrebase and it is a pain to have to accommodate two different message\nformats). While it is possible to determine the backend used for a\nrebase from the reflog messages, the differences are not designed for\nthat purpose. c2417d3af7 (rebase: drop '-i' from the reflog for\ninteractive-based rebases, 2020-02-15) removed the clear distinction\nbetween the reflog messages of the two backends without complaint.\n\nAs the merge backend is the default it is likely to be the format most\ncommon in existing reflogs. For that reason the apply backend is changed\nto format its reflog messages to match the merge backend as closely as\npossible. Note that there is still a difference as when committing a\nconflict resolution the apply backend will use \"(pick)\" rather than\n\"(continue)\" because it is not currently possible to change the message\nfor a single commit.\n\nIn addition to c2417d3af7 we also changed the reflog messages in\n68aa495b59 (rebase: implement --merge via the interactive machinery,\n2018-12-11) and 2ac0d6273f (rebase: change the default backend from \"am\"\nto \"merge\", 2020-02-15). This commit makes the same change to \"git\nrebase --apply\" that 2ac0d6273f made to \"git rebase\" without any backend\nspecific options. As the messages are changed to use an existing format\nany scripts that can parse the reflog messages of the default rebase\nbackend should be unaffected by this change.\n\nThere are existing tests for the messages from both backends which are\nadjusted to ensure that they do not get out of sync in the future.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 9 +++++----\n t/t3406-rebase-message.sh | 2 +-\n 2 files changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex ea246c6bb3a..5253ba66861 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -582,10 +582,10 @@ static int move_to_original_branch(struct rebase_options *opts)\n \tif (!opts->onto)\n \t\tBUG(\"move_to_original_branch without onto\");\n \n-\tstrbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n+\tstrbuf_addf(&branch_reflog, \"%s (finish): %s onto %s\",\n \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n \t\t    opts->head_name, oid_to_hex(&opts->onto->object.oid));\n-\tstrbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n+\tstrbuf_addf(&head_reflog, \"%s (finish): returning to %s\",\n \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n \tropts.branch = opts->head_name;\n \tropts.flags = RESET_HEAD_REFS_ONLY;\n@@ -615,7 +615,8 @@ static int run_am(struct rebase_options *opts)\n \n \tam.git_cmd = 1;\n \tstrvec_push(&am.args, \"am\");\n-\n+\tstrvec_pushf(&am.env, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n+\t\t     getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n \t\tstrvec_push(&am.args, \"--resolved\");\n \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n@@ -1792,7 +1793,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tprintf(_(\"First, rewinding head to replay your work on top of \"\n \t\t\t \"it...\\n\"));\n \n-\tstrbuf_addf(&msg, \"%s: checkout %s\",\n+\tstrbuf_addf(&msg, \"%s (start): checkout %s\",\n \t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);\n \tropts.oid = &options.onto->object.oid;\n \tropts.orig_head = &options.orig_head->object.oid,\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex bb2a4949abc..5c6cd9af3bc 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -88,7 +88,7 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n write_reflog_expect () {\n \tif test $mode = --apply\n \tthen\n-\t\tsed 's/(finish)/finished/; s/ ([^)]*)//'\n+\t\tsed 's/(continue)/(pick)/'\n \telse\n \t\tcat\n \tfi >expect\n-- \ngitgitgadget\n\n"},{"id":"465439","messageId":"c8fa57f129dd61fd4925e1c29ca78b89364dc62b.1666344108.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v4.git.1666344108.gitgitgadget@gmail.com","subject":"[PATCH v4 7/8] rebase --abort: improve reflog message","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-21T09:21:47Z","receivedAt":"2022-10-21T09:22:15Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nWhen aborting a rebase the reflog message looks like\n\n\trebase (abort): updating HEAD\n\nwhich is not very informative. Improve the message by mentioning the\nbranch that we are returning to as we do at the end of a successful\nrebase so it looks like.\n\n\trebase (abort): returning to refs/heads/topic\n\nIf GIT_REFLOG_ACTION is set in the environment we no longer omit\n\"(abort)\" from the reflog message. We don't omit \"(start)\" and\n\"(finish)\" when starting and finishing a rebase in that case so we\nshouldn't omit \"(abort)\".\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c          | 28 ++++++---------------\n t/t3406-rebase-message.sh | 51 +++++++++++++++++++++++++++++++++++++++\n 2 files changed, 59 insertions(+), 20 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 5253ba66861..d63d77757e8 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1001,23 +1001,6 @@ static void NORETURN error_on_missing_default_upstream(void)\n \texit(1);\n }\n \n-static void set_reflog_action(struct rebase_options *options)\n-{\n-\tconst char *env;\n-\tstruct strbuf buf = STRBUF_INIT;\n-\n-\tif (!is_merge(options))\n-\t\treturn;\n-\n-\tenv = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);\n-\tif (env && strcmp(\"rebase\", env))\n-\t\treturn; /* only override it if it is \"rebase\" */\n-\n-\tstrbuf_addf(&buf, \"rebase (%s)\", options->action);\n-\tsetenv(GIT_REFLOG_ACTION_ENVIRONMENT, buf.buf, 1);\n-\tstrbuf_release(&buf);\n-}\n-\n static int check_exec_cmd(const char *cmd)\n {\n \tif (strchr(cmd, '\\n'))\n@@ -1311,18 +1294,23 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t}\n \tcase ACTION_ABORT: {\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n-\t\toptions.action = \"abort\";\n-\t\tset_reflog_action(&options);\n+\t\tstruct strbuf head_msg = STRBUF_INIT;\n \n+\t\toptions.action = \"abort\";\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \n \t\tif (read_basic_state(&options))\n \t\t\texit(1);\n+\n+\t\tstrbuf_addf(&head_msg, \"%s (abort): returning to %s\",\n+\t\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n+\t\t\t    options.head_name ? options.head_name\n+\t\t\t\t\t      : oid_to_hex(&options.orig_head->object.oid));\n \t\tropts.oid = &options.orig_head->object.oid;\n+\t\tropts.head_msg = head_msg.buf;\n \t\tropts.branch = options.head_name;\n \t\tropts.flags = RESET_HEAD_HARD;\n-\t\tropts.default_reflog_action = DEFAULT_REFLOG_ACTION;\n \t\tif (reset_head(the_repository, &ropts) < 0)\n \t\t\tdie(_(\"could not move back to %s\"),\n \t\t\t    oid_to_hex(&options.orig_head->object.oid));\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex 5c6cd9af3bc..ceca1600053 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -187,6 +187,57 @@ test_reflog () {\n \tEOF\n \ttest_cmp expect actual\n \t'\n+\n+\ttest_expect_success \"rebase $mode --abort reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout conflicts &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\tgit log -g -1 conflicts >branch-expect &&\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\tgit rebase --abort\n+\t) &&\n+\n+\tgit log -g --format=%gs -3 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (abort): returning to refs/heads/conflicts\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n+\tEOF\n+\ttest_cmp expect actual &&\n+\n+\t# check branch reflog is unchanged\n+\tgit log -g -1 conflicts >branch-actual &&\n+\ttest_cmp branch-expect branch-actual\n+\t'\n+\n+\ttest_expect_success \"rebase $mode --abort detached HEAD reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}\" '\n+\tgit checkout Q &&\n+\ttest_when_finished \"git reset --hard Q\" &&\n+\n+\t(\n+\t\tif test -n \"$reflog_action\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$reflog_action\" &&\n+\t\t\texport GIT_REFLOG_ACTION\n+\t\tfi &&\n+\t\ttest_must_fail git rebase $mode main &&\n+\t\tgit rebase --abort\n+\t) &&\n+\n+\tgit log -g --format=%gs -3 >actual &&\n+\twrite_reflog_expect <<-EOF &&\n+\t${reflog_action:-rebase} (abort): returning to $(git rev-parse Q)\n+\t${reflog_action:-rebase} (pick): P\n+\t${reflog_action:-rebase} (start): checkout main\n+\tEOF\n+\ttest_cmp expect actual\n+\t'\n }\n \n test_reflog --merge\n-- \ngitgitgadget\n\n"},{"id":"465440","messageId":"ed800844ba13d143bdbc5fd0b033af96df131529.1666344108.git.gitgitgadget@gmail.com","threadId":"57450","inReplyTo":"pull.1150.v4.git.1666344108.gitgitgadget@gmail.com","subject":"[PATCH v4 8/8] rebase: cleanup action handling","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-10-21T09:21:48Z","receivedAt":"2022-10-21T09:22:23Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nTreating the action as a string is a hang over from the scripted\nrebase. The last commit removed the only remaining use of the action\nthat required a string so lets convert the other action users to use\nthe existing action enum instead. If we ever need the action name as a\nstring in the future the action_names array exists exactly for that\npurpose.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/rebase.c | 93 +++++++++++++++++++++++-------------------------\n 1 file changed, 44 insertions(+), 49 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex d63d77757e8..d5e684a7cec 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -59,6 +59,26 @@ enum empty_type {\n \tEMPTY_ASK\n };\n \n+enum action {\n+\tACTION_NONE = 0,\n+\tACTION_CONTINUE,\n+\tACTION_SKIP,\n+\tACTION_ABORT,\n+\tACTION_QUIT,\n+\tACTION_EDIT_TODO,\n+\tACTION_SHOW_CURRENT_PATCH\n+};\n+\n+static const char *action_names[] = {\n+\t\"undefined\",\n+\t\"continue\",\n+\t\"skip\",\n+\t\"abort\",\n+\t\"quit\",\n+\t\"edit_todo\",\n+\t\"show_current_patch\"\n+};\n+\n struct rebase_options {\n \tenum rebase_type type;\n \tenum empty_type empty;\n@@ -85,7 +105,7 @@ struct rebase_options {\n \t\tREBASE_INTERACTIVE_EXPLICIT = 1<<4,\n \t} flags;\n \tstruct strvec git_am_opts;\n-\tconst char *action;\n+\tenum action action;\n \tint signoff;\n \tint allow_rerere_autoupdate;\n \tint keep_empty;\n@@ -156,24 +176,6 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)\n \treturn replay;\n }\n \n-enum action {\n-\tACTION_NONE = 0,\n-\tACTION_CONTINUE,\n-\tACTION_SKIP,\n-\tACTION_ABORT,\n-\tACTION_QUIT,\n-\tACTION_EDIT_TODO,\n-\tACTION_SHOW_CURRENT_PATCH\n-};\n-\n-static const char *action_names[] = { \"undefined\",\n-\t\t\t\t      \"continue\",\n-\t\t\t\t      \"skip\",\n-\t\t\t\t      \"abort\",\n-\t\t\t\t      \"quit\",\n-\t\t\t\t      \"edit_todo\",\n-\t\t\t\t      \"show_current_patch\" };\n-\n static int edit_todo_file(unsigned flags)\n {\n \tconst char *todo_file = rebase_path_todo();\n@@ -310,8 +312,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)\n \treturn ret;\n }\n \n-static int run_sequencer_rebase(struct rebase_options *opts,\n-\t\t\t\t  enum action command)\n+static int run_sequencer_rebase(struct rebase_options *opts)\n {\n \tunsigned flags = 0;\n \tint abbreviate_commands = 0, ret = 0;\n@@ -326,7 +327,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n \tflags |= opts->reapply_cherry_picks ? TODO_LIST_REAPPLY_CHERRY_PICKS : 0;\n \tflags |= opts->flags & REBASE_NO_QUIET ? TODO_LIST_WARN_SKIPPED_CHERRY_PICKS : 0;\n \n-\tswitch (command) {\n+\tswitch (opts->action) {\n \tcase ACTION_NONE: {\n \t\tif (!opts->onto && !opts->upstream)\n \t\t\tdie(_(\"a base commit must be provided with --upstream or --onto\"));\n@@ -359,7 +360,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n \t\tbreak;\n \t}\n \tdefault:\n-\t\tBUG(\"invalid command '%d'\", command);\n+\t\tBUG(\"invalid command '%d'\", opts->action);\n \t}\n \n \treturn ret;\n@@ -617,7 +618,7 @@ static int run_am(struct rebase_options *opts)\n \tstrvec_push(&am.args, \"am\");\n \tstrvec_pushf(&am.env, GIT_REFLOG_ACTION_ENVIRONMENT \"=%s (pick)\",\n \t\t     getenv(GIT_REFLOG_ACTION_ENVIRONMENT));\n-\tif (opts->action && !strcmp(\"continue\", opts->action)) {\n+\tif (opts->action == ACTION_CONTINUE) {\n \t\tstrvec_push(&am.args, \"--resolved\");\n \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n \t\tif (opts->gpg_sign_opt)\n@@ -628,7 +629,7 @@ static int run_am(struct rebase_options *opts)\n \n \t\treturn move_to_original_branch(opts);\n \t}\n-\tif (opts->action && !strcmp(\"skip\", opts->action)) {\n+\tif (opts->action == ACTION_SKIP) {\n \t\tstrvec_push(&am.args, \"--skip\");\n \t\tstrvec_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n \t\tstatus = run_command(&am);\n@@ -637,7 +638,7 @@ static int run_am(struct rebase_options *opts)\n \n \t\treturn move_to_original_branch(opts);\n \t}\n-\tif (opts->action && !strcmp(\"show-current-patch\", opts->action)) {\n+\tif (opts->action == ACTION_SHOW_CURRENT_PATCH) {\n \t\tstrvec_push(&am.args, \"--show-current-patch\");\n \t\treturn run_command(&am);\n \t}\n@@ -730,7 +731,7 @@ static int run_am(struct rebase_options *opts)\n \treturn status;\n }\n \n-static int run_specific_rebase(struct rebase_options *opts, enum action action)\n+static int run_specific_rebase(struct rebase_options *opts)\n {\n \tint status;\n \n@@ -748,7 +749,7 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n \t\t\topts->gpg_sign_opt = tmp;\n \t\t}\n \n-\t\tstatus = run_sequencer_rebase(opts, action);\n+\t\tstatus = run_sequencer_rebase(opts);\n \t} else if (opts->type == REBASE_APPLY)\n \t\tstatus = run_am(opts);\n \telse\n@@ -1025,7 +1026,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct object_id branch_base;\n \tint ignore_whitespace = 0;\n-\tenum action action = ACTION_NONE;\n \tconst char *gpg_sign = NULL;\n \tstruct string_list exec = STRING_LIST_INIT_NODUP;\n \tconst char *rebase_merges = NULL;\n@@ -1074,18 +1074,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tOPT_BIT(0, \"no-ff\", &options.flags,\n \t\t\tN_(\"cherry-pick all commits, even if unchanged\"),\n \t\t\tREBASE_FORCE),\n-\t\tOPT_CMDMODE(0, \"continue\", &action, N_(\"continue\"),\n+\t\tOPT_CMDMODE(0, \"continue\", &options.action, N_(\"continue\"),\n \t\t\t    ACTION_CONTINUE),\n-\t\tOPT_CMDMODE(0, \"skip\", &action,\n+\t\tOPT_CMDMODE(0, \"skip\", &options.action,\n \t\t\t    N_(\"skip current patch and continue\"), ACTION_SKIP),\n-\t\tOPT_CMDMODE(0, \"abort\", &action,\n+\t\tOPT_CMDMODE(0, \"abort\", &options.action,\n \t\t\t    N_(\"abort and check out the original branch\"),\n \t\t\t    ACTION_ABORT),\n-\t\tOPT_CMDMODE(0, \"quit\", &action,\n+\t\tOPT_CMDMODE(0, \"quit\", &options.action,\n \t\t\t    N_(\"abort but keep HEAD where it is\"), ACTION_QUIT),\n-\t\tOPT_CMDMODE(0, \"edit-todo\", &action, N_(\"edit the todo list \"\n+\t\tOPT_CMDMODE(0, \"edit-todo\", &options.action, N_(\"edit the todo list \"\n \t\t\t    \"during an interactive rebase\"), ACTION_EDIT_TODO),\n-\t\tOPT_CMDMODE(0, \"show-current-patch\", &action,\n+\t\tOPT_CMDMODE(0, \"show-current-patch\", &options.action,\n \t\t\t    N_(\"show the patch file being applied or merged\"),\n \t\t\t    ACTION_SHOW_CURRENT_PATCH),\n \t\tOPT_CALLBACK_F(0, \"apply\", &options, NULL,\n@@ -1174,7 +1174,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t} else if (is_directory(merge_dir())) {\n \t\tstrbuf_reset(&buf);\n \t\tstrbuf_addf(&buf, \"%s/rewritten\", merge_dir());\n-\t\tif (!(action == ACTION_ABORT) && is_directory(buf.buf)) {\n+\t\tif (!(options.action == ACTION_ABORT) && is_directory(buf.buf)) {\n \t\t\tdie(_(\"`rebase --preserve-merges` (-p) is no longer supported.\\n\"\n \t\t\t\"Use `git rebase --abort` to terminate current rebase.\\n\"\n \t\t\t\"Or downgrade to v2.33, or earlier, to complete the rebase.\"));\n@@ -1201,7 +1201,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\t\"Note: Your `pull.rebase` configuration may also be set to 'preserve',\\n\"\n \t\t\t\"which is no longer supported; use 'merges' instead\"));\n \n-\tif (action != ACTION_NONE && total_argc != 2) {\n+\tif (options.action != ACTION_NONE && total_argc != 2) {\n \t\tusage_with_options(builtin_rebase_usage,\n \t\t\t\t   builtin_rebase_options);\n \t}\n@@ -1232,11 +1232,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tif (options.root && options.fork_point > 0)\n \t\tdie(_(\"options '%s' and '%s' cannot be used together\"), \"--root\", \"--fork-point\");\n \n-\tif (action != ACTION_NONE && !in_progress)\n+\tif (options.action != ACTION_NONE && !in_progress)\n \t\tdie(_(\"No rebase in progress?\"));\n \tsetenv(GIT_REFLOG_ACTION_ENVIRONMENT, \"rebase\", 0);\n \n-\tif (action == ACTION_EDIT_TODO && !is_merge(&options))\n+\tif (options.action == ACTION_EDIT_TODO && !is_merge(&options))\n \t\tdie(_(\"The --edit-todo action can only be used during \"\n \t\t      \"interactive rebase.\"));\n \n@@ -1246,16 +1246,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\telse if (exec.nr)\n \t\t\ttrace2_cmd_mode(\"interactive-exec\");\n \t\telse\n-\t\t\ttrace2_cmd_mode(action_names[action]);\n+\t\t\ttrace2_cmd_mode(action_names[options.action]);\n \t}\n \n-\tswitch (action) {\n+\tswitch (options.action) {\n \tcase ACTION_CONTINUE: {\n \t\tstruct object_id head;\n \t\tstruct lock_file lock_file = LOCK_INIT;\n \t\tint fd;\n \n-\t\toptions.action = \"continue\";\n \t\t/* Sanity check */\n \t\tif (get_oid(\"HEAD\", &head))\n \t\t\tdie(_(\"Cannot read HEAD\"));\n@@ -1281,7 +1280,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tcase ACTION_SKIP: {\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n \n-\t\toptions.action = \"skip\";\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \t\tropts.flags = RESET_HEAD_HARD;\n@@ -1296,7 +1294,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n \t\tstruct strbuf head_msg = STRBUF_INIT;\n \n-\t\toptions.action = \"abort\";\n \t\trerere_clear(the_repository, &merge_rr);\n \t\tstring_list_clear(&merge_rr, 1);\n \n@@ -1336,17 +1333,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tgoto cleanup;\n \t}\n \tcase ACTION_EDIT_TODO:\n-\t\toptions.action = \"edit-todo\";\n \t\toptions.dont_finish_rebase = 1;\n \t\tgoto run_rebase;\n \tcase ACTION_SHOW_CURRENT_PATCH:\n-\t\toptions.action = \"show-current-patch\";\n \t\toptions.dont_finish_rebase = 1;\n \t\tgoto run_rebase;\n \tcase ACTION_NONE:\n \t\tbreak;\n \tdefault:\n-\t\tBUG(\"action: %d\", action);\n+\t\tBUG(\"action: %d\", options.action);\n \t}\n \n \t/* Make sure no rebase is in progress */\n@@ -1370,7 +1365,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif ((options.flags & REBASE_INTERACTIVE_EXPLICIT) ||\n-\t    (action != ACTION_NONE) ||\n+\t    (options.action != ACTION_NONE) ||\n \t    (exec.nr > 0) ||\n \t    options.autosquash) {\n \t\tallow_preemptive_ff = 0;\n@@ -1815,7 +1810,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \toptions.revisions = revisions.buf;\n \n run_rebase:\n-\tret = run_specific_rebase(&options, action);\n+\tret = run_specific_rebase(&options);\n \n cleanup:\n \tstrbuf_release(&buf);\n-- \ngitgitgadget\n"},{"id":"465494","messageId":"xmqqk04tm62o.fsf@gitster.g","threadId":"57450","inReplyTo":"2c965f4b97c1773abc6b844b87fa64c5d6d1524c.1666344108.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 3/8] rebase --merge: fix reflog when continuing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-10-21T17:37:03Z","receivedAt":"2022-10-21T17:37:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> ... This\n> introduces a memory leak similar to the one leaking GIT_REFLOG_ACTION\n> in pick_commits().\n\nIs it just the matter of freeing previous_reflog_action after you\ncall setenv(), or does it take much more involved changes?\n\n> Both of these will be fixed in a future series that\n> stops the sequencer calling setenv().\n\nIf it gets fixed in a future step in the same series, that is a\ndifferent matter, but if it is easy enough not to deliberately\nintroduce a new leak, we'd prefer to do so.\n"},{"id":"465495","messageId":"xmqqfsfhm603.fsf@gitster.g","threadId":"57450","inReplyTo":"0c71c73290441b67e2d70809cfaf605a1f3f70ca.1666344108.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 5/8] rebase --apply: respect GIT_REFLOG_ACTION","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-10-21T17:38:36Z","receivedAt":"2022-10-21T17:38:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> The reflog messages when finishing a rebase hard code \"rebase\" rather\n> than using GIT_REFLOG_ACTION.\n\nMakes sense.\n\n>\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  builtin/rebase.c          | 7 ++++---\n>  t/t3406-rebase-message.sh | 2 +-\n>  2 files changed, 5 insertions(+), 4 deletions(-)\n>\n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index c1e68173b5f..ea246c6bb3a 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -582,10 +582,11 @@ static int move_to_original_branch(struct rebase_options *opts)\n>  \tif (!opts->onto)\n>  \t\tBUG(\"move_to_original_branch without onto\");\n>  \n> -\tstrbuf_addf(&branch_reflog, \"rebase finished: %s onto %s\",\n> +\tstrbuf_addf(&branch_reflog, \"%s finished: %s onto %s\",\n> +\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT),\n>  \t\t    opts->head_name, oid_to_hex(&opts->onto->object.oid));\n> -\tstrbuf_addf(&head_reflog, \"rebase finished: returning to %s\",\n> -\t\t    opts->head_name);\n> +\tstrbuf_addf(&head_reflog, \"%s finished: returning to %s\",\n> +\t\t    getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);\n>  \tropts.branch = opts->head_name;\n>  \tropts.flags = RESET_HEAD_REFS_ONLY;\n>  \tropts.branch_msg = branch_reflog.buf;\n> diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\n> index 8aa6a79acc1..bb2a4949abc 100755\n> --- a/t/t3406-rebase-message.sh\n> +++ b/t/t3406-rebase-message.sh\n> @@ -88,7 +88,7 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n>  write_reflog_expect () {\n>  \tif test $mode = --apply\n>  \tthen\n> -\t\tsed 's/.*(finish)/rebase finished/; s/ ([^)]*)//'\n> +\t\tsed 's/(finish)/finished/; s/ ([^)]*)//'\n>  \telse\n>  \t\tcat\n>  \tfi >expect\n"},{"id":"465496","messageId":"xmqqbkq5m5yh.fsf@gitster.g","threadId":"57450","inReplyTo":"3f6b2e39f4091e891f3ab83da7944a0c497ec300.1666344108.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 6/8] rebase --apply: make reflog messages match rebase --merge","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-10-21T17:39:34Z","receivedAt":"2022-10-21T17:39:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> The apply backend creates slightly different reflog messages to the\n> merge backend when starting or finishing a rebase and when picking\n> commits. ...\n> There are existing tests for the messages from both backends which are\n> adjusted to ensure that they do not get out of sync in the future.\n\nNice.\n"},{"id":"465497","messageId":"xmqq7d0tm5qr.fsf@gitster.g","threadId":"57450","inReplyTo":"c8fa57f129dd61fd4925e1c29ca78b89364dc62b.1666344108.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 7/8] rebase --abort: improve reflog message","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-10-21T17:44:12Z","receivedAt":"2022-10-21T17:44:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> When aborting a rebase the reflog message looks like\n>\n> \trebase (abort): updating HEAD\n>\n> which is not very informative. Improve the message by mentioning the\n> branch that we are returning to as we do at the end of a successful\n> rebase so it looks like.\n>\n> \trebase (abort): returning to refs/heads/topic\n>\n> If GIT_REFLOG_ACTION is set in the environment we no longer omit\n> \"(abort)\" from the reflog message. We don't omit \"(start)\" and\n> \"(finish)\" when starting and finishing a rebase in that case so we\n> shouldn't omit \"(abort)\".\n\nSuper nice.\n\n"},{"id":"465498","messageId":"xmqqo7u5kqov.fsf@gitster.g","threadId":"57450","inReplyTo":"ed800844ba13d143bdbc5fd0b033af96df131529.1666344108.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 8/8] rebase: cleanup action handling","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-10-21T17:54:40Z","receivedAt":"2022-10-21T17:54:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> Treating the action as a string is a hang over from the scripted\n> rebase. The last commit removed the only remaining use of the action\n> that required a string so lets convert the other action users to use\n> the existing action enum instead. If we ever need the action name as a\n> string in the future the action_names array exists exactly for that\n> purpose.\n\nNice.\n\n\n#leftoverbit\n\nPerhaps a clean-up worth making after the dust settles from this\nseries would be to use designated initialisers to avoid names and\ntheir string values going out of sync, perhaps like\n\n\tstatic const char *action_names[] = {\n\t\t[ACTION_NONE] = \"undefined\",\n\t\t[ACTION_CONTINUE] = \"continue\",\n\t\t...\n\t\t[ACTION_SHOW_CURRENT_PATCH] = \"show_current_patch\",\n\t};\n\nUnless the final element is something that must stay at the end even\nwhen adding new member to a collection, it is a good idea to keep a\n(seemingly unnecessary) comma at the end.  That would make it easier\nto add a new member without unnecessary patch noise.\n\n"},{"id":"465695","messageId":"86699708-d631-fb49-482c-af27204a3570@dunelm.org.uk","threadId":"57450","inReplyTo":"xmqqk04tm62o.fsf@gitster.g","subject":"Re: [PATCH v4 3/8] rebase --merge: fix reflog when continuing","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2022-10-25T10:08:41Z","receivedAt":"2022-10-25T10:15:44Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Junio\n\nOn 21/10/2022 18:37, Junio C Hamano wrote:\n> \"Phillip Wood via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> \n>> ... This\n>> introduces a memory leak similar to the one leaking GIT_REFLOG_ACTION\n>> in pick_commits().\n> \n> Is it just the matter of freeing previous_reflog_action after you\n> call setenv(), or does it take much more involved changes?\n\nWe should be freeing previous_reflog_action - I had misremembered a \nprevious discussion about setenv() but the manual page makes it quite \nclear that it copies the strings passed to it. However we call setenv() \neach time we pick a commit and that leaks the previous value. The \nsolution is to avoid calling setenv() at all and instead use the env \nmember of struct child_process when we run \"git commit\".\n\n>> Both of these will be fixed in a future series that\n>> stops the sequencer calling setenv().\n> \n> If it gets fixed in a future step in the same series, that is a\n> different matter, but if it is easy enough not to deliberately\n> introduce a new leak, we'd prefer to do so.\n\nIt's a couple of patches to fix which are more or less finished, I'm \nplanning to send them once this series is in next.\n\nBest Wishes\n\nPhillip\n"},{"id":"465715","messageId":"xmqqczafopc0.fsf@gitster.g","threadId":"57450","inReplyTo":"86699708-d631-fb49-482c-af27204a3570@dunelm.org.uk","subject":"Re: [PATCH v4 3/8] rebase --merge: fix reflog when continuing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-10-25T16:11:43Z","receivedAt":"2022-10-25T16:11:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n>>> Both of these will be fixed in a future series that\n>>> stops the sequencer calling setenv().\n>> If it gets fixed in a future step in the same series, that is a\n>> different matter, but if it is easy enough not to deliberately\n>> introduce a new leak, we'd prefer to do so.\n>\n> It's a couple of patches to fix which are more or less finished, I'm\n> planning to send them once this series is in next.\n\nSo we will do the \"add a known breakage of the same kind as there\nexists others, and then later fix them all up, including the one\nthat is added by this series, because fixes are non-trivial and this\ntopic is easier to finish if we allowed to add a known breakage\"\napproach?  Just making sure it is what you plan to do.\n\nThanks.\n"},{"id":"465793","messageId":"8af26af0-548d-52c8-9752-1a265af8fd54@dunelm.org.uk","threadId":"57450","inReplyTo":"xmqqczafopc0.fsf@gitster.g","subject":"Re: [PATCH v4 3/8] rebase --merge: fix reflog when continuing","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2022-10-26T15:17:13Z","receivedAt":"2022-10-26T15:17:25Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Junio\n\nOn 25/10/2022 17:11, Junio C Hamano wrote:\n> Phillip Wood <phillip.wood123@gmail.com> writes:\n> \n>>>> Both of these will be fixed in a future series that\n>>>> stops the sequencer calling setenv().\n>>> If it gets fixed in a future step in the same series, that is a\n>>> different matter, but if it is easy enough not to deliberately\n>>> introduce a new leak, we'd prefer to do so.\n>>\n>> It's a couple of patches to fix which are more or less finished, I'm\n>> planning to send them once this series is in next.\n> \n> So we will do the \"add a known breakage of the same kind as there\n> exists others, and then later fix them all up, including the one\n> that is added by this series, because fixes are non-trivial and this\n> topic is easier to finish if we allowed to add a known breakage\"\n> approach?  Just making sure it is what you plan to do.\n\nYes, that's right\n\nThanks\n\nPhillip\n\n> Thanks.\n"},{"id":"465808","messageId":"xmqq7d0mikyj.fsf@gitster.g","threadId":"57450","inReplyTo":"8af26af0-548d-52c8-9752-1a265af8fd54@dunelm.org.uk","subject":"Re: [PATCH v4 3/8] rebase --merge: fix reflog when continuing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-10-26T16:55:00Z","receivedAt":"2022-10-26T16:55:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> Hi Junio\n>\n> On 25/10/2022 17:11, Junio C Hamano wrote:\n>> Phillip Wood <phillip.wood123@gmail.com> writes:\n>> \n>>>>> Both of these will be fixed in a future series that\n>>>>> stops the sequencer calling setenv().\n>>>> If it gets fixed in a future step in the same series, that is a\n>>>> different matter, but if it is easy enough not to deliberately\n>>>> introduce a new leak, we'd prefer to do so.\n>>>\n>>> It's a couple of patches to fix which are more or less finished, I'm\n>>> planning to send them once this series is in next.\n>> So we will do the \"add a known breakage of the same kind as there\n>> exists others, and then later fix them all up, including the one\n>> that is added by this series, because fixes are non-trivial and this\n>> topic is easier to finish if we allowed to add a known breakage\"\n>> approach?  Just making sure it is what you plan to do.\n>\n> Yes, that's right\n\nOK, I do not mind as long as we leave a NEEDSWORK note to tell\nothers that we know the leak and promise to fix it soon (so they do\nnot waste their effort to fix it independently).\n\nThanks.\n"}]}