rebase: fix GIT_REFLOG_ACTION regression
The scripted version of "rebase" honored the `GIT_REFLOG_ACTION`, and some automation scripts expected the reflog entries to be prefixed with "rebase -i", not "rebase", after running "rebase -i". This regressed in the reimplementation in C. Fix that, and add a regression test, both with `GIT_REFLOG_ACTION` set and unset. Note: the reflog message for "rebase finished" did *not* honor GIT_REFLOG_ACTION, and as we are very late in the v2.20.0-rcN phase, we leave that bug for later (as it seems that that bug has been with us from the very beginning). Reported by Ian Jackson. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Schindelin committed
Nov 29, 2018 at 11:09 UTC
13a5a9f0fdcf36270dcc2dcb7752c281bbea06f1
2 files changed
+52
-3
builtin/rebase.c
+26
-3
@@ -776,6 +776,23 @@ static void NORETURN error_on_missing_default_upstream(void)
776
exit(1);
777
}
778
779
+static void set_reflog_action(struct rebase_options *options)
780
+{
781
+ const char *env;
782
+ struct strbuf buf = STRBUF_INIT;
783
+
784
+ if (!is_interactive(options))
785
+ return;
786
+
787
+ env = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
788
+ if (env && strcmp("rebase", env))
789
+ return; /* only override it if it is "rebase" */
790
+
791
+ strbuf_addf(&buf, "rebase -i (%s)", options->action);
792
+ setenv(GIT_REFLOG_ACTION_ENVIRONMENT, buf.buf, 1);
793
+ strbuf_release(&buf);
794
+}
795
+
796
int cmd_rebase(int argc, const char **argv, const char *prefix)
797
{
798
struct rebase_options options = {
@@ -978,6 +995,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
995
996
if (action != NO_ACTION && !in_progress)
997
die(_("No rebase in progress?"));
998
+ setenv(GIT_REFLOG_ACTION_ENVIRONMENT, "rebase", 0);
999
1000
if (action == ACTION_EDIT_TODO && !is_interactive(&options))
1001
die(_("The --edit-todo action can only be used during "
@@ -990,6 +1008,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1008
int fd;
1009
1010
options.action = "continue";
1011
+ set_reflog_action(&options);
1012
1013
/* Sanity check */
1014
if (get_oid("HEAD", &head))
@@ -1018,6 +1037,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1037
struct string_list merge_rr = STRING_LIST_INIT_DUP;
1038
1039
options.action = "skip";
1040
+ set_reflog_action(&options);
1041
1042
rerere_clear(&merge_rr);
1043
string_list_clear(&merge_rr, 1);
@@ -1033,6 +1053,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1053
case ACTION_ABORT: {
1054
struct string_list merge_rr = STRING_LIST_INIT_DUP;
1055
options.action = "abort";
1056
+ set_reflog_action(&options);
1057
1058
rerere_clear(&merge_rr);
1059
string_list_clear(&merge_rr, 1);
@@ -1440,11 +1461,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1461
}
1462
1463
strbuf_reset(&buf);
1443
- strbuf_addf(&buf, "rebase: checkout %s",
1464
+ strbuf_addf(&buf, "%s: checkout %s",
1465
+ getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
1466
options.switch_to);
1467
if (reset_head(&oid, "checkout",
1468
options.head_name, 0,
1447
- NULL, NULL) < 0) {
1469
+ NULL, buf.buf) < 0) {
1470
ret = !!error(_("could not switch to "
1471
"%s"),
1472
options.switch_to);
@@ -1508,7 +1530,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1530
printf(_("First, rewinding head to replay your work on top of "
1531
"it...\n"));
1532
1511
- strbuf_addf(&msg, "rebase: checkout %s", options.onto_name);
1533
+ strbuf_addf(&msg, "%s: checkout %s",
1534
+ getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);
1535
if (reset_head(&options.onto->object.oid, "checkout", NULL,
1536
RESET_HEAD_DETACH, NULL, msg.buf))
1537
die(_("Could not detach HEAD"));
t/t3406-rebase-message.sh
+26
@@ -91,4 +91,30 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '
91
test_i18ngrep "Invalid whitespace option" err
92
'
93
94
+test_expect_success 'GIT_REFLOG_ACTION' '
95
+ git checkout start &&
96
+ test_commit reflog-onto &&
97
+ git checkout -b reflog-topic start &&
98
+ test_commit reflog-to-rebase &&
99
+
100
+ git rebase reflog-onto &&
101
+ git log -g --format=%gs -3 >actual &&
102
+ cat >expect <<-\EOF &&
103
+ rebase finished: returning to refs/heads/reflog-topic
104
+ rebase: reflog-to-rebase
105
+ rebase: checkout reflog-onto
106
+ EOF
107
+ test_cmp expect actual &&
108
+
109
+ git checkout -b reflog-prefix reflog-to-rebase &&
110
+ GIT_REFLOG_ACTION=change-the-reflog git rebase reflog-onto &&
111
+ git log -g --format=%gs -3 >actual &&
112
+ cat >expect <<-\EOF &&
113
+ rebase finished: returning to refs/heads/reflog-prefix
114
+ change-the-reflog: reflog-to-rebase
115
+ change-the-reflog: checkout reflog-onto
116
+ EOF
117
+ test_cmp expect actual
118
+'
119
+
120
test_done