From 163f3925902446735b2f631dc44ab67882a93024 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Mon, 7 Dec 2009 05:22:58 +0100 Subject: t3404: Use test_commit to set up test repository Also adjust "expected" text to reflect the file contents generated by test_commit, which are slightly different than those generated by the old code. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- t/t3404-rebase-interactive.sh | 66 +++++++++++++------------------------------ 1 file changed, 20 insertions(+), 46 deletions(-) diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 3a37793c0..778daf419 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -16,53 +16,26 @@ set_fake_editor # set up two branches like this: # -# A - B - C - D - E +# A - B - C - D - E (master) # \ -# F - G - H +# F - G - H (branch1) # \ -# I +# I (branch2) # -# where B, D and G touch the same file. +# where A, B, D and G touch the same file. test_expect_success 'setup' ' - : > file1 && - git add file1 && - test_tick && - git commit -m A && - git tag A && - echo 1 > file1 && - test_tick && - git commit -m B file1 && - : > file2 && - git add file2 && - test_tick && - git commit -m C && - echo 2 > file1 && - test_tick && - git commit -m D file1 && - : > file3 && - git add file3 && - test_tick && - git commit -m E && + test_commit A file1 && + test_commit B file1 && + test_commit C file2 && + test_commit D file1 && + test_commit E file3 && git checkout -b branch1 A && - : > file4 && - git add file4 && - test_tick && - git commit -m F && - git tag F && - echo 3 > file1 && - test_tick && - git commit -m G file1 && - : > file5 && - git add file5 && - test_tick && - git commit -m H && + test_commit F file4 && + test_commit G file1 && + test_commit H file5 && git checkout -b branch2 F && - : > file6 && - git add file6 && - test_tick && - git commit -m I && - git tag I + test_commit I file6 ' test_expect_success 'no changes are a nop' ' @@ -111,19 +84,20 @@ test_expect_success 'exchange two commits' ' cat > expect << EOF diff --git a/file1 b/file1 -index e69de29..00750ed 100644 +index f70f10e..fd79235 100644 --- a/file1 +++ b/file1 -@@ -0,0 +1 @@ -+3 +@@ -1 +1 @@ +-A ++G EOF cat > expect2 << EOF <<<<<<< HEAD -2 +D ======= -3 ->>>>>>> b7ca976... G +G +>>>>>>> 91201e5... G EOF test_expect_success 'stop on conflicting pick' ' -- cgit v1.2.1 From 0205e72f088322a70a77643a7cd2d8b23ee07e14 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Mon, 7 Dec 2009 10:20:59 +0100 Subject: 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 Acked-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-rebase.txt | 13 ++++++++----- git-rebase--interactive.sh | 45 +++++++++++++++++++++++++++++++++---------- t/lib-rebase.sh | 7 ++++--- t/t3404-rebase-interactive.sh | 30 +++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 18 deletions(-) diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index ca5e1e865..9b648ece6 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -382,9 +382,12 @@ If you just want to edit the commit message for a commit, replace the command "pick" with the command "reword". If you want to fold two or more commits into one, replace the command -"pick" with "squash" for the second and subsequent commit. If the -commits had different authors, it will attribute the squashed commit to -the author of the first commit. +"pick" for the second and subsequent commits with "squash" or "fixup". +If the commits had different authors, the folded commit will be +attributed to the author of the first commit. The suggested commit +message for the folded commit is the concatenation of the commit +messages of the first commit and of those with the "squash" command, +but omits the commit messages of commits with the "fixup" command. 'git-rebase' will stop when "pick" has been replaced with "edit" or 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.:: Hard case: The changes are not the same.:: This happens if the 'subsystem' rebase had conflicts, or used - `\--interactive` to omit, edit, or squash commits; or if the - upstream used one of `commit \--amend`, `reset`, or + `\--interactive` to omit, edit, squash, or fixup commits; or + if the upstream used one of `commit \--amend`, `reset`, or `filter-branch`. diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 0bd3bf78b..30de96ee1 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -302,7 +302,10 @@ nth_string () { make_squash_message () { if test -f "$SQUASH_MSG"; then - COUNT=$(($(sed -n "s/^# This is [^0-9]*\([1-9][0-9]*\).*/\1/p" \ + # We want to be careful about matching only the commit + # message comment lines generated by this function. + # "[snrt][tdh]" matches the nth_string endings. + COUNT=$(($(sed -n "s/^# Th[^0-9]*\([1-9][0-9]*\)[snrt][tdh] commit message.*:/\1/p" \ < "$SQUASH_MSG" | sed -ne '$p')+1)) echo "# This is a combination of $COUNT commits." sed -e 1d -e '2,/^./{ @@ -315,10 +318,23 @@ make_squash_message () { echo git cat-file commit HEAD | sed -e '1,/^$/d' fi - echo - echo "# This is the $(nth_string $COUNT) commit message:" - echo - git cat-file commit $1 | sed -e '1,/^$/d' + case $1 in + squash) + echo + echo "# This is the $(nth_string $COUNT) commit message:" + echo + git cat-file commit $2 | sed -e '1,/^$/d' + ;; + fixup) + echo + echo "# The $(nth_string $COUNT) commit message will be skipped:" + echo + # Comment the lines of the commit message out using + # "# " rather than "# " to make them less likely to + # confuse the sed regexp above. + git cat-file commit $2 | sed -e '1,/^$/d' -e 's/^/# /' + ;; + esac } peek_next_command () { @@ -367,20 +383,28 @@ do_next () { warn exit 0 ;; - squash|s) - comment_for_reflog squash + squash|s|fixup|f) + case "$command" in + squash|s) + squash_style=squash + ;; + fixup|f) + squash_style=fixup + ;; + esac + comment_for_reflog $squash_style test -f "$DONE" && has_action "$DONE" || - die "Cannot 'squash' without a previous commit" + die "Cannot '$squash_style' without a previous commit" mark_action_done - make_squash_message $sha1 > "$MSG" + make_squash_message $squash_style $sha1 > "$MSG" failed=f author_script=$(get_author_ident_from_commit HEAD) output git reset --soft HEAD^ pick_one -n $sha1 || failed=t case "$(peek_next_command)" in - squash|s) + squash|s|fixup|f) USE_OUTPUT=output MSG_OPT=-F EDIT_OR_FILE="$MSG" @@ -768,6 +792,7 @@ first and then run 'git rebase --continue' again." # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit +# f, fixup = like "squash", but discard this commit's log message # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index 62f452c8e..f4dda02b5 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -9,8 +9,9 @@ # # "[] []..." # -# If a line number is prefixed with "squash", "edit", or "reword", the -# respective line's command will be replaced with the specified one. +# If a line number is prefixed with "squash", "fixup", "edit", or +# "reword", the respective line's command will be replaced with the +# specified one. set_fake_editor () { echo "#!$SHELL_PATH" >fake-editor.sh @@ -32,7 +33,7 @@ cat "$1".tmp action=pick for line in $FAKE_LINES; do case $line in - squash|edit|reword) + squash|fixup|edit|reword) action="$line";; *) echo sed -n "${line}s/^pick/$action/p" diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 778daf419..ea2611513 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -235,6 +235,36 @@ test_expect_success 'multi-squash only fires up editor once' ' test 1 = $(git show | grep ONCE | wc -l) ' +test_expect_success 'multi-fixup only fires up editor once' ' + git checkout -b multi-fixup E && + base=$(git rev-parse HEAD~4) && + FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 fixup 2 fixup 3 fixup 4" \ + git rebase -i $base && + test $base = $(git rev-parse HEAD^) && + test 1 = $(git show | grep ONCE | wc -l) && + git checkout to-be-rebased && + git branch -D multi-fixup +' + +cat > expect-squash-fixup << EOF +B + +D + +ONCE +EOF + +test_expect_success 'squash and fixup generate correct log messages' ' + git checkout -b squash-fixup E && + base=$(git rev-parse HEAD~4) && + FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 fixup 2 squash 3 fixup 4" \ + git rebase -i $base && + git cat-file commit HEAD | sed -e 1,/^\$/d > actual-squash-fixup && + test_cmp expect-squash-fixup actual-squash-fixup && + git checkout to-be-rebased && + git branch -D squash-fixup +' + test_expect_success 'squash works as expected' ' for n in one two three four do -- cgit v1.2.1 From f64b4856243a9ea9445068a0989c71a8915c3862 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Tue, 12 Jan 2010 16:38:34 +0100 Subject: lib-rebase: Provide clearer debugging info about what the editor did (For testing "rebase -i"): Output the "rebase -i" command script before and after the edits, to make it clearer what the editor did. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- t/lib-rebase.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index f4dda02b5..0fce5952c 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -29,6 +29,7 @@ test -z "$EXPECT_COUNT" || test -z "$FAKE_LINES" && exit grep -v '^#' < "$1" > "$1".tmp rm -f "$1" +echo 'rebase -i script before editing:' cat "$1".tmp action=pick for line in $FAKE_LINES; do @@ -36,12 +37,12 @@ for line in $FAKE_LINES; do squash|fixup|edit|reword) action="$line";; *) - echo sed -n "${line}s/^pick/$action/p" - sed -n "${line}p" < "$1".tmp sed -n "${line}s/^pick/$action/p" < "$1".tmp >> "$1" action=pick;; esac done +echo 'rebase -i script after editing:' +cat "$1" EOF test_set_editor "$(pwd)/fake-editor.sh" -- cgit v1.2.1 From 05c95dbe44b42f9c3f7efe6793d311a26e1b8181 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Tue, 12 Jan 2010 16:38:35 +0100 Subject: lib-rebase: Allow comments and blank lines to be added to the rebase script (For testing "rebase -i"): Support new action types in $FAKE_LINES to allow comments and blank lines to be added to the "rebase -i" command list. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- t/lib-rebase.sh | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index 0fce5952c..0db8250c5 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -5,13 +5,20 @@ # - override the commit message with $FAKE_COMMIT_MESSAGE, # - amend the commit message with $FAKE_COMMIT_AMEND # - check that non-commit messages have a certain line count with $EXPECT_COUNT -# - rewrite a rebase -i script with $FAKE_LINES in the form +# - rewrite a rebase -i script as directed by $FAKE_LINES. +# $FAKE_LINES consists of a sequence of words separated by spaces. +# The following word combinations are possible: # -# "[] []..." +# "" -- add a "pick" line with the SHA1 taken from the +# specified line. # -# If a line number is prefixed with "squash", "fixup", "edit", or -# "reword", the respective line's command will be replaced with the -# specified one. +# " " -- add a line with the specified command +# ("squash", "fixup", "edit", or "reword") and the SHA1 taken +# from the specified line. +# +# "#" -- Add a comment line. +# +# ">" -- Add a blank line. set_fake_editor () { echo "#!$SHELL_PATH" >fake-editor.sh @@ -36,6 +43,10 @@ for line in $FAKE_LINES; do case $line in squash|fixup|edit|reword) action="$line";; + "#") + echo '# comment' >> "$1";; + ">") + echo >> "$1";; *) sed -n "${line}s/^pick/$action/p" < "$1".tmp >> "$1" action=pick;; -- cgit v1.2.1 From 234b3dae2fe83ae7df2c82194cd5f5eb01fd166d Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Tue, 12 Jan 2010 16:38:36 +0100 Subject: rebase-i: Ignore comments and blank lines in peek_next_command Previously, blank lines and/or comments within a series of squash/fixup commands would confuse "git rebase -i" into thinking that the series was finished. It would therefore require the user to edit the commit message for the squash/fixup commits seen so far. Then, after continuing, it would ask the user to edit the commit message again. Ignore comments and blank lines within a group of squash/fixup commands, allowing them to be processed in one go. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- git-rebase--interactive.sh | 2 +- t/t3404-rebase-interactive.sh | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 30de96ee1..55c451ade 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -338,7 +338,7 @@ make_squash_message () { } peek_next_command () { - sed -n "1s/ .*$//p" < "$TODO" + sed -n -e "/^#/d" -e "/^$/d" -e "s/ .*//p" -e "q" < "$TODO" } do_next () { diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index ea2611513..d9382e41d 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -265,6 +265,30 @@ test_expect_success 'squash and fixup generate correct log messages' ' git branch -D squash-fixup ' +test_expect_success 'squash ignores comments' ' + git checkout -b skip-comments E && + base=$(git rev-parse HEAD~4) && + FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="# 1 # squash 2 # squash 3 # squash 4 #" \ + EXPECT_HEADER_COUNT=4 \ + git rebase -i $base && + test $base = $(git rev-parse HEAD^) && + test 1 = $(git show | grep ONCE | wc -l) && + git checkout to-be-rebased && + git branch -D skip-comments +' + +test_expect_success 'squash ignores blank lines' ' + git checkout -b skip-blank-lines E && + base=$(git rev-parse HEAD~4) && + FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="> 1 > squash 2 > squash 3 > squash 4 >" \ + EXPECT_HEADER_COUNT=4 \ + git rebase -i $base && + test $base = $(git rev-parse HEAD^) && + test 1 = $(git show | grep ONCE | wc -l) && + git checkout to-be-rebased && + git branch -D skip-blank-lines +' + test_expect_success 'squash works as expected' ' for n in one two three four do -- cgit v1.2.1