@matheusbsbs / matheus-bagliano / commits / 68d5d03bc4
Fork 0

rebase: teach --autosquash to match on sha1 in addition to message

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> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Kevin Ballard committed Nov 4, 2010 at 15:36 UTC 68d5d03bc49a073be3b0e14b22d30d70e7ae686d
2 files changed +64 -7
git-rebase--interactive.sh
+33 -7
@@ -675,9 +675,27 @@ get_saved_options () {
675 # comes immediately after the former, and change "pick" to
676 # "fixup"/"squash".
677 rearrange_squash () {
678 - sed -n -e 's/^pick \([0-9a-f]*\) \(squash\)! /\1 \2 /p' \
679 - -e 's/^pick \([0-9a-f]*\) \(fixup\)! /\1 \2 /p' \
680 - "$1" >"$1.sq"
678 + # extract fixup!/squash! lines and resolve any referenced sha1's
679 + while read -r pick sha1 message
680 + do
681 + case "$message" in
682 + "squash! "*|"fixup! "*)
683 + action="${message%%!*}"
684 + rest="${message#*! }"
685 + echo "$sha1 $action $rest"
686 + # if it's a single word, try to resolve to a full sha1 and
687 + # emit a second copy. This allows us to match on both message
688 + # and on sha1 prefix
689 + if test "${rest#* }" = "$rest"; then
690 + fullsha="$(git rev-parse -q --verify "$rest" 2>/dev/null)"
691 + if test -n "$fullsha"; then
692 + # prefix the action to uniquely identify this line as
693 + # intended for full sha1 match
694 + echo "$sha1 +$action $fullsha"
695 + fi
696 + fi
697 + esac
698 + done >"$1.sq" <"$1"
699 test -s "$1.sq" || return
700
701 used=
@@ -693,12 +711,20 @@ rearrange_squash () {
711 case " $used" in
712 *" $squash "*) continue ;;
713 esac
696 - case "$message" in
697 - "$msg"*)
714 + emit=0
715 + case "$action" in
716 + +*)
717 + action="${action#+}"
718 + # full sha1 prefix test
719 + case "$msg" in "$sha1"*) emit=1;; esac ;;
720 + *)
721 + # message prefix test
722 + case "$message" in "$msg"*) emit=1;; esac ;;
723 + esac
724 + if test $emit = 1; then
725 printf '%s\n' "$action $squash $action! $msg"
726 used="$used$squash "
700 - ;;
701 - esac
727 + fi
728 done <"$1.sq"
729 done >"$1.rearranged" <"$1"
730 cat "$1.rearranged" >"$1"
t/t3415-rebase-autosquash.sh
+31
@@ -136,5 +136,36 @@ test_expect_success 'auto squash that matches a commit after the squash' '
136 test 1 = $(git cat-file commit HEAD | grep third | wc -l) &&
137 test 1 = $(git cat-file commit HEAD^ | grep third | wc -l)
138 '
139 +test_expect_success 'auto squash that matches a sha1' '
140 + git reset --hard base &&
141 + echo 1 >file1 &&
142 + git add -u &&
143 + test_tick &&
144 + git commit -m "squash! $(git rev-parse --short HEAD^)" &&
145 + git tag final-shasquash &&
146 + test_tick &&
147 + git rebase --autosquash -i HEAD^^^ &&
148 + git log --oneline >actual &&
149 + test 3 = $(wc -l <actual) &&
150 + git diff --exit-code final-shasquash &&
151 + test 1 = "$(git cat-file blob HEAD^:file1)" &&
152 + test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)
153 +'
154 +
155 +test_expect_success 'auto squash that matches longer sha1' '
156 + git reset --hard base &&
157 + echo 1 >file1 &&
158 + git add -u &&
159 + test_tick &&
160 + git commit -m "squash! $(git rev-parse --short=11 HEAD^)" &&
161 + git tag final-longshasquash &&
162 + test_tick &&
163 + git rebase --autosquash -i HEAD^^^ &&
164 + git log --oneline >actual &&
165 + test 3 = $(wc -l <actual) &&
166 + git diff --exit-code final-longshasquash &&
167 + test 1 = "$(git cat-file blob HEAD^:file1)" &&
168 + test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)
169 +'
170
171 test_done