@matheusbsbs / matheus-bagliano / commits / 0205e72f08
Fork 0

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