* [PATCH 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash
@ 2010-11-04 2:41 Kevin Ballard
2010-11-04 2:41 ` [PATCH 2/2] rebase: teach --autosquash to match on sha1 in addition to message Kevin Ballard
0 siblings, 1 reply; 13+ messages in thread
From: Kevin Ballard @ 2010-11-04 2:41 UTC (permalink / raw)
To: git; +Cc: Kevin Ballard
The current behvaior of --autosquash can duplicate fixup!/squash! lines
if they match multiple commits, and it can also apply them to commits
that come after them in the todo list. Even more oddly, a commit that
looks like "fixup! fixup!" will match itself and be duplicated in the
todo list.
Change the todo list rearranging to mark all commits as used as soon
as they are emitted, and to avoid emitting a fixup/squash commit if the
commit has already been marked as used.
Signed-off-by: Kevin Ballard <kevin@sb.org>
---
git-rebase--interactive.sh | 4 +++
t/t3415-rebase-autosquash.sh | 43 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 0 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index a27952d..379bbac 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -687,8 +687,12 @@ rearrange_squash () {
*" $sha1 "*) continue ;;
esac
printf '%s\n' "$pick $sha1 $message"
+ used="$used$sha1 "
while read -r squash action msg
do
+ case " $used" in
+ *" $squash "*) continue ;;
+ esac
case "$message" in
"$msg"*)
printf '%s\n' "$action $squash $action! $msg"
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index fd2184c..712bbe8 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -94,4 +94,47 @@ test_expect_success 'misspelled auto squash' '
test 0 = $(git rev-list final-missquash...HEAD | wc -l)
'
+test_expect_success 'auto squash that matches 2 commits' '
+ git reset --hard base &&
+ echo 4 >file4 &&
+ git add file4 &&
+ test_tick &&
+ git commit -m "first new commit" &&
+ echo 1 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "squash! first" &&
+ git tag final-multisquash &&
+ test_tick &&
+ git rebase --autosquash -i HEAD~4 &&
+ git log --oneline >actual &&
+ test 4 = $(wc -l <actual) &&
+ git diff --exit-code final-multisquash &&
+ test 1 = "$(git cat-file blob HEAD^^:file1)" &&
+ test 2 = $(git cat-file commit HEAD^^ | grep first | wc -l) &&
+ test 1 = $(git cat-file commit HEAD | grep first | wc -l)
+'
+
+test_expect_success 'auto squash that matches a commit after the squash' '
+ git reset --hard base &&
+ echo 1 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "squash! third" &&
+ echo 4 >file4 &&
+ git add file4 &&
+ test_tick &&
+ git commit -m "third commit" &&
+ git tag final-presquash &&
+ test_tick &&
+ git rebase --autosquash -i HEAD~4 &&
+ git log --oneline >actual &&
+ test 5 = $(wc -l <actual) &&
+ git diff --exit-code final-presquash &&
+ test 0 = "$(git cat-file blob HEAD^^:file1)" &&
+ test 1 = "$(git cat-file blob HEAD^:file1)" &&
+ test 1 = $(git cat-file commit HEAD | grep third | wc -l) &&
+ test 1 = $(git cat-file commit HEAD^ | grep third | wc -l)
+'
+
test_done
--
1.7.3.2.201.g24941.dirty
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/2] rebase: teach --autosquash to match on sha1 in addition to message
2010-11-04 2:41 [PATCH 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash Kevin Ballard
@ 2010-11-04 2:41 ` Kevin Ballard
2010-11-04 4:49 ` Kevin Ballard
2010-11-05 13:04 ` [PATCH " Peter Krefting
0 siblings, 2 replies; 13+ messages in thread
From: Kevin Ballard @ 2010-11-04 2:41 UTC (permalink / raw)
To: git; +Cc: Kevin Ballard
Support lines of the form "fixup! 7a235b" that specify an exact commit
in addition to the normal "squash! Old commit message" form.
Signed-off-by: Kevin Ballard <kevin@sb.org>
---
I chose 4 characters as the restriction because that's the minimum number
that `git rev-parse --short=<n>` will emit.
git-rebase--interactive.sh | 13 +++++++++----
t/t3415-rebase-autosquash.sh | 33 +++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 379bbac..9121bb6 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -693,12 +693,17 @@ rearrange_squash () {
case " $used" in
*" $squash "*) continue ;;
esac
- case "$message" in
- "$msg"*)
+ emit=0
+ case "$message" in "$msg"*) emit=1;; esac
+ if test $emit != 1; then
+ case "$sha1" in "$msg"*) emit=1;; esac
+ # ensure the message is at least 4 characters long
+ case "$msg" in ????*);; *) emit=0;; esac
+ fi
+ if test $emit = 1; then
printf '%s\n' "$action $squash $action! $msg"
used="$used$squash "
- ;;
- esac
+ fi
done <"$1.sq"
done >"$1.rearranged" <"$1"
cat "$1.rearranged" >"$1"
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index 712bbe8..14cdbeb 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -136,5 +136,38 @@ test_expect_success 'auto squash that matches a commit after the squash' '
test 1 = $(git cat-file commit HEAD | grep third | wc -l) &&
test 1 = $(git cat-file commit HEAD^ | grep third | wc -l)
'
+test_expect_success 'auto squash that matches a sha1' '
+ git reset --hard base &&
+ echo 1 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "squash! $(git rev-parse --short HEAD^)" &&
+ git tag final-shasquash &&
+ test_tick &&
+ git rebase --autosquash -i HEAD^^^ &&
+ git log --oneline >actual &&
+ test 3 = $(wc -l <actual) &&
+ git diff --exit-code final-shasquash &&
+ test 1 = "$(git cat-file blob HEAD^:file1)" &&
+ test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)
+'
+
+# this test just ensures that < 4 characters can't match a sha1
+test_expect_success 'auto squash that accidentally matches a sha1' '
+ git reset --hard base &&
+ echo 1 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "squash! $(git rev-parse HEAD^ | cut -c 1-3)" &&
+ git tag final-badshasquash &&
+ test_tick &&
+ git rebase --autosquash -i HEAD^^^ &&
+ git log --oneline >actual &&
+ test 4 = $(wc -l <actual) &&
+ git diff --exit-code final-badshasquash &&
+ test 0 = "$(git cat-file blob HEAD^^:file1)" &&
+ test 0 = $(git cat-file commit HEAD^^ | grep squash | wc -l) &&
+ test 1 = $(git cat-file commit HEAD | grep squash | wc -l)
+'
test_done
--
1.7.3.2.201.g24941.dirty
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] rebase: teach --autosquash to match on sha1 in addition to message
2010-11-04 2:41 ` [PATCH 2/2] rebase: teach --autosquash to match on sha1 in addition to message Kevin Ballard
@ 2010-11-04 4:49 ` Kevin Ballard
2010-11-04 10:44 ` Sverre Rabbelier
2010-11-04 19:09 ` Junio C Hamano
2010-11-05 13:04 ` [PATCH " Peter Krefting
1 sibling, 2 replies; 13+ messages in thread
From: Kevin Ballard @ 2010-11-04 4:49 UTC (permalink / raw)
To: Git mailing list
On Nov 3, 2010, at 7:41 PM, Kevin Ballard wrote:
> Support lines of the form "fixup! 7a235b" that specify an exact commit
> in addition to the normal "squash! Old commit message" form.
I just realized that this only works for sha1's of up to 7 characters.
If you provide more it won't match, as it's comparing against the sha1
given in the todo list. I wonder if it's worth resolving all sha1s to
their full length if the provided string is longer than 7 characters?
-Kevin Ballard
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] rebase: teach --autosquash to match on sha1 in addition to message
2010-11-04 4:49 ` Kevin Ballard
@ 2010-11-04 10:44 ` Sverre Rabbelier
2010-11-04 21:35 ` Kevin Ballard
2010-11-04 19:09 ` Junio C Hamano
1 sibling, 1 reply; 13+ messages in thread
From: Sverre Rabbelier @ 2010-11-04 10:44 UTC (permalink / raw)
To: Kevin Ballard; +Cc: Git mailing list
Heya,
On Thu, Nov 4, 2010 at 05:49, Kevin Ballard <kevin@sb.org> wrote:
> I just realized that this only works for sha1's of up to 7 characters.
> If you provide more it won't match, as it's comparing against the sha1
> given in the todo list. I wonder if it's worth resolving all sha1s to
> their full length if the provided string is longer than 7 characters?
Well, not if you're resolving them based on the 7-character string
from the rebase todo list. If you run in to ambiguity with those
7-length hash we should instead increase the length of the hashes in
the todo list.
So I'd say, solve this by doing a prefix match?
--
Cheers,
Sverre Rabbelier
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] rebase: teach --autosquash to match on sha1 in addition to message
2010-11-04 10:44 ` Sverre Rabbelier
@ 2010-11-04 21:35 ` Kevin Ballard
0 siblings, 0 replies; 13+ messages in thread
From: Kevin Ballard @ 2010-11-04 21:35 UTC (permalink / raw)
To: Sverre Rabbelier; +Cc: Git mailing list
On Nov 4, 2010, at 3:44 AM, Sverre Rabbelier wrote:
> On Thu, Nov 4, 2010 at 05:49, Kevin Ballard <kevin@sb.org> wrote:
>> I just realized that this only works for sha1's of up to 7 characters.
>> If you provide more it won't match, as it's comparing against the sha1
>> given in the todo list. I wonder if it's worth resolving all sha1s to
>> their full length if the provided string is longer than 7 characters?
>
> Well, not if you're resolving them based on the 7-character string
> from the rebase todo list. If you run in to ambiguity with those
> 7-length hash we should instead increase the length of the hashes in
> the todo list.
>
> So I'd say, solve this by doing a prefix match?
Prefix match of what against what? If the 7-character string used in the
TODO list is already ambiguous, then the rebase itself would be expected
to fail. I'm inclined to just try to resolve the message in the fixup!
line itself to a full SHA1, and if that works, then try to match the
7-character sha1 with a prefix comparison.
-Kevin Ballard
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] rebase: teach --autosquash to match on sha1 in addition to message
2010-11-04 4:49 ` Kevin Ballard
2010-11-04 10:44 ` Sverre Rabbelier
@ 2010-11-04 19:09 ` Junio C Hamano
2010-11-04 22:36 ` [PATCHv2 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash Kevin Ballard
2010-11-04 22:36 ` [PATCHv2 2/2] rebase: teach --autosquash to match on sha1 in addition to message Kevin Ballard
1 sibling, 2 replies; 13+ messages in thread
From: Junio C Hamano @ 2010-11-04 19:09 UTC (permalink / raw)
To: Kevin Ballard; +Cc: Git mailing list
Kevin Ballard <kevin@sb.org> writes:
> On Nov 3, 2010, at 7:41 PM, Kevin Ballard wrote:
>
>> Support lines of the form "fixup! 7a235b" that specify an exact commit
>> in addition to the normal "squash! Old commit message" form.
>
> I just realized that this only works for sha1's of up to 7 characters.
> If you provide more it won't match, as it's comparing against the sha1
> given in the todo list. I wonder if it's worth resolving all sha1s to
> their full length if the provided string is longer than 7 characters?
Yeah, this is a nice feature I sometimes missed ;-)
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCHv2 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash
2010-11-04 19:09 ` Junio C Hamano
@ 2010-11-04 22:36 ` Kevin Ballard
2010-11-04 22:36 ` [PATCHv2 2/2] rebase: teach --autosquash to match on sha1 in addition to message Kevin Ballard
1 sibling, 0 replies; 13+ messages in thread
From: Kevin Ballard @ 2010-11-04 22:36 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Sverre Rabbelier, Kevin Ballard
The current behvaior of --autosquash can duplicate fixup!/squash! lines
if they match multiple commits, and it can also apply them to commits
that come after them in the todo list. Even more oddly, a commit that
looks like "fixup! fixup!" will match itself and be duplicated in the
todo list.
Change the todo list rearranging to mark all commits as used as soon
as they are emitted, and to avoid emitting a fixup/squash commit if the
commit has already been marked as used.
Signed-off-by: Kevin Ballard <kevin@sb.org>
---
This patch is unchanged from the previous version.
git-rebase--interactive.sh | 4 +++
t/t3415-rebase-autosquash.sh | 43 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 0 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index a27952d..379bbac 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -687,8 +687,12 @@ rearrange_squash () {
*" $sha1 "*) continue ;;
esac
printf '%s\n' "$pick $sha1 $message"
+ used="$used$sha1 "
while read -r squash action msg
do
+ case " $used" in
+ *" $squash "*) continue ;;
+ esac
case "$message" in
"$msg"*)
printf '%s\n' "$action $squash $action! $msg"
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index fd2184c..712bbe8 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -94,4 +94,47 @@ test_expect_success 'misspelled auto squash' '
test 0 = $(git rev-list final-missquash...HEAD | wc -l)
'
+test_expect_success 'auto squash that matches 2 commits' '
+ git reset --hard base &&
+ echo 4 >file4 &&
+ git add file4 &&
+ test_tick &&
+ git commit -m "first new commit" &&
+ echo 1 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "squash! first" &&
+ git tag final-multisquash &&
+ test_tick &&
+ git rebase --autosquash -i HEAD~4 &&
+ git log --oneline >actual &&
+ test 4 = $(wc -l <actual) &&
+ git diff --exit-code final-multisquash &&
+ test 1 = "$(git cat-file blob HEAD^^:file1)" &&
+ test 2 = $(git cat-file commit HEAD^^ | grep first | wc -l) &&
+ test 1 = $(git cat-file commit HEAD | grep first | wc -l)
+'
+
+test_expect_success 'auto squash that matches a commit after the squash' '
+ git reset --hard base &&
+ echo 1 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "squash! third" &&
+ echo 4 >file4 &&
+ git add file4 &&
+ test_tick &&
+ git commit -m "third commit" &&
+ git tag final-presquash &&
+ test_tick &&
+ git rebase --autosquash -i HEAD~4 &&
+ git log --oneline >actual &&
+ test 5 = $(wc -l <actual) &&
+ git diff --exit-code final-presquash &&
+ test 0 = "$(git cat-file blob HEAD^^:file1)" &&
+ test 1 = "$(git cat-file blob HEAD^:file1)" &&
+ test 1 = $(git cat-file commit HEAD | grep third | wc -l) &&
+ test 1 = $(git cat-file commit HEAD^ | grep third | wc -l)
+'
+
test_done
--
1.7.3.2.202.g3b863.dirty
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCHv2 2/2] rebase: teach --autosquash to match on sha1 in addition to message
2010-11-04 19:09 ` Junio C Hamano
2010-11-04 22:36 ` [PATCHv2 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash Kevin Ballard
@ 2010-11-04 22:36 ` Kevin Ballard
1 sibling, 0 replies; 13+ messages in thread
From: Kevin Ballard @ 2010-11-04 22:36 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Sverre Rabbelier, Kevin Ballard
Support lines of the form "fixup! 7a235b" that specify an exact commit
in addition to the normal "squash! Old commit message" form.
Signed-off-by: Kevin Ballard <kevin@sb.org>
---
This version attempts to resolve all single-word fixup!/squash! messages to
full sha1s. It only tries this once per line and records the results in the
$TODO.sq file. The reasoning for the duplication of such lines is to allow
a line like
fixup! 8a23b5f 7a5436
to still prefix-match "7a5436" against commit messages in addition to matching
the fullly-resolved sha1 against the other sha1's.
git-rebase--interactive.sh | 40 +++++++++++++++++++++++++++++++++-------
t/t3415-rebase-autosquash.sh | 31 +++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+), 7 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 379bbac..c2383bf 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -675,9 +675,27 @@ get_saved_options () {
# comes immediately after the former, and change "pick" to
# "fixup"/"squash".
rearrange_squash () {
- sed -n -e 's/^pick \([0-9a-f]*\) \(squash\)! /\1 \2 /p' \
- -e 's/^pick \([0-9a-f]*\) \(fixup\)! /\1 \2 /p' \
- "$1" >"$1.sq"
+ # extract fixup!/squash! lines and resolve any referenced sha1's
+ while read -r pick sha1 message
+ do
+ case "$message" in
+ "squash! "*|"fixup! "*)
+ action="${message%%!*}"
+ rest="${message#*! }"
+ echo "$sha1 $action $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
+ if test "${rest#* }" = "$rest"; then
+ fullsha="$(git rev-parse -q --verify "$rest" 2>/dev/null)"
+ if test -n "$fullsha"; then
+ # prefix the action to uniquely identify this line as
+ # intended for full sha1 match
+ echo "$sha1 +$action $fullsha"
+ fi
+ fi
+ esac
+ done >"$1.sq" <"$1"
test -s "$1.sq" || return
used=
@@ -693,12 +711,20 @@ rearrange_squash () {
case " $used" in
*" $squash "*) continue ;;
esac
- case "$message" in
- "$msg"*)
+ emit=0
+ case "$action" in
+ +*)
+ action="${action#+}"
+ # full sha1 prefix test
+ case "$msg" in "$sha1"*) emit=1;; esac ;;
+ *)
+ # message prefix test
+ case "$message" in "$msg"*) emit=1;; esac ;;
+ esac
+ if test $emit = 1; then
printf '%s\n' "$action $squash $action! $msg"
used="$used$squash "
- ;;
- esac
+ fi
done <"$1.sq"
done >"$1.rearranged" <"$1"
cat "$1.rearranged" >"$1"
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index 712bbe8..ca16b70 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -136,5 +136,36 @@ test_expect_success 'auto squash that matches a commit after the squash' '
test 1 = $(git cat-file commit HEAD | grep third | wc -l) &&
test 1 = $(git cat-file commit HEAD^ | grep third | wc -l)
'
+test_expect_success 'auto squash that matches a sha1' '
+ git reset --hard base &&
+ echo 1 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "squash! $(git rev-parse --short HEAD^)" &&
+ git tag final-shasquash &&
+ test_tick &&
+ git rebase --autosquash -i HEAD^^^ &&
+ git log --oneline >actual &&
+ test 3 = $(wc -l <actual) &&
+ git diff --exit-code final-shasquash &&
+ test 1 = "$(git cat-file blob HEAD^:file1)" &&
+ test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)
+'
+
+test_expect_success 'auto squash that matches longer sha1' '
+ git reset --hard base &&
+ echo 1 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "squash! $(git rev-parse --short=11 HEAD^)" &&
+ git tag final-longshasquash &&
+ test_tick &&
+ git rebase --autosquash -i HEAD^^^ &&
+ git log --oneline >actual &&
+ test 3 = $(wc -l <actual) &&
+ git diff --exit-code final-longshasquash &&
+ test 1 = "$(git cat-file blob HEAD^:file1)" &&
+ test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)
+'
test_done
--
1.7.3.2.202.g3b863.dirty
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] rebase: teach --autosquash to match on sha1 in addition to message
2010-11-04 2:41 ` [PATCH 2/2] rebase: teach --autosquash to match on sha1 in addition to message Kevin Ballard
2010-11-04 4:49 ` Kevin Ballard
@ 2010-11-05 13:04 ` Peter Krefting
2010-11-08 10:48 ` [PATCHv3 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash Kevin Ballard
2010-11-08 10:48 ` [PATCHv3 2/2] rebase: teach --autosquash to match on sha1 in addition to message Kevin Ballard
1 sibling, 2 replies; 13+ messages in thread
From: Peter Krefting @ 2010-11-05 13:04 UTC (permalink / raw)
To: Kevin Ballard; +Cc: Git Mailing List
Kevin Ballard:
> Support lines of the form "fixup! 7a235b" that specify an exact commit
> in addition to the normal "squash! Old commit message" form.
The patch I posted for this in June (Message-Id:
<20100617125746.E86B42FC00@perkele>) also updated the manual page for
git-rebase. You may want to re-use parts of that.
http://www.spinics.net/lists/git/msg133571.html has an archived version of it.
--
\\// Peter - http://www.softwolves.pp.se/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCHv3 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash
2010-11-05 13:04 ` [PATCH " Peter Krefting
@ 2010-11-08 10:48 ` Kevin Ballard
2010-11-08 10:52 ` Yann Dirson
2010-11-08 10:48 ` [PATCHv3 2/2] rebase: teach --autosquash to match on sha1 in addition to message Kevin Ballard
1 sibling, 1 reply; 13+ messages in thread
From: Kevin Ballard @ 2010-11-08 10:48 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Sverre Rabbelier, Peter Krefting, Kevin Ballard
The current behvaior of --autosquash can duplicate fixup!/squash! lines
if they match multiple commits, and it can also apply them to commits
that come after them in the todo list. Even more oddly, a commit that
looks like "fixup! fixup!" will match itself and be duplicated in the
todo list.
Change the todo list rearranging to mark all commits as used as soon
as they are emitted, and to avoid emitting a fixup/squash commit if the
commit has already been marked as used.
Signed-off-by: Kevin Ballard <kevin@sb.org>
---
This patch is unchanged from v2.
git-rebase--interactive.sh | 4 +++
t/t3415-rebase-autosquash.sh | 43 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 0 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index e29fd91..56cfdb5 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -707,8 +707,12 @@ rearrange_squash () {
*" $sha1 "*) continue ;;
esac
printf '%s\n' "$pick $sha1 $message"
+ used="$used$sha1 "
while read -r squash action msg
do
+ case " $used" in
+ *" $squash "*) continue ;;
+ esac
case "$message" in
"$msg"*)
printf '%s\n' "$action $squash $action! $msg"
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index fd2184c..712bbe8 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -94,4 +94,47 @@ test_expect_success 'misspelled auto squash' '
test 0 = $(git rev-list final-missquash...HEAD | wc -l)
'
+test_expect_success 'auto squash that matches 2 commits' '
+ git reset --hard base &&
+ echo 4 >file4 &&
+ git add file4 &&
+ test_tick &&
+ git commit -m "first new commit" &&
+ echo 1 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "squash! first" &&
+ git tag final-multisquash &&
+ test_tick &&
+ git rebase --autosquash -i HEAD~4 &&
+ git log --oneline >actual &&
+ test 4 = $(wc -l <actual) &&
+ git diff --exit-code final-multisquash &&
+ test 1 = "$(git cat-file blob HEAD^^:file1)" &&
+ test 2 = $(git cat-file commit HEAD^^ | grep first | wc -l) &&
+ test 1 = $(git cat-file commit HEAD | grep first | wc -l)
+'
+
+test_expect_success 'auto squash that matches a commit after the squash' '
+ git reset --hard base &&
+ echo 1 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "squash! third" &&
+ echo 4 >file4 &&
+ git add file4 &&
+ test_tick &&
+ git commit -m "third commit" &&
+ git tag final-presquash &&
+ test_tick &&
+ git rebase --autosquash -i HEAD~4 &&
+ git log --oneline >actual &&
+ test 5 = $(wc -l <actual) &&
+ git diff --exit-code final-presquash &&
+ test 0 = "$(git cat-file blob HEAD^^:file1)" &&
+ test 1 = "$(git cat-file blob HEAD^:file1)" &&
+ test 1 = $(git cat-file commit HEAD | grep third | wc -l) &&
+ test 1 = $(git cat-file commit HEAD^ | grep third | wc -l)
+'
+
test_done
--
1.7.3.2.195.gc69dde
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCHv3 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash
2010-11-08 10:48 ` [PATCHv3 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash Kevin Ballard
@ 2010-11-08 10:52 ` Yann Dirson
2010-11-08 11:10 ` Kevin Ballard
0 siblings, 1 reply; 13+ messages in thread
From: Yann Dirson @ 2010-11-08 10:52 UTC (permalink / raw)
To: Kevin Ballard; +Cc: git
Kevin wrote:
>The current behvaior of --autosquash can duplicate fixup!/squash! lines
>if they match multiple commits, and it can also apply them to commits
>that come after them in the todo list.
That last part of the sentence does not match my experience - it looks
like you describe as a bug a nonexistent feature I miss :)
See http://marc.info/?l=git&m=128784082701920 for a testcase that
exhibits what I think is a problem.
--
Yann Dirson - Bertin Technologies
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCHv3 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash
2010-11-08 10:52 ` Yann Dirson
@ 2010-11-08 11:10 ` Kevin Ballard
0 siblings, 0 replies; 13+ messages in thread
From: Kevin Ballard @ 2010-11-08 11:10 UTC (permalink / raw)
To: Yann Dirson; +Cc: git
On Nov 8, 2010, at 2:52 AM, Yann Dirson wrote:
> Kevin wrote:
>> The current behvaior of --autosquash can duplicate fixup!/squash! lines
>> if they match multiple commits, and it can also apply them to commits
>> that come after them in the todo list.
>
> That last part of the sentence does not match my experience - it looks
> like you describe as a bug a nonexistent feature I miss :)
>
> See http://marc.info/?l=git&m=128784082701920 for a testcase that
> exhibits what I think is a problem.
The bug is definitely present. It seems what you're describing is that you
want it to continue to place that fixup! there, but you want it to skip the
pick line that occurs earlier in the TODO list. My feeling is that this is
purely a bug, and should be fixed to not place the fixup! line after the
later commit.
If you do want the behavior where it skips the pick and places the fixup!
line after the later commit, I would encourage you to file a separate patch
for that.
-Kevin Ballard
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCHv3 2/2] rebase: teach --autosquash to match on sha1 in addition to message
2010-11-05 13:04 ` [PATCH " Peter Krefting
2010-11-08 10:48 ` [PATCHv3 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash Kevin Ballard
@ 2010-11-08 10:48 ` Kevin Ballard
1 sibling, 0 replies; 13+ messages in thread
From: Kevin Ballard @ 2010-11-08 10:48 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Sverre Rabbelier, Peter Krefting, Kevin Ballard
Support lines of the form "fixup! 7a235b" that specify an exact commit
in addition to the normal "squash! Old commit message" form.
Signed-off-by: Kevin Ballard <kevin@sb.org>
---
The only change from v2 is I've added the manpage change from Peter Krefting's
previous patch on this subject (http://www.spinics.net/lists/git/msg133571.html),
as referenced in message id <alpine.DEB.2.00.1011051401090.7611@ds9.cixit.se>.
Documentation/git-rebase.txt | 8 ++++----
git-rebase--interactive.sh | 40 +++++++++++++++++++++++++++++++++-------
t/t3415-rebase-autosquash.sh | 31 +++++++++++++++++++++++++++++++
3 files changed, 68 insertions(+), 11 deletions(-)
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 30e5c0e..17f50cb 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -339,10 +339,10 @@ idea unless you know what you are doing (see BUGS below).
--no-autosquash::
When the commit log message begins with "squash! ..." (or
"fixup! ..."), and there is a commit whose title begins with
- 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`).
+ the same ..., or whose hash is ..., 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`).
+
This option is only valid when the '--interactive' option is used.
+
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 56cfdb5..31abbff 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -695,9 +695,27 @@ get_saved_options () {
# comes immediately after the former, and change "pick" to
# "fixup"/"squash".
rearrange_squash () {
- sed -n -e 's/^pick \([0-9a-f]*\) \(squash\)! /\1 \2 /p' \
- -e 's/^pick \([0-9a-f]*\) \(fixup\)! /\1 \2 /p' \
- "$1" >"$1.sq"
+ # extract fixup!/squash! lines and resolve any referenced sha1's
+ while read -r pick sha1 message
+ do
+ case "$message" in
+ "squash! "*|"fixup! "*)
+ action="${message%%!*}"
+ rest="${message#*! }"
+ echo "$sha1 $action $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
+ if test "${rest#* }" = "$rest"; then
+ fullsha="$(git rev-parse -q --verify "$rest" 2>/dev/null)"
+ if test -n "$fullsha"; then
+ # prefix the action to uniquely identify this line as
+ # intended for full sha1 match
+ echo "$sha1 +$action $fullsha"
+ fi
+ fi
+ esac
+ done >"$1.sq" <"$1"
test -s "$1.sq" || return
used=
@@ -713,12 +731,20 @@ rearrange_squash () {
case " $used" in
*" $squash "*) continue ;;
esac
- case "$message" in
- "$msg"*)
+ emit=0
+ case "$action" in
+ +*)
+ action="${action#+}"
+ # full sha1 prefix test
+ case "$msg" in "$sha1"*) emit=1;; esac ;;
+ *)
+ # message prefix test
+ case "$message" in "$msg"*) emit=1;; esac ;;
+ esac
+ if test $emit = 1; then
printf '%s\n' "$action $squash $action! $msg"
used="$used$squash "
- ;;
- esac
+ fi
done <"$1.sq"
done >"$1.rearranged" <"$1"
cat "$1.rearranged" >"$1"
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index 712bbe8..ca16b70 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -136,5 +136,36 @@ test_expect_success 'auto squash that matches a commit after the squash' '
test 1 = $(git cat-file commit HEAD | grep third | wc -l) &&
test 1 = $(git cat-file commit HEAD^ | grep third | wc -l)
'
+test_expect_success 'auto squash that matches a sha1' '
+ git reset --hard base &&
+ echo 1 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "squash! $(git rev-parse --short HEAD^)" &&
+ git tag final-shasquash &&
+ test_tick &&
+ git rebase --autosquash -i HEAD^^^ &&
+ git log --oneline >actual &&
+ test 3 = $(wc -l <actual) &&
+ git diff --exit-code final-shasquash &&
+ test 1 = "$(git cat-file blob HEAD^:file1)" &&
+ test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)
+'
+
+test_expect_success 'auto squash that matches longer sha1' '
+ git reset --hard base &&
+ echo 1 >file1 &&
+ git add -u &&
+ test_tick &&
+ git commit -m "squash! $(git rev-parse --short=11 HEAD^)" &&
+ git tag final-longshasquash &&
+ test_tick &&
+ git rebase --autosquash -i HEAD^^^ &&
+ git log --oneline >actual &&
+ test 3 = $(wc -l <actual) &&
+ git diff --exit-code final-longshasquash &&
+ test 1 = "$(git cat-file blob HEAD^:file1)" &&
+ test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)
+'
test_done
--
1.7.3.2.195.gc69dde
^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2010-11-08 11:10 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-04 2:41 [PATCH 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash Kevin Ballard
2010-11-04 2:41 ` [PATCH 2/2] rebase: teach --autosquash to match on sha1 in addition to message Kevin Ballard
2010-11-04 4:49 ` Kevin Ballard
2010-11-04 10:44 ` Sverre Rabbelier
2010-11-04 21:35 ` Kevin Ballard
2010-11-04 19:09 ` Junio C Hamano
2010-11-04 22:36 ` [PATCHv2 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash Kevin Ballard
2010-11-04 22:36 ` [PATCHv2 2/2] rebase: teach --autosquash to match on sha1 in addition to message Kevin Ballard
2010-11-05 13:04 ` [PATCH " Peter Krefting
2010-11-08 10:48 ` [PATCHv3 1/2] rebase: better rearranging of fixup!/squash! lines with --autosquash Kevin Ballard
2010-11-08 10:52 ` Yann Dirson
2010-11-08 11:10 ` Kevin Ballard
2010-11-08 10:48 ` [PATCHv3 2/2] rebase: teach --autosquash to match on sha1 in addition to message Kevin Ballard
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).