rebase -i: For fixup commands without squashes, do not start editor
If the "rebase -i" commands include a series of fixup commands without any squash commands, then commit the combined commit using the commit message of the corresponding "pick" without starting up the commit-message editor. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Michael Haggerty committed
Jan 14, 2010 at 06:54 UTC
a25eb13909088f04f87acec26c522cc555f6b4a9
2 files changed
+57
-31
git-rebase--interactive.sh
+54
-27
@@ -65,6 +65,13 @@ MSG="$DOTEST"/message
65
# updated. It is deleted just before the combined commit is made.
66
SQUASH_MSG="$DOTEST"/message-squash
67
68
+# If the current series of squash/fixups has not yet included a squash
69
+# command, then this file exists and holds the commit message of the
70
+# original "pick" commit. (If the series ends without a "squash"
71
+# command, then this can be used as the commit message of the combined
72
+# commit without opening the editor.)
73
+FIXUP_MSG="$DOTEST"/message-fixup
74
+
75
# $REWRITTEN is the name of a directory containing files for each
76
# commit that is reachable by at least one merge base of $HEAD and
77
# $UPSTREAM. They are not necessarily rewritten, but their children
@@ -358,7 +365,7 @@ nth_string () {
365
esac
366
}
367
361
-update_squash_message () {
368
+update_squash_messages () {
369
if test -f "$SQUASH_MSG"; then
370
mv "$SQUASH_MSG" "$SQUASH_MSG".bak || exit
371
COUNT=$(($(sed -n \
@@ -371,16 +378,18 @@ update_squash_message () {
378
}' <"$SQUASH_MSG".bak
379
} >$SQUASH_MSG
380
else
381
+ commit_message HEAD > "$FIXUP_MSG" || die "Cannot write $FIXUP_MSG"
382
COUNT=2
383
{
384
echo "# This is a combination of 2 commits."
385
echo "# The first commit's message is:"
386
echo
379
- commit_message HEAD
387
+ cat "$FIXUP_MSG"
388
} >$SQUASH_MSG
389
fi
390
case $1 in
391
squash)
392
+ rm -f "$FIXUP_MSG"
393
echo
394
echo "# This is the $(nth_string $COUNT) commit message:"
395
echo
@@ -455,7 +464,7 @@ do_next () {
464
die "Cannot '$squash_style' without a previous commit"
465
466
mark_action_done
458
- update_squash_message $squash_style $sha1
467
+ update_squash_messages $squash_style $sha1
468
failed=f
469
author_script=$(get_author_ident_from_commit HEAD)
470
echo "$author_script" > "$AUTHOR_SCRIPT"
@@ -464,34 +473,52 @@ do_next () {
473
pick_one -n $sha1 || failed=t
474
case "$(peek_next_command)" in
475
squash|s|fixup|f)
467
- USE_OUTPUT=output
468
- cp "$SQUASH_MSG" "$MSG" || exit
469
- MSG_OPT=-F
470
- EDIT_OR_FILE="$MSG"
476
+ # This is an intermediate commit; its message will only be
477
+ # used in case of trouble. So use the long version:
478
+ if test $failed = f
479
+ then
480
+ do_with_author output git commit --no-verify -F "$SQUASH_MSG" ||
481
+ failed=t
482
+ fi
483
+ if test $failed = t
484
+ then
485
+ cp "$SQUASH_MSG" "$MSG" || exit
486
+ # After any kind of hiccup, prevent committing without
487
+ # opening the commit message editor:
488
+ rm -f "$FIXUP_MSG"
489
+ cp "$MSG" "$GIT_DIR"/MERGE_MSG || exit
490
+ warn
491
+ warn "Could not apply $sha1... $rest"
492
+ die_with_patch $sha1 ""
493
+ fi
494
;;
495
*)
473
- USE_OUTPUT=
474
- MSG_OPT=
475
- EDIT_OR_FILE=-e
476
- cp "$SQUASH_MSG" "$MSG" || exit
477
- mv "$SQUASH_MSG" "$GIT_DIR"/SQUASH_MSG || exit
478
- rm -f "$GIT_DIR"/MERGE_MSG || exit
496
+ # This is the final command of this squash/fixup group
497
+ if test $failed = f
498
+ then
499
+ if test -f "$FIXUP_MSG"
500
+ then
501
+ do_with_author git commit --no-verify -F "$FIXUP_MSG" ||
502
+ failed=t
503
+ else
504
+ cp "$SQUASH_MSG" "$GIT_DIR"/SQUASH_MSG || exit
505
+ rm -f "$GIT_DIR"/MERGE_MSG
506
+ do_with_author git commit --no-verify -e ||
507
+ failed=t
508
+ fi
509
+ fi
510
+ rm -f "$FIXUP_MSG"
511
+ if test $failed = t
512
+ then
513
+ mv "$SQUASH_MSG" "$MSG" || exit
514
+ cp "$MSG" "$GIT_DIR"/MERGE_MSG || exit
515
+ warn
516
+ warn "Could not apply $sha1... $rest"
517
+ die_with_patch $sha1 ""
518
+ fi
519
+ rm -f "$SQUASH_MSG"
520
;;
521
esac
481
- if test $failed = f
482
- then
483
- # This is like --amend, but with a different message
484
- do_with_author $USE_OUTPUT git commit --no-verify \
485
- $MSG_OPT "$EDIT_OR_FILE" ||
486
- failed=t
487
- fi
488
- if test $failed = t
489
- then
490
- cp "$MSG" "$GIT_DIR"/MERGE_MSG
491
- warn
492
- warn "Could not apply $sha1... $rest"
493
- die_with_patch $sha1 ""
494
- fi
522
;;
523
*)
524
warn "Unknown command: $command $sha1 $rest"
t/t3404-rebase-interactive.sh
+3
-4
@@ -237,14 +237,13 @@ test_expect_success 'multi-squash only fires up editor once' '
237
test 1 = $(git show | grep ONCE | wc -l)
238
'
239
240
-test_expect_success 'multi-fixup only fires up editor once' '
240
+test_expect_success 'multi-fixup does not fire up editor' '
241
git checkout -b multi-fixup E &&
242
base=$(git rev-parse HEAD~4) &&
243
- FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 fixup 2 fixup 3 fixup 4" \
244
- EXPECT_HEADER_COUNT=4 \
243
+ FAKE_COMMIT_AMEND="NEVER" FAKE_LINES="1 fixup 2 fixup 3 fixup 4" \
244
git rebase -i $base &&
245
test $base = $(git rev-parse HEAD^) &&
247
- test 1 = $(git show | grep ONCE | wc -l) &&
246
+ test 0 = $(git show | grep NEVER | wc -l) &&
247
git checkout to-be-rebased &&
248
git branch -D multi-fixup
249
'