t7505: add tests for cherry-pick and rebase -i/-p

Check that cherry-pick and rebase call the 'prepare-commit-msg' hook correctly. The expected values for the hook arguments are taken to match the current master branch. I think there is scope for improving the arguments passed so they make a bit more sense - for instance cherry-pick currently passes different arguments depending on whether the commit message is being edited. Also the arguments for rebase could be improved. Commit 7c4188360ac ("rebase -i: proper prepare-commit-msg hook argument when squashing", 2008-10-3) apparently changed things so that when squashing rebase would pass 'squash' as the argument to the hook but that has been lost. I think that it would make more sense to pass 'message' for revert and cherry-pick -x/-s (i.e. cases where there is a new message or the current message in modified by the command), 'squash' when squashing with a new message and 'commit HEAD/CHERRY_PICK_HEAD' otherwise (picking and squashing without a new message). Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Phillip Wood committed Jan 24, 2018 at 12:34 UTC 15cd6d3a259c3c6d8b16ffa4793505720db45e0c
3 files changed +157 -4
t/t7505-prepare-commit-msg-hook.sh
+122 -4
@@ -4,6 +4,38 @@ test_description='prepare-commit-msg hook'
4
5 . ./test-lib.sh
6
7 +test_expect_success 'set up commits for rebasing' '
8 + test_commit root &&
9 + test_commit a a a &&
10 + test_commit b b b &&
11 + git checkout -b rebase-me root &&
12 + test_commit rebase-a a aa &&
13 + test_commit rebase-b b bb &&
14 + for i in $(test_seq 1 13)
15 + do
16 + test_commit rebase-$i c $i
17 + done &&
18 + git checkout master &&
19 +
20 + cat >rebase-todo <<-EOF
21 + pick $(git rev-parse rebase-a)
22 + pick $(git rev-parse rebase-b)
23 + fixup $(git rev-parse rebase-1)
24 + fixup $(git rev-parse rebase-2)
25 + pick $(git rev-parse rebase-3)
26 + fixup $(git rev-parse rebase-4)
27 + squash $(git rev-parse rebase-5)
28 + reword $(git rev-parse rebase-6)
29 + squash $(git rev-parse rebase-7)
30 + fixup $(git rev-parse rebase-8)
31 + fixup $(git rev-parse rebase-9)
32 + edit $(git rev-parse rebase-10)
33 + squash $(git rev-parse rebase-11)
34 + squash $(git rev-parse rebase-12)
35 + edit $(git rev-parse rebase-13)
36 + EOF
37 +'
38 +
39 test_expect_success 'with no hook' '
40
41 echo "foo" > file &&
@@ -31,19 +63,41 @@ mkdir -p "$HOOKDIR"
63 echo "#!$SHELL_PATH" > "$HOOK"
64 cat >> "$HOOK" <<'EOF'
65
66 +GIT_DIR=$(git rev-parse --git-dir)
67 +if test -d "$GIT_DIR/rebase-merge"
68 +then
69 + rebasing=1
70 +else
71 + rebasing=0
72 +fi
73 +
74 +get_last_cmd () {
75 + tail -n1 "$GIT_DIR/rebase-merge/done" | {
76 + read cmd id _
77 + git log --pretty="[$cmd %s]" -n1 $id
78 + }
79 +}
80 +
81 if test "$2" = commit
82 then
36 - source=$(git rev-parse "$3")
83 + if test $rebasing = 1
84 + then
85 + source="$3"
86 + else
87 + source=$(git rev-parse "$3")
88 + fi
89 else
90 source=${2-default}
91 fi
40 -if test "$GIT_EDITOR" = :
92 +test "$GIT_EDITOR" = : && source="$source (no editor)"
93 +
94 +if test $rebasing = 1
95 then
42 - sed -e "1s/.*/$source (no editor)/" "$1" >msg.tmp
96 + echo "$source $(get_last_cmd)" >"$1"
97 else
98 sed -e "1s/.*/$source/" "$1" >msg.tmp
99 + mv msg.tmp "$1"
100 fi
46 -mv msg.tmp "$1"
101 exit 0
102 EOF
103 chmod +x "$HOOK"
@@ -158,6 +212,63 @@ test_expect_success 'with hook and editor (merge)' '
212 test "$(git log -1 --pretty=format:%s)" = "merge"
213 '
214
215 +test_rebase () {
216 + expect=$1 &&
217 + mode=$2 &&
218 + test_expect_$expect C_LOCALE_OUTPUT "with hook (rebase $mode)" '
219 + test_when_finished "\
220 + git rebase --abort
221 + git checkout -f master
222 + git branch -D tmp" &&
223 + git checkout -b tmp rebase-me &&
224 + GIT_SEQUENCE_EDITOR="cp rebase-todo" &&
225 + GIT_EDITOR="\"$FAKE_EDITOR\"" &&
226 + (
227 + export GIT_SEQUENCE_EDITOR GIT_EDITOR &&
228 + test_must_fail git rebase $mode b &&
229 + echo x >a &&
230 + git add a &&
231 + test_must_fail git rebase --continue &&
232 + echo x >b &&
233 + git add b &&
234 + git commit &&
235 + git rebase --continue &&
236 + echo y >a &&
237 + git add a &&
238 + git commit &&
239 + git rebase --continue &&
240 + echo y >b &&
241 + git add b &&
242 + git rebase --continue
243 + ) &&
244 + if test $mode = -p # reword amended after pick
245 + then
246 + n=18
247 + else
248 + n=17
249 + fi &&
250 + git log --pretty=%s -g -n$n HEAD@{1} >actual &&
251 + test_cmp "$TEST_DIRECTORY/t7505/expected-rebase$mode" actual
252 + '
253 +}
254 +
255 +test_rebase failure -i
256 +test_rebase failure -p
257 +
258 +test_expect_failure 'with hook (cherry-pick)' '
259 + test_when_finished "git checkout -f master" &&
260 + git checkout -B other b &&
261 + git cherry-pick rebase-1 &&
262 + test "$(git log -1 --pretty=format:%s)" = "message (no editor)"
263 +'
264 +
265 +test_expect_success 'with hook and editor (cherry-pick)' '
266 + test_when_finished "git checkout -f master" &&
267 + git checkout -B other b &&
268 + git cherry-pick -e rebase-1 &&
269 + test "$(git log -1 --pretty=format:%s)" = merge
270 +'
271 +
272 cat > "$HOOK" <<'EOF'
273 #!/bin/sh
274 exit 1
@@ -199,4 +310,11 @@ test_expect_success 'with failing hook (merge)' '
310
311 '
312
313 +test_expect_failure C_LOCALE_OUTPUT 'with failing hook (cherry-pick)' '
314 + test_when_finished "git checkout -f master" &&
315 + git checkout -B other b &&
316 + test_must_fail git cherry-pick rebase-1 2>actual &&
317 + test $(grep -c prepare-commit-msg actual) = 1
318 +'
319 +
320 test_done
t/t7505/expected-rebase-i new
+17
@@ -0,0 +1,17 @@
1 +message [edit rebase-13]
2 +message (no editor) [edit rebase-13]
3 +message [squash rebase-12]
4 +message (no editor) [squash rebase-11]
5 +default [edit rebase-10]
6 +message (no editor) [edit rebase-10]
7 +message [fixup rebase-9]
8 +message (no editor) [fixup rebase-8]
9 +message (no editor) [squash rebase-7]
10 +message [reword rebase-6]
11 +message [squash rebase-5]
12 +message (no editor) [fixup rebase-4]
13 +message (no editor) [pick rebase-3]
14 +message (no editor) [fixup rebase-2]
15 +message (no editor) [fixup rebase-1]
16 +merge [pick rebase-b]
17 +message [pick rebase-a]
t/t7505/expected-rebase-p new
+18
@@ -0,0 +1,18 @@
1 +message [edit rebase-13]
2 +message (no editor) [edit rebase-13]
3 +message [squash rebase-12]
4 +message (no editor) [squash rebase-11]
5 +default [edit rebase-10]
6 +message (no editor) [edit rebase-10]
7 +message [fixup rebase-9]
8 +message (no editor) [fixup rebase-8]
9 +message (no editor) [squash rebase-7]
10 +HEAD [reword rebase-6]
11 +message (no editor) [reword rebase-6]
12 +message [squash rebase-5]
13 +message (no editor) [fixup rebase-4]
14 +message (no editor) [pick rebase-3]
15 +message (no editor) [fixup rebase-2]
16 +message (no editor) [fixup rebase-1]
17 +merge [pick rebase-b]
18 +message [pick rebase-a]