Skip to content

Commit 8fe9c3f

Browse files
committed
Merge branch 'en/rebase-merge-on-sequencer'
"git rebase --merge" as been reimplemented by reusing the internal machinery used for "git rebase -i". * en/rebase-merge-on-sequencer: rebase: implement --merge via the interactive machinery rebase: define linearization ordering and enforce it git-legacy-rebase: simplify unnecessary triply-nested if git-rebase, sequencer: extend --quiet option for the interactive machinery am, rebase--merge: do not overlook --skip'ed commits with post-rewrite t5407: add a test demonstrating how interactive handles --skip differently rebase: fix incompatible options error message rebase: make builtin and legacy script error messages the same
2 parents 8feddda + 68aa495 commit 8fe9c3f

17 files changed

+121
-340
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@
125125
/git-rebase--am
126126
/git-rebase--common
127127
/git-rebase--interactive
128-
/git-rebase--merge
129128
/git-rebase--preserve-merges
130129
/git-receive-pack
131130
/git-reflog

Documentation/git-rebase.txt

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -515,31 +515,20 @@ See also INCOMPATIBLE OPTIONS below.
515515
INCOMPATIBLE OPTIONS
516516
--------------------
517517

518-
git-rebase has many flags that are incompatible with each other,
519-
predominantly due to the fact that it has three different underlying
520-
implementations:
521-
522-
* one based on linkgit:git-am[1] (the default)
523-
* one based on git-merge-recursive (merge backend)
524-
* one based on linkgit:git-cherry-pick[1] (interactive backend)
525-
526-
Flags only understood by the am backend:
518+
The following options:
527519

528520
* --committer-date-is-author-date
529521
* --ignore-date
530522
* --whitespace
531523
* --ignore-whitespace
532524
* -C
533525

534-
Flags understood by both merge and interactive backends:
526+
are incompatible with the following options:
535527

536528
* --merge
537529
* --strategy
538530
* --strategy-option
539531
* --allow-empty-message
540-
541-
Flags only understood by the interactive backend:
542-
543532
* --[no-]autosquash
544533
* --rebase-merges
545534
* --preserve-merges
@@ -550,7 +539,7 @@ Flags only understood by the interactive backend:
550539
* --edit-todo
551540
* --root when used in combination with --onto
552541

553-
Other incompatible flag pairs:
542+
In addition, the following pairs of options are incompatible:
554543

555544
* --preserve-merges and --interactive
556545
* --preserve-merges and --signoff

Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,6 @@ SCRIPT_LIB += git-parse-remote
634634
SCRIPT_LIB += git-rebase--am
635635
SCRIPT_LIB += git-rebase--common
636636
SCRIPT_LIB += git-rebase--preserve-merges
637-
SCRIPT_LIB += git-rebase--merge
638637
SCRIPT_LIB += git-sh-setup
639638
SCRIPT_LIB += git-sh-i18n
640639

builtin/am.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,6 +2000,15 @@ static void am_skip(struct am_state *state)
20002000
if (clean_index(&head, &head))
20012001
die(_("failed to clean index"));
20022002

2003+
if (state->rebasing) {
2004+
FILE *fp = xfopen(am_path(state, "rewritten"), "a");
2005+
2006+
assert(!is_null_oid(&state->orig_commit));
2007+
fprintf(fp, "%s ", oid_to_hex(&state->orig_commit));
2008+
fprintf(fp, "%s\n", oid_to_hex(&head));
2009+
fclose(fp);
2010+
}
2011+
20032012
am_next(state);
20042013
am_load(state);
20052014
am_run(state, 0);

builtin/rebase.c

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ static void imply_interactive(struct rebase_options *opts, const char *option)
123123
case REBASE_PRESERVE_MERGES:
124124
break;
125125
case REBASE_MERGE:
126-
/* we silently *upgrade* --merge to --interactive if needed */
126+
/* we now implement --merge via --interactive */
127127
default:
128128
opts->type = REBASE_INTERACTIVE; /* implied */
129129
break;
@@ -186,10 +186,7 @@ static int read_basic_state(struct rebase_options *opts)
186186
if (get_oid(buf.buf, &opts->orig_head))
187187
return error(_("invalid orig-head: '%s'"), buf.buf);
188188

189-
strbuf_reset(&buf);
190-
if (read_one(state_dir_path("quiet", opts), &buf))
191-
return -1;
192-
if (buf.len)
189+
if (file_exists(state_dir_path("quiet", opts)))
193190
opts->flags &= ~REBASE_NO_QUIET;
194191
else
195192
opts->flags |= REBASE_NO_QUIET;
@@ -488,10 +485,6 @@ static int run_specific_rebase(struct rebase_options *opts)
488485
backend = "git-rebase--am";
489486
backend_func = "git_rebase__am";
490487
break;
491-
case REBASE_MERGE:
492-
backend = "git-rebase--merge";
493-
backend_func = "git_rebase__merge";
494-
break;
495488
case REBASE_PRESERVE_MERGES:
496489
backend = "git-rebase--preserve-merges";
497490
backend_func = "git_rebase__preserve_merges";
@@ -1233,6 +1226,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
12331226
}
12341227
}
12351228

1229+
if (options.type == REBASE_MERGE)
1230+
imply_interactive(&options, "--merge");
1231+
12361232
if (options.root && !options.onto_name)
12371233
imply_interactive(&options, "--root without --onto");
12381234

@@ -1265,14 +1261,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
12651261
break;
12661262

12671263
if (is_interactive(&options) && i >= 0)
1268-
die(_("error: cannot combine interactive options "
1269-
"(--interactive, --exec, --rebase-merges, "
1270-
"--preserve-merges, --keep-empty, --root + "
1271-
"--onto) with am options (%s)"), buf.buf);
1272-
if (options.type == REBASE_MERGE && i >= 0)
1273-
die(_("error: cannot combine merge options (--merge, "
1274-
"--strategy, --strategy-option) with am options "
1275-
"(%s)"), buf.buf);
1264+
die(_("cannot combine am options with either "
1265+
"interactive or merge options"));
12761266
}
12771267

12781268
if (options.signoff) {
@@ -1290,7 +1280,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
12901280
* git-rebase.txt caveats with "unless you know what you are doing"
12911281
*/
12921282
if (options.rebase_merges)
1293-
die(_("error: cannot combine '--preserve-merges' with "
1283+
die(_("cannot combine '--preserve-merges' with "
12941284
"'--rebase-merges'"));
12951285

12961286
if (options.reschedule_failed_exec)
@@ -1300,10 +1290,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
13001290

13011291
if (options.rebase_merges) {
13021292
if (strategy_options.nr)
1303-
die(_("error: cannot combine '--rebase-merges' with "
1293+
die(_("cannot combine '--rebase-merges' with "
13041294
"'--strategy-option'"));
13051295
if (options.strategy)
1306-
die(_("error: cannot combine '--rebase-merges' with "
1296+
die(_("cannot combine '--rebase-merges' with "
13071297
"'--strategy'"));
13081298
}
13091299

git-legacy-rebase.sh

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ read_basic_state () {
118118
else
119119
orig_head=$(cat "$state_dir"/head)
120120
fi &&
121-
GIT_QUIET=$(cat "$state_dir"/quiet) &&
121+
test -f "$state_dir"/quiet && GIT_QUIET=t
122122
test -f "$state_dir"/verbose && verbose=t
123123
test -f "$state_dir"/strategy && strategy="$(cat "$state_dir"/strategy)"
124124
test -f "$state_dir"/strategy_opts &&
@@ -226,17 +226,15 @@ then
226226
state_dir="$apply_dir"
227227
elif test -d "$merge_dir"
228228
then
229+
type=interactive
229230
if test -d "$merge_dir"/rewritten
230231
then
231232
type=preserve-merges
232233
interactive_rebase=explicit
233234
preserve_merges=t
234235
elif test -f "$merge_dir"/interactive
235236
then
236-
type=interactive
237237
interactive_rebase=explicit
238-
else
239-
type=merge
240238
fi
241239
state_dir="$merge_dir"
242240
fi
@@ -496,6 +494,7 @@ then
496494
test -z "$interactive_rebase" && interactive_rebase=implied
497495
fi
498496

497+
actually_interactive=
499498
if test -n "$interactive_rebase"
500499
then
501500
if test -z "$preserve_merges"
@@ -504,11 +503,12 @@ then
504503
else
505504
type=preserve-merges
506505
fi
507-
506+
actually_interactive=t
508507
state_dir="$merge_dir"
509508
elif test -n "$do_merge"
510509
then
511-
type=merge
510+
interactive_rebase=implied
511+
type=interactive
512512
state_dir="$merge_dir"
513513
else
514514
type=am
@@ -520,28 +520,20 @@ then
520520
git_format_patch_opt="$git_format_patch_opt --progress"
521521
fi
522522

523-
if test -n "$git_am_opt"; then
524-
incompatible_opts=$(echo " $git_am_opt " | \
525-
sed -e 's/ -q / /g' -e 's/^ \(.*\) $/\1/')
526-
if test -n "$interactive_rebase"
523+
incompatible_opts=$(echo " $git_am_opt " | \
524+
sed -e 's/ -q / /g' -e 's/^ \(.*\) $/\1/')
525+
if test -n "$incompatible_opts"
526+
then
527+
if test -n "$actually_interactive" || test "$do_merge"
527528
then
528-
if test -n "$incompatible_opts"
529-
then
530-
die "$(gettext "error: cannot combine interactive options (--interactive, --exec, --rebase-merges, --preserve-merges, --keep-empty, --root + --onto) with am options ($incompatible_opts)")"
531-
fi
532-
fi
533-
if test -n "$do_merge"; then
534-
if test -n "$incompatible_opts"
535-
then
536-
die "$(gettext "error: cannot combine merge options (--merge, --strategy, --strategy-option) with am options ($incompatible_opts)")"
537-
fi
529+
die "$(gettext "fatal: cannot combine am options with either interactive or merge options")"
538530
fi
539531
fi
540532

541533
if test -n "$signoff"
542534
then
543535
test -n "$preserve_merges" &&
544-
die "$(gettext "error: cannot combine '--signoff' with '--preserve-merges'")"
536+
die "$(gettext "fatal: cannot combine '--signoff' with '--preserve-merges'")"
545537
git_am_opt="$git_am_opt $signoff"
546538
force_rebase=t
547539
fi
@@ -552,7 +544,7 @@ then
552544
# Note: incompatibility with --interactive is just a strong warning;
553545
# git-rebase.txt caveats with "unless you know what you are doing"
554546
test -n "$rebase_merges" &&
555-
die "$(gettext "error: cannot combine '--preserve-merges' with '--rebase-merges'")"
547+
die "$(gettext "fatal: cannot combine '--preserve-merges' with '--rebase-merges'")"
556548

557549
test -n "$reschedule_failed_exec" &&
558550
die "$(gettext "error: cannot combine '--preserve-merges' with '--reschedule-failed-exec'")"
@@ -561,9 +553,9 @@ fi
561553
if test -n "$rebase_merges"
562554
then
563555
test -n "$strategy_opts" &&
564-
die "$(gettext "error: cannot combine '--rebase-merges' with '--strategy-option'")"
556+
die "$(gettext "fatal: cannot combine '--rebase-merges' with '--strategy-option'")"
565557
test -n "$strategy" &&
566-
die "$(gettext "error: cannot combine '--rebase-merges' with '--strategy'")"
558+
die "$(gettext "fatal: cannot combine '--rebase-merges' with '--strategy'")"
567559
fi
568560

569561
if test -z "$rebase_root"
@@ -702,7 +694,7 @@ require_clean_work_tree "rebase" "$(gettext "Please commit or stash them.")"
702694
# but this should be done only when upstream and onto are the same
703695
# and if this is not an interactive rebase.
704696
mb=$(git merge-base "$onto" "$orig_head")
705-
if test -z "$interactive_rebase" && test "$upstream" = "$onto" &&
697+
if test -z "$actually_interactive" && test "$upstream" = "$onto" &&
706698
test "$mb" = "$onto" && test -z "$restrict_revision" &&
707699
# linear history?
708700
! (git rev-list --parents "$onto".."$orig_head" | sane_grep " .* ") > /dev/null
@@ -752,6 +744,19 @@ then
752744
GIT_PAGER='' git diff --stat --summary "$mb_tree" "$onto"
753745
fi
754746

747+
if test -z "$actually_interactive" && test "$mb" = "$orig_head"
748+
then
749+
say "$(eval_gettext "Fast-forwarded \$branch_name to \$onto_name.")"
750+
GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name" \
751+
git checkout -q "$onto^0" || die "could not detach HEAD"
752+
# If the $onto is a proper descendant of the tip of the branch, then
753+
# we just fast-forwarded.
754+
git update-ref ORIG_HEAD $orig_head
755+
move_to_original_branch
756+
finish_rebase
757+
exit 0
758+
fi
759+
755760
test -n "$interactive_rebase" && run_specific_rebase
756761

757762
# Detach HEAD and reset the tree
@@ -761,16 +766,6 @@ GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name" \
761766
git checkout -q "$onto^0" || die "could not detach HEAD"
762767
git update-ref ORIG_HEAD $orig_head
763768

764-
# If the $onto is a proper descendant of the tip of the branch, then
765-
# we just fast-forwarded.
766-
if test "$mb" = "$orig_head"
767-
then
768-
say "$(eval_gettext "Fast-forwarded \$branch_name to \$onto_name.")"
769-
move_to_original_branch
770-
finish_rebase
771-
exit 0
772-
fi
773-
774769
if test -n "$rebase_root"
775770
then
776771
revisions="$onto..$orig_head"

git-rebase--am.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ rm -f "$GIT_DIR/rebased-patches"
3636

3737
git format-patch -k --stdout --full-index --cherry-pick --right-only \
3838
--src-prefix=a/ --dst-prefix=b/ --no-renames --no-cover-letter \
39-
--pretty=mboxrd \
39+
--pretty=mboxrd --topo-order \
4040
$git_format_patch_opt \
4141
"$revisions" ${restrict_revision+^$restrict_revision} \
4242
>"$GIT_DIR/rebased-patches"

git-rebase--common.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ write_basic_state () {
1010
echo "$head_name" > "$state_dir"/head-name &&
1111
echo "$onto" > "$state_dir"/onto &&
1212
echo "$orig_head" > "$state_dir"/orig-head &&
13-
echo "$GIT_QUIET" > "$state_dir"/quiet &&
13+
test t = "$GIT_QUIET" && : > "$state_dir"/quiet
1414
test t = "$verbose" && : > "$state_dir"/verbose
1515
test -n "$strategy" && echo "$strategy" > "$state_dir"/strategy
1616
test -n "$strategy_opts" && echo "$strategy_opts" > \

0 commit comments

Comments
 (0)