From: Andrew Pimlott <andrew@pimlott.net>
To: Andrew Pimlott <andrew@pimlott.net>
Cc: Junio C Hamano <gitster@pobox.com>,
Thomas Rast <trast@inf.ethz.ch>, git <git@vger.kernel.org>
Subject: Re: [PATCH] rebase -i: fixup fixup! fixup!
Date: Thu, 27 Jun 2013 12:26:31 -0700 [thread overview]
Message-ID: <1372359783-sup-4507@pimlott.net> (raw)
In-Reply-To: <1372291877-sup-8201@pimlott.net>
Excerpts from Andrew Pimlott's message of Wed Jun 26 17:20:32 -0700 2013:
> Excerpts from Junio C Hamano's message of Wed Jun 26 16:48:57 -0700 2013:
> > Andrew Pimlott <andrew@pimlott.net> writes:
> > > In order to test this, I wrote a helper function to dump the rebase -i
> > > todo list. Would you like this introduced in its own patch, or
> > > combined? See below.
> >
> > Depends on how involved the addition of the tests that actually use
> > the helper, but in general it would be a good idea to add it in the
> > first patch that actually uses it. Unused code added in a separate
> > patch will not point at that patch when bisecting, if that unused
> > code was broken from the beginning (not that I see anything
> > immediately broken in the code the following adds).
>
> Ok, here is the complete commit, incorporating all feedback.
Updated for recommended here-doc style.
Andrew
---8<---
Subject: [PATCH] rebase -i: handle fixup! fixup! in --autosquash
In rebase -i --autosquash, ignore all "fixup! " or "squash! " after the
first. This supports the case when a git commit --fixup/--squash referred
to an earlier fixup/squash instead of the original commit (whether
intentionally, as when the user expressly meant to note that the commit
fixes an earlier fixup; or inadvertently, as when the user meant to refer to
the original commit with :/msg; or out of laziness, as when the user could
remember how to refer to the fixup but not the original).
In the todo list, the full commit message is preserved, in case it provides
useful cues to the user. A test helper set_cat_todo_editor is introduced to
check this.
Helped-by: Thomas Rast <trast@inf.ethz.ch>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Andrew Pimlott <andrew@pimlott.net>
---
Documentation/git-rebase.txt | 4 ++-
git-rebase--interactive.sh | 25 ++++++++++++++----
t/lib-rebase.sh | 14 +++++++++++
t/t3415-rebase-autosquash.sh | 57 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 94 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index c84854a..6b2e1c8 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -389,7 +389,9 @@ squash/fixup series.
the same ..., automatically modify the todo list of rebase -i
so that the commit marked for squashing comes right after the
commit to be modified, and change the action of the moved
- commit from `pick` to `squash` (or `fixup`).
+ commit from `pick` to `squash` (or `fixup`). Ignores subsequent
+ "fixup! " or "squash! " after the first, in case you referred to an
+ earlier fixup/squash with `git commit --fixup/--squash`.
+
This option is only valid when the '--interactive' option is used.
+
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index f953d8d..169e876 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -689,8 +689,22 @@ rearrange_squash () {
case "$message" in
"squash! "*|"fixup! "*)
action="${message%%!*}"
- rest="${message#*! }"
- echo "$sha1 $action $rest"
+ rest=$message
+ prefix=
+ # skip all squash! or fixup! (but save for later)
+ while :
+ do
+ case "$rest" in
+ "squash! "*|"fixup! "*)
+ prefix="$prefix${rest%%!*},"
+ rest="${rest#*! }"
+ ;;
+ *)
+ break
+ ;;
+ esac
+ done
+ echo "$sha1 $action $prefix $rest"
# if it's a single word, try to resolve to a full sha1 and
# emit a second copy. This allows us to match on both message
# and on sha1 prefix
@@ -699,7 +713,7 @@ rearrange_squash () {
if test -n "$fullsha"; then
# prefix the action to uniquely identify this line as
# intended for full sha1 match
- echo "$sha1 +$action $fullsha"
+ echo "$sha1 +$action $prefix $fullsha"
fi
fi
esac
@@ -714,7 +728,7 @@ rearrange_squash () {
esac
printf '%s\n' "$pick $sha1 $message"
used="$used$sha1 "
- while read -r squash action msg_content
+ while read -r squash action msg_prefix msg_content
do
case " $used" in
*" $squash "*) continue ;;
@@ -730,7 +744,8 @@ rearrange_squash () {
case "$message" in "$msg_content"*) emit=1;; esac ;;
esac
if test $emit = 1; then
- printf '%s\n' "$action $squash $action! $msg_content"
+ real_prefix=$(echo "$msg_prefix" | sed "s/,/! /g")
+ printf '%s\n' "$action $squash ${real_prefix}$msg_content"
used="$used$squash "
fi
done <"$1.sq"
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 4b74ae4..cfd3409 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -66,6 +66,20 @@ EOF
chmod a+x fake-editor.sh
}
+# After set_cat_todo_editor, rebase -i will write the todo list (ignoring
+# blank lines and comments) to stdout, and exit failure (so you should run
+# it with test_must_fail). This can be used to verify the expected user
+# experience, for todo list changes that do not affect the outcome of
+# rebase; or as an extra check in addition to checking the outcome.
+
+set_cat_todo_editor () {
+ write_script fake-editor.sh <<-\EOF
+ grep "^[^#]" "$1"
+ exit 1
+ EOF
+ test_set_editor "$(pwd)/fake-editor.sh"
+}
+
# checks that the revisions in "$2" represent a linear range with the
# subjects in "$1"
test_linear_range () {
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index a1e86c4..7c989f9 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -4,6 +4,8 @@ test_description='auto squash'
. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
test_expect_success setup '
echo 0 >file0 &&
git add . &&
@@ -193,4 +195,59 @@ test_expect_success 'use commit --squash' '
test_auto_commit_flags squash 2
'
+test_auto_fixup_fixup () {
+ git reset --hard base &&
+ echo 1 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "$1! first" &&
+ echo 2 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "$1! $2! first" &&
+ git tag "final-$1-$2" &&
+ test_tick &&
+ (
+ set_cat_todo_editor &&
+ test_must_fail git rebase --autosquash -i HEAD^^^^ >actual &&
+ cat >expected <<EOF
+pick $(git rev-parse --short HEAD^^^) first commit
+$1 $(git rev-parse --short HEAD^) $1! first
+$1 $(git rev-parse --short HEAD) $1! $2! first
+pick $(git rev-parse --short HEAD^^) second commit
+EOF
+ test_cmp expected actual
+ ) &&
+ git rebase --autosquash -i HEAD^^^^ &&
+ git log --oneline >actual &&
+ test_line_count = 3 actual
+ git diff --exit-code "final-$1-$2" &&
+ test 2 = "$(git cat-file blob HEAD^:file1)" &&
+ if test "$1" = "fixup"
+ then
+ test 1 = $(git cat-file commit HEAD^ | grep first | wc -l)
+ elif test "$1" = "squash"
+ then
+ test 3 = $(git cat-file commit HEAD^ | grep first | wc -l)
+ else
+ false
+ fi
+}
+
+test_expect_success 'fixup! fixup!' '
+ test_auto_fixup_fixup fixup fixup
+'
+
+test_expect_success 'fixup! squash!' '
+ test_auto_fixup_fixup fixup squash
+'
+
+test_expect_success 'squash! squash!' '
+ test_auto_fixup_fixup squash squash
+'
+
+test_expect_success 'squash! fixup!' '
+ test_auto_fixup_fixup squash fixup
+'
+
test_done
--
1.7.10.4
next prev parent reply other threads:[~2013-06-27 19:26 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-11 18:05 rebase --autosquash does not handle fixup! of fixup! Andrew Pimlott
2013-06-11 18:50 ` Thomas Rast
2013-06-14 19:31 ` [PATCH] rebase -i: fixup fixup! fixup! Andrew Pimlott
2013-06-15 6:50 ` Andrew Pimlott
2013-06-15 10:07 ` Junio C Hamano
2013-06-16 1:19 ` Junio C Hamano
2013-06-16 11:08 ` Thomas Rast
2013-06-17 2:38 ` Junio C Hamano
2013-06-17 8:07 ` Thomas Rast
2013-06-17 14:27 ` Junio C Hamano
2013-06-25 20:41 ` Andrew Pimlott
2013-06-25 21:33 ` Junio C Hamano
2013-06-25 23:17 ` Andrew Pimlott
2013-06-25 21:36 ` Junio C Hamano
2013-06-25 21:45 ` Junio C Hamano
2013-06-25 22:01 ` Junio C Hamano
2013-06-25 23:03 ` Andrew Pimlott
2013-06-26 22:00 ` Andrew Pimlott
2013-06-26 23:48 ` Junio C Hamano
2013-06-27 0:20 ` Andrew Pimlott
2013-06-27 19:26 ` Andrew Pimlott [this message]
2013-06-27 20:52 ` Junio C Hamano
2013-06-28 14:20 ` Andrew Pimlott
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1372359783-sup-4507@pimlott.net \
--to=andrew@pimlott.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=trast@inf.ethz.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).