Browse Source

Merge branch 'ns/rebase-auto-squash'

* ns/rebase-auto-squash:
  rebase -i --autosquash: auto-squash commits

Conflicts:
	git-rebase--interactive.sh
maint
Junio C Hamano 15 years ago
parent
commit
cea20f2473
  1. 10
      Documentation/git-rebase.txt
  2. 37
      git-rebase--interactive.sh
  3. 73
      t/t3415-rebase-autosquash.sh

10
Documentation/git-rebase.txt

@ -308,6 +308,16 @@ which makes little sense. @@ -308,6 +308,16 @@ which makes little sense.
root commits will be rewritten to have <newbase> as parent
instead.

--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 quashing come 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 '--interactive' option is used.

include::merge-strategies.txt[]

NOTES

37
git-rebase--interactive.sh

@ -28,6 +28,7 @@ abort abort rebasing process and restore original branch @@ -28,6 +28,7 @@ abort abort rebasing process and restore original branch
skip skip current patch and continue rebasing process
no-verify override pre-rebase hook from stopping the operation
root rebase all reachable commmits up to the root(s)
autosquash move commits that begin with squash!/fixup! under -i
"

. git-sh-setup
@ -46,6 +47,7 @@ ONTO= @@ -46,6 +47,7 @@ ONTO=
VERBOSE=
OK_TO_SKIP_PRE_REBASE=
REBASE_ROOT=
AUTOSQUASH=

GIT_CHERRY_PICK_HELP=" After resolving the conflicts,
mark the corrected paths with 'git add <paths>', and
@ -519,6 +521,37 @@ get_saved_options () { @@ -519,6 +521,37 @@ get_saved_options () {
test -f "$DOTEST"/rebase-root && REBASE_ROOT=t
}

# Rearrange the todo list that has both "pick sha1 msg" and
# "pick sha1 fixup!/squash! msg" appears in it so that the latter
# 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"
test -s "$1.sq" || return

used=
while read pick sha1 message
do
case " $used" in
*" $sha1 "*) continue ;;
esac
echo "$pick $sha1 $message"
while read squash action msg
do
case "$message" in
"$msg"*)
echo "$action $squash $action! $msg"
used="$used$squash "
;;
esac
done <"$1.sq"
done >"$1.rearranged" <"$1"
cat "$1.rearranged" >"$1"
rm -f "$1.sq" "$1.rearranged"
}

LF='
'
parse_onto () {
@ -643,6 +676,9 @@ first and then run 'git rebase --continue' again." @@ -643,6 +676,9 @@ first and then run 'git rebase --continue' again."
--root)
REBASE_ROOT=t
;;
--autosquash)
AUTOSQUASH=t
;;
--onto)
shift
ONTO=$(parse_onto "$1") ||
@ -802,6 +838,7 @@ first and then run 'git rebase --continue' again." @@ -802,6 +838,7 @@ first and then run 'git rebase --continue' again."
fi

test -s "$TODO" || echo noop >> "$TODO"
test -n "$AUTOSQUASH" && rearrange_squash "$TODO"
cat >> "$TODO" << EOF

# Rebase $SHORTREVISIONS onto $SHORTONTO

73
t/t3415-rebase-autosquash.sh

@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
#!/bin/sh

test_description='auto squash'

. ./test-lib.sh

test_expect_success setup '
echo 0 >file0 &&
git add . &&
test_tick &&
git commit -m "initial commit" &&
echo 0 >file1 &&
echo 2 >file2 &&
git add . &&
test_tick &&
git commit -m "first commit" &&
echo 3 >file3 &&
git add . &&
test_tick &&
git commit -m "second commit" &&
git tag base
'

test_expect_success 'auto fixup' '
git reset --hard base &&
echo 1 >file1 &&
git add -u &&
test_tick &&
git commit -m "fixup! first"

git tag final-fixup &&
test_tick &&
git rebase --autosquash -i HEAD^^^ &&
git log --oneline >actual &&
test 3 = $(wc -l <actual) &&
git diff --exit-code final-fixup &&
test 1 = "$(git cat-file blob HEAD^:file1)" &&
test 1 = $(git cat-file commit HEAD^ | grep first | wc -l)
'

test_expect_success 'auto squash' '
git reset --hard base &&
echo 1 >file1 &&
git add -u &&
test_tick &&
git commit -m "squash! first"

git tag final-squash &&
test_tick &&
git rebase --autosquash -i HEAD^^^ &&
git log --oneline >actual &&
test 3 = $(wc -l <actual) &&
git diff --exit-code final-squash &&
test 1 = "$(git cat-file blob HEAD^:file1)" &&
test 2 = $(git cat-file commit HEAD^ | grep first | wc -l)
'

test_expect_success 'misspelled auto squash' '
git reset --hard base &&
echo 1 >file1 &&
git add -u &&
test_tick &&
git commit -m "squash! forst"
git tag final-missquash &&
test_tick &&
git rebase --autosquash -i HEAD^^^ &&
git log --oneline >actual &&
test 4 = $(wc -l <actual) &&
git diff --exit-code final-missquash &&
test 0 = $(git rev-list final-missquash...HEAD | wc -l)
'

test_done
Loading…
Cancel
Save