Add a command "fixup" to rebase --interactive
The command is like "squash", except that it discards the commit message of the corresponding commit. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Acked-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Michael Haggerty committed
Dec 7, 2009 at 10:20 UTC
0205e72f088322a70a77643a7cd2d8b23ee07e14
4 files changed
+77
-18
Documentation/git-rebase.txt
+8
-5
@@ -382,9 +382,12 @@ If you just want to edit the commit message for a commit, replace the
382
command "pick" with the command "reword".
383
384
If you want to fold two or more commits into one, replace the command
385
-"pick" with "squash" for the second and subsequent commit. If the
386
-commits had different authors, it will attribute the squashed commit to
387
-the author of the first commit.
385
+"pick" for the second and subsequent commits with "squash" or "fixup".
386
+If the commits had different authors, the folded commit will be
387
+attributed to the author of the first commit. The suggested commit
388
+message for the folded commit is the concatenation of the commit
389
+messages of the first commit and of those with the "squash" command,
390
+but omits the commit messages of commits with the "fixup" command.
391
392
'git-rebase' will stop when "pick" has been replaced with "edit" or
393
when a command fails due to merge errors. When you are done editing
@@ -512,8 +515,8 @@ Easy case: The changes are literally the same.::
515
Hard case: The changes are not the same.::
516
517
This happens if the 'subsystem' rebase had conflicts, or used
515
- `\--interactive` to omit, edit, or squash commits; or if the
516
- upstream used one of `commit \--amend`, `reset`, or
518
+ `\--interactive` to omit, edit, squash, or fixup commits; or
519
+ if the upstream used one of `commit \--amend`, `reset`, or
520
`filter-branch`.
521
522
git-rebase--interactive.sh
+35
-10
@@ -302,7 +302,10 @@ nth_string () {
302
303
make_squash_message () {
304
if test -f "$SQUASH_MSG"; then
305
- COUNT=$(($(sed -n "s/^# This is [^0-9]*\([1-9][0-9]*\).*/\1/p" \
305
+ # We want to be careful about matching only the commit
306
+ # message comment lines generated by this function.
307
+ # "[snrt][tdh]" matches the nth_string endings.
308
+ COUNT=$(($(sed -n "s/^# Th[^0-9]*\([1-9][0-9]*\)[snrt][tdh] commit message.*:/\1/p" \
309
< "$SQUASH_MSG" | sed -ne '$p')+1))
310
echo "# This is a combination of $COUNT commits."
311
sed -e 1d -e '2,/^./{
@@ -315,10 +318,23 @@ make_squash_message () {
318
echo
319
git cat-file commit HEAD | sed -e '1,/^$/d'
320
fi
318
- echo
319
- echo "# This is the $(nth_string $COUNT) commit message:"
320
- echo
321
- git cat-file commit $1 | sed -e '1,/^$/d'
321
+ case $1 in
322
+ squash)
323
+ echo
324
+ echo "# This is the $(nth_string $COUNT) commit message:"
325
+ echo
326
+ git cat-file commit $2 | sed -e '1,/^$/d'
327
+ ;;
328
+ fixup)
329
+ echo
330
+ echo "# The $(nth_string $COUNT) commit message will be skipped:"
331
+ echo
332
+ # Comment the lines of the commit message out using
333
+ # "# " rather than "# " to make them less likely to
334
+ # confuse the sed regexp above.
335
+ git cat-file commit $2 | sed -e '1,/^$/d' -e 's/^/# /'
336
+ ;;
337
+ esac
338
}
339
340
peek_next_command () {
@@ -367,20 +383,28 @@ do_next () {
383
warn
384
exit 0
385
;;
370
- squash|s)
371
- comment_for_reflog squash
386
+ squash|s|fixup|f)
387
+ case "$command" in
388
+ squash|s)
389
+ squash_style=squash
390
+ ;;
391
+ fixup|f)
392
+ squash_style=fixup
393
+ ;;
394
+ esac
395
+ comment_for_reflog $squash_style
396
397
test -f "$DONE" && has_action "$DONE" ||
374
- die "Cannot 'squash' without a previous commit"
398
+ die "Cannot '$squash_style' without a previous commit"
399
400
mark_action_done
377
- make_squash_message $sha1 > "$MSG"
401
+ make_squash_message $squash_style $sha1 > "$MSG"
402
failed=f
403
author_script=$(get_author_ident_from_commit HEAD)
404
output git reset --soft HEAD^
405
pick_one -n $sha1 || failed=t
406
case "$(peek_next_command)" in
383
- squash|s)
407
+ squash|s|fixup|f)
408
USE_OUTPUT=output
409
MSG_OPT=-F
410
EDIT_OR_FILE="$MSG"
@@ -768,6 +792,7 @@ first and then run 'git rebase --continue' again."
792
# r, reword = use commit, but edit the commit message
793
# e, edit = use commit, but stop for amending
794
# s, squash = use commit, but meld into previous commit
795
+# f, fixup = like "squash", but discard this commit's log message
796
#
797
# If you remove a line here THAT COMMIT WILL BE LOST.
798
# However, if you remove everything, the rebase will be aborted.
t/lib-rebase.sh
+4
-3
@@ -9,8 +9,9 @@
9
#
10
# "[<lineno1>] [<lineno2>]..."
11
#
12
-# If a line number is prefixed with "squash", "edit", or "reword", the
13
-# respective line's command will be replaced with the specified one.
12
+# If a line number is prefixed with "squash", "fixup", "edit", or
13
+# "reword", the respective line's command will be replaced with the
14
+# specified one.
15
16
set_fake_editor () {
17
echo "#!$SHELL_PATH" >fake-editor.sh
@@ -32,7 +33,7 @@ cat "$1".tmp
33
action=pick
34
for line in $FAKE_LINES; do
35
case $line in
35
- squash|edit|reword)
36
+ squash|fixup|edit|reword)
37
action="$line";;
38
*)
39
echo sed -n "${line}s/^pick/$action/p"
t/t3404-rebase-interactive.sh
+30
@@ -235,6 +235,36 @@ test_expect_success 'multi-squash only fires up editor once' '
235
test 1 = $(git show | grep ONCE | wc -l)
236
'
237
238
+test_expect_success 'multi-fixup only fires up editor once' '
239
+ git checkout -b multi-fixup E &&
240
+ base=$(git rev-parse HEAD~4) &&
241
+ FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 fixup 2 fixup 3 fixup 4" \
242
+ git rebase -i $base &&
243
+ test $base = $(git rev-parse HEAD^) &&
244
+ test 1 = $(git show | grep ONCE | wc -l) &&
245
+ git checkout to-be-rebased &&
246
+ git branch -D multi-fixup
247
+'
248
+
249
+cat > expect-squash-fixup << EOF
250
+B
251
+
252
+D
253
+
254
+ONCE
255
+EOF
256
+
257
+test_expect_success 'squash and fixup generate correct log messages' '
258
+ git checkout -b squash-fixup E &&
259
+ base=$(git rev-parse HEAD~4) &&
260
+ FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 fixup 2 squash 3 fixup 4" \
261
+ git rebase -i $base &&
262
+ git cat-file commit HEAD | sed -e 1,/^\$/d > actual-squash-fixup &&
263
+ test_cmp expect-squash-fixup actual-squash-fixup &&
264
+ git checkout to-be-rebased &&
265
+ git branch -D squash-fixup
266
+'
267
+
268
test_expect_success 'squash works as expected' '
269
for n in one two three four
270
do