Skip to content

Commit 8851c4b

Browse files
committed
Merge branch 'pw/rebase-reflog-fixes'
Fix some bugs in the reflog messages when rebasing and changes the reflog messages of "rebase --apply" to match "rebase --merge" with the aim of making the reflog easier to parse. * pw/rebase-reflog-fixes: rebase: cleanup action handling rebase --abort: improve reflog message rebase --apply: make reflog messages match rebase --merge rebase --apply: respect GIT_REFLOG_ACTION rebase --merge: fix reflog message after skipping rebase --merge: fix reflog when continuing t3406: rework rebase reflog tests rebase --apply: remove duplicated code
2 parents 003f815 + 9a1925b commit 8851c4b

File tree

3 files changed

+215
-121
lines changed

3 files changed

+215
-121
lines changed

builtin/rebase.c

Lines changed: 59 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,26 @@ enum empty_type {
5959
EMPTY_ASK
6060
};
6161

62+
enum action {
63+
ACTION_NONE = 0,
64+
ACTION_CONTINUE,
65+
ACTION_SKIP,
66+
ACTION_ABORT,
67+
ACTION_QUIT,
68+
ACTION_EDIT_TODO,
69+
ACTION_SHOW_CURRENT_PATCH
70+
};
71+
72+
static const char *action_names[] = {
73+
"undefined",
74+
"continue",
75+
"skip",
76+
"abort",
77+
"quit",
78+
"edit_todo",
79+
"show_current_patch"
80+
};
81+
6282
struct rebase_options {
6383
enum rebase_type type;
6484
enum empty_type empty;
@@ -85,7 +105,7 @@ struct rebase_options {
85105
REBASE_INTERACTIVE_EXPLICIT = 1<<4,
86106
} flags;
87107
struct strvec git_am_opts;
88-
const char *action;
108+
enum action action;
89109
int signoff;
90110
int allow_rerere_autoupdate;
91111
int keep_empty;
@@ -157,24 +177,6 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)
157177
return replay;
158178
}
159179

160-
enum action {
161-
ACTION_NONE = 0,
162-
ACTION_CONTINUE,
163-
ACTION_SKIP,
164-
ACTION_ABORT,
165-
ACTION_QUIT,
166-
ACTION_EDIT_TODO,
167-
ACTION_SHOW_CURRENT_PATCH
168-
};
169-
170-
static const char *action_names[] = { "undefined",
171-
"continue",
172-
"skip",
173-
"abort",
174-
"quit",
175-
"edit_todo",
176-
"show_current_patch" };
177-
178180
static int edit_todo_file(unsigned flags)
179181
{
180182
const char *todo_file = rebase_path_todo();
@@ -311,8 +313,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
311313
return ret;
312314
}
313315

314-
static int run_sequencer_rebase(struct rebase_options *opts,
315-
enum action command)
316+
static int run_sequencer_rebase(struct rebase_options *opts)
316317
{
317318
unsigned flags = 0;
318319
int abbreviate_commands = 0, ret = 0;
@@ -327,7 +328,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,
327328
flags |= opts->reapply_cherry_picks ? TODO_LIST_REAPPLY_CHERRY_PICKS : 0;
328329
flags |= opts->flags & REBASE_NO_QUIET ? TODO_LIST_WARN_SKIPPED_CHERRY_PICKS : 0;
329330

330-
switch (command) {
331+
switch (opts->action) {
331332
case ACTION_NONE: {
332333
if (!opts->onto && !opts->upstream)
333334
die(_("a base commit must be provided with --upstream or --onto"));
@@ -360,7 +361,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,
360361
break;
361362
}
362363
default:
363-
BUG("invalid command '%d'", command);
364+
BUG("invalid command '%d'", opts->action);
364365
}
365366

366367
return ret;
@@ -583,10 +584,11 @@ static int move_to_original_branch(struct rebase_options *opts)
583584
if (!opts->onto)
584585
BUG("move_to_original_branch without onto");
585586

586-
strbuf_addf(&branch_reflog, "rebase finished: %s onto %s",
587+
strbuf_addf(&branch_reflog, "%s (finish): %s onto %s",
588+
getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
587589
opts->head_name, oid_to_hex(&opts->onto->object.oid));
588-
strbuf_addf(&head_reflog, "rebase finished: returning to %s",
589-
opts->head_name);
590+
strbuf_addf(&head_reflog, "%s (finish): returning to %s",
591+
getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);
590592
ropts.branch = opts->head_name;
591593
ropts.flags = RESET_HEAD_REFS_ONLY;
592594
ropts.branch_msg = branch_reflog.buf;
@@ -615,8 +617,9 @@ static int run_am(struct rebase_options *opts)
615617

616618
am.git_cmd = 1;
617619
strvec_push(&am.args, "am");
618-
619-
if (opts->action && !strcmp("continue", opts->action)) {
620+
strvec_pushf(&am.env, GIT_REFLOG_ACTION_ENVIRONMENT "=%s (pick)",
621+
getenv(GIT_REFLOG_ACTION_ENVIRONMENT));
622+
if (opts->action == ACTION_CONTINUE) {
620623
strvec_push(&am.args, "--resolved");
621624
strvec_pushf(&am.args, "--resolvemsg=%s", resolvemsg);
622625
if (opts->gpg_sign_opt)
@@ -627,7 +630,7 @@ static int run_am(struct rebase_options *opts)
627630

628631
return move_to_original_branch(opts);
629632
}
630-
if (opts->action && !strcmp("skip", opts->action)) {
633+
if (opts->action == ACTION_SKIP) {
631634
strvec_push(&am.args, "--skip");
632635
strvec_pushf(&am.args, "--resolvemsg=%s", resolvemsg);
633636
status = run_command(&am);
@@ -636,7 +639,7 @@ static int run_am(struct rebase_options *opts)
636639

637640
return move_to_original_branch(opts);
638641
}
639-
if (opts->action && !strcmp("show-current-patch", opts->action)) {
642+
if (opts->action == ACTION_SHOW_CURRENT_PATCH) {
640643
strvec_push(&am.args, "--show-current-patch");
641644
return run_command(&am);
642645
}
@@ -729,7 +732,7 @@ static int run_am(struct rebase_options *opts)
729732
return status;
730733
}
731734

732-
static int run_specific_rebase(struct rebase_options *opts, enum action action)
735+
static int run_specific_rebase(struct rebase_options *opts)
733736
{
734737
int status;
735738

@@ -747,7 +750,7 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)
747750
opts->gpg_sign_opt = tmp;
748751
}
749752

750-
status = run_sequencer_rebase(opts, action);
753+
status = run_sequencer_rebase(opts);
751754
} else if (opts->type == REBASE_APPLY)
752755
status = run_am(opts);
753756
else
@@ -1005,23 +1008,6 @@ static void NORETURN error_on_missing_default_upstream(void)
10051008
exit(1);
10061009
}
10071010

1008-
static void set_reflog_action(struct rebase_options *options)
1009-
{
1010-
const char *env;
1011-
struct strbuf buf = STRBUF_INIT;
1012-
1013-
if (!is_merge(options))
1014-
return;
1015-
1016-
env = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
1017-
if (env && strcmp("rebase", env))
1018-
return; /* only override it if it is "rebase" */
1019-
1020-
strbuf_addf(&buf, "rebase (%s)", options->action);
1021-
setenv(GIT_REFLOG_ACTION_ENVIRONMENT, buf.buf, 1);
1022-
strbuf_release(&buf);
1023-
}
1024-
10251011
static int check_exec_cmd(const char *cmd)
10261012
{
10271013
if (strchr(cmd, '\n'))
@@ -1046,7 +1032,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
10461032
struct strbuf buf = STRBUF_INIT;
10471033
struct object_id branch_base;
10481034
int ignore_whitespace = 0;
1049-
enum action action = ACTION_NONE;
10501035
const char *gpg_sign = NULL;
10511036
struct string_list exec = STRING_LIST_INIT_NODUP;
10521037
const char *rebase_merges = NULL;
@@ -1095,18 +1080,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
10951080
OPT_BIT(0, "no-ff", &options.flags,
10961081
N_("cherry-pick all commits, even if unchanged"),
10971082
REBASE_FORCE),
1098-
OPT_CMDMODE(0, "continue", &action, N_("continue"),
1083+
OPT_CMDMODE(0, "continue", &options.action, N_("continue"),
10991084
ACTION_CONTINUE),
1100-
OPT_CMDMODE(0, "skip", &action,
1085+
OPT_CMDMODE(0, "skip", &options.action,
11011086
N_("skip current patch and continue"), ACTION_SKIP),
1102-
OPT_CMDMODE(0, "abort", &action,
1087+
OPT_CMDMODE(0, "abort", &options.action,
11031088
N_("abort and check out the original branch"),
11041089
ACTION_ABORT),
1105-
OPT_CMDMODE(0, "quit", &action,
1090+
OPT_CMDMODE(0, "quit", &options.action,
11061091
N_("abort but keep HEAD where it is"), ACTION_QUIT),
1107-
OPT_CMDMODE(0, "edit-todo", &action, N_("edit the todo list "
1092+
OPT_CMDMODE(0, "edit-todo", &options.action, N_("edit the todo list "
11081093
"during an interactive rebase"), ACTION_EDIT_TODO),
1109-
OPT_CMDMODE(0, "show-current-patch", &action,
1094+
OPT_CMDMODE(0, "show-current-patch", &options.action,
11101095
N_("show the patch file being applied or merged"),
11111096
ACTION_SHOW_CURRENT_PATCH),
11121097
OPT_CALLBACK_F(0, "apply", &options, NULL,
@@ -1198,7 +1183,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
11981183
} else if (is_directory(merge_dir())) {
11991184
strbuf_reset(&buf);
12001185
strbuf_addf(&buf, "%s/rewritten", merge_dir());
1201-
if (!(action == ACTION_ABORT) && is_directory(buf.buf)) {
1186+
if (!(options.action == ACTION_ABORT) && is_directory(buf.buf)) {
12021187
die(_("`rebase --preserve-merges` (-p) is no longer supported.\n"
12031188
"Use `git rebase --abort` to terminate current rebase.\n"
12041189
"Or downgrade to v2.33, or earlier, to complete the rebase."));
@@ -1225,7 +1210,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
12251210
"Note: Your `pull.rebase` configuration may also be set to 'preserve',\n"
12261211
"which is no longer supported; use 'merges' instead"));
12271212

1228-
if (action != ACTION_NONE && total_argc != 2) {
1213+
if (options.action != ACTION_NONE && total_argc != 2) {
12291214
usage_with_options(builtin_rebase_usage,
12301215
builtin_rebase_options);
12311216
}
@@ -1256,11 +1241,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
12561241
if (options.root && options.fork_point > 0)
12571242
die(_("options '%s' and '%s' cannot be used together"), "--root", "--fork-point");
12581243

1259-
if (action != ACTION_NONE && !in_progress)
1244+
if (options.action != ACTION_NONE && !in_progress)
12601245
die(_("No rebase in progress?"));
12611246
setenv(GIT_REFLOG_ACTION_ENVIRONMENT, "rebase", 0);
12621247

1263-
if (action == ACTION_EDIT_TODO && !is_merge(&options))
1248+
if (options.action == ACTION_EDIT_TODO && !is_merge(&options))
12641249
die(_("The --edit-todo action can only be used during "
12651250
"interactive rebase."));
12661251

@@ -1270,18 +1255,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
12701255
else if (exec.nr)
12711256
trace2_cmd_mode("interactive-exec");
12721257
else
1273-
trace2_cmd_mode(action_names[action]);
1258+
trace2_cmd_mode(action_names[options.action]);
12741259
}
12751260

1276-
switch (action) {
1261+
switch (options.action) {
12771262
case ACTION_CONTINUE: {
12781263
struct object_id head;
12791264
struct lock_file lock_file = LOCK_INIT;
12801265
int fd;
12811266

1282-
options.action = "continue";
1283-
set_reflog_action(&options);
1284-
12851267
/* Sanity check */
12861268
if (get_oid("HEAD", &head))
12871269
die(_("Cannot read HEAD"));
@@ -1307,9 +1289,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
13071289
case ACTION_SKIP: {
13081290
struct string_list merge_rr = STRING_LIST_INIT_DUP;
13091291

1310-
options.action = "skip";
1311-
set_reflog_action(&options);
1312-
13131292
rerere_clear(the_repository, &merge_rr);
13141293
string_list_clear(&merge_rr, 1);
13151294
ropts.flags = RESET_HEAD_HARD;
@@ -1322,18 +1301,22 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
13221301
}
13231302
case ACTION_ABORT: {
13241303
struct string_list merge_rr = STRING_LIST_INIT_DUP;
1325-
options.action = "abort";
1326-
set_reflog_action(&options);
1304+
struct strbuf head_msg = STRBUF_INIT;
13271305

13281306
rerere_clear(the_repository, &merge_rr);
13291307
string_list_clear(&merge_rr, 1);
13301308

13311309
if (read_basic_state(&options))
13321310
exit(1);
1311+
1312+
strbuf_addf(&head_msg, "%s (abort): returning to %s",
1313+
getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
1314+
options.head_name ? options.head_name
1315+
: oid_to_hex(&options.orig_head->object.oid));
13331316
ropts.oid = &options.orig_head->object.oid;
1317+
ropts.head_msg = head_msg.buf;
13341318
ropts.branch = options.head_name;
13351319
ropts.flags = RESET_HEAD_HARD;
1336-
ropts.default_reflog_action = DEFAULT_REFLOG_ACTION;
13371320
if (reset_head(the_repository, &ropts) < 0)
13381321
die(_("could not move back to %s"),
13391322
oid_to_hex(&options.orig_head->object.oid));
@@ -1359,17 +1342,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
13591342
goto cleanup;
13601343
}
13611344
case ACTION_EDIT_TODO:
1362-
options.action = "edit-todo";
13631345
options.dont_finish_rebase = 1;
13641346
goto run_rebase;
13651347
case ACTION_SHOW_CURRENT_PATCH:
1366-
options.action = "show-current-patch";
13671348
options.dont_finish_rebase = 1;
13681349
goto run_rebase;
13691350
case ACTION_NONE:
13701351
break;
13711352
default:
1372-
BUG("action: %d", action);
1353+
BUG("action: %d", options.action);
13731354
}
13741355

13751356
/* Make sure no rebase is in progress */
@@ -1393,7 +1374,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
13931374
}
13941375

13951376
if ((options.flags & REBASE_INTERACTIVE_EXPLICIT) ||
1396-
(action != ACTION_NONE) ||
1377+
(options.action != ACTION_NONE) ||
13971378
(exec.nr > 0) ||
13981379
options.autosquash) {
13991380
allow_preemptive_ff = 0;
@@ -1804,7 +1785,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
18041785
printf(_("First, rewinding head to replay your work on top of "
18051786
"it...\n"));
18061787

1807-
strbuf_addf(&msg, "%s: checkout %s",
1788+
strbuf_addf(&msg, "%s (start): checkout %s",
18081789
getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);
18091790
ropts.oid = &options.onto->object.oid;
18101791
ropts.orig_head = &options.orig_head->object.oid,
@@ -1820,19 +1801,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
18201801
* If the onto is a proper descendant of the tip of the branch, then
18211802
* we just fast-forwarded.
18221803
*/
1823-
strbuf_reset(&msg);
18241804
if (oideq(&branch_base, &options.orig_head->object.oid)) {
18251805
printf(_("Fast-forwarded %s to %s.\n"),
18261806
branch_name, options.onto_name);
1827-
strbuf_addf(&msg, "rebase finished: %s onto %s",
1828-
options.head_name ? options.head_name : "detached HEAD",
1829-
oid_to_hex(&options.onto->object.oid));
1830-
memset(&ropts, 0, sizeof(ropts));
1831-
ropts.branch = options.head_name;
1832-
ropts.flags = RESET_HEAD_REFS_ONLY;
1833-
ropts.head_msg = msg.buf;
1834-
reset_head(the_repository, &ropts);
1835-
strbuf_release(&msg);
1807+
move_to_original_branch(&options);
18361808
ret = finish_rebase(&options);
18371809
goto cleanup;
18381810
}
@@ -1847,7 +1819,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
18471819
options.revisions = revisions.buf;
18481820

18491821
run_rebase:
1850-
ret = run_specific_rebase(&options, action);
1822+
ret = run_specific_rebase(&options);
18511823

18521824
cleanup:
18531825
strbuf_release(&buf);

sequencer.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5050,6 +5050,8 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)
50505050
if (read_populate_opts(opts))
50515051
return -1;
50525052
if (is_rebase_i(opts)) {
5053+
char *previous_reflog_action;
5054+
50535055
if ((res = read_populate_todo(r, &todo_list, opts)))
50545056
goto release_todo_list;
50555057

@@ -5060,10 +5062,13 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)
50605062
unlink(rebase_path_dropped());
50615063
}
50625064

5065+
previous_reflog_action = xstrdup(getenv(GIT_REFLOG_ACTION));
5066+
setenv(GIT_REFLOG_ACTION, reflog_message(opts, "continue", NULL), 1);
50635067
if (commit_staged_changes(r, opts, &todo_list)) {
50645068
res = -1;
50655069
goto release_todo_list;
50665070
}
5071+
setenv(GIT_REFLOG_ACTION, previous_reflog_action, 1);
50675072
} else if (!file_exists(get_todo_path(opts)))
50685073
return continue_single_pick(r, opts);
50695074
else if ((res = read_populate_todo(r, &todo_list, opts)))

0 commit comments

Comments
 (0)