Raw
1 #!/bin/sh
2 #
3 # Copyright (c) 2018 Phillip Wood
4 #
5
6 test_description='git rebase interactive fixup options
7
8 This test checks the "fixup [-C|-c]" command of rebase interactive.
9 In addition to amending the contents of the commit, "fixup -C"
10 replaces the original commit message with the message of the fixup
11 commit. "fixup -c" also replaces the original message, but opens the
12 editor to allow the user to edit the message before committing. Similar
13 to the "fixup" command that works with "fixup!", "fixup -C" works with
14 "amend!" upon --autosquash.
15 '
16
17 . ./test-lib.sh
18
19 . "$TEST_DIRECTORY"/lib-rebase.sh
20
21 EMPTY=""
22
23 get_author () {
24 rev="$1" &&
25 git log -1 --pretty=format:"%an %ae %at" "$rev"
26 }
27
28 test_expect_success 'setup' '
29 cat >message <<-EOF &&
30 amend! B
31 $EMPTY
32 new subject
33 $EMPTY
34 new
35 body
36 EOF
37
38 test_commit initial &&
39 test_commit A A &&
40 test_commit B B &&
41 get_author HEAD >expected-author &&
42 ORIG_AUTHOR_NAME="$GIT_AUTHOR_NAME" &&
43 ORIG_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" &&
44 GIT_AUTHOR_NAME="Amend Author" &&
45 GIT_AUTHOR_EMAIL="amend@example.com" &&
46 test_commit "$(cat message)" A A1 A1 &&
47 test_commit A2 A &&
48 test_commit A3 A &&
49 GIT_AUTHOR_NAME="$ORIG_AUTHOR_NAME" &&
50 GIT_AUTHOR_EMAIL="$ORIG_AUTHOR_EMAIL" &&
51 git checkout -b conflicts-branch A &&
52 test_commit conflicts A &&
53
54 set_fake_editor &&
55 git checkout -b branch B &&
56 echo B1 >B &&
57 test_tick &&
58 git commit --fixup=HEAD -a &&
59 git tag B1 &&
60 test_tick &&
61 FAKE_COMMIT_AMEND="edited 1" git commit --fixup=reword:B &&
62 test_tick &&
63 FAKE_COMMIT_AMEND="edited 2" git commit --fixup=reword:HEAD &&
64 echo B2 >B &&
65 test_tick &&
66 FAKE_COMMIT_AMEND="edited squash" git commit --squash=HEAD -a &&
67 git tag B2 &&
68 echo B3 >B &&
69 test_tick &&
70 FAKE_COMMIT_AMEND="edited 3" git commit -a --fixup=amend:HEAD^ &&
71 git tag B3 &&
72
73 GIT_AUTHOR_NAME="Rebase Author" &&
74 GIT_AUTHOR_EMAIL="rebase.author@example.com" &&
75 GIT_COMMITTER_NAME="Rebase Committer" &&
76 GIT_COMMITTER_EMAIL="rebase.committer@example.com"
77 '
78
79 test_expect_success 'simple fixup -C works' '
80 test_when_finished "test_might_fail git rebase --abort" &&
81 git checkout --detach A2 &&
82 FAKE_LINES="1 fixup_-C 2" git rebase -i B &&
83 test_cmp_rev HEAD^ B &&
84 test_cmp_rev HEAD^{tree} A2^{tree} &&
85 test_commit_message HEAD -m "A2"
86 '
87
88 test_expect_success 'simple fixup -c works' '
89 test_when_finished "test_might_fail git rebase --abort" &&
90 git checkout --detach A2 &&
91 git log -1 --pretty=format:%B >expected-fixup-message &&
92 test_write_lines "" "Modified A2" >>expected-fixup-message &&
93 FAKE_LINES="1 fixup_-c 2" \
94 FAKE_COMMIT_AMEND="Modified A2" \
95 git rebase -i B &&
96 test_cmp_rev HEAD^ B &&
97 test_cmp_rev HEAD^{tree} A2^{tree} &&
98 test_commit_message HEAD expected-fixup-message
99 '
100
101 test_expect_success 'fixup -C removes amend! from message' '
102 test_when_finished "test_might_fail git rebase --abort" &&
103 git checkout --detach A1 &&
104 git log -1 --pretty=format:%b >expected-message &&
105 FAKE_LINES="1 fixup_-C 2" git rebase -i A &&
106 test_cmp_rev HEAD^ A &&
107 test_cmp_rev HEAD^{tree} A1^{tree} &&
108 test_commit_message HEAD expected-message &&
109 get_author HEAD >actual-author &&
110 test_cmp expected-author actual-author
111 '
112
113 test_expect_success 'fixup -C with conflicts gives correct message' '
114 test_when_finished "test_might_fail git rebase --abort" &&
115 git checkout --detach A1 &&
116 git log -1 --pretty=format:%b >expected-message &&
117 test_write_lines "" "edited" >>expected-message &&
118 test_must_fail env FAKE_LINES="1 fixup_-C 2" git rebase -i conflicts &&
119 git checkout --theirs -- A &&
120 git add A &&
121 FAKE_COMMIT_AMEND=edited git rebase --continue &&
122 test_cmp_rev HEAD^ conflicts &&
123 test_cmp_rev HEAD^{tree} A1^{tree} &&
124 test_commit_message HEAD expected-message &&
125 get_author HEAD >actual-author &&
126 test_cmp expected-author actual-author
127 '
128
129 test_expect_success 'conflicting fixup -C after fixup with custom comment string' '
130 test_config core.commentString COMMENT &&
131 test_when_finished "test_might_fail git rebase --abort" &&
132 git checkout --detach A3 &&
133 test_must_fail env FAKE_LINES="1 fixup 2 fixup_-C 4" git rebase -i A &&
134 echo resolved >A &&
135 git add A &&
136 FAKE_COMMIT_AMEND=edited git rebase --continue &&
137 test_commit_message HEAD <<-\EOF
138 A3
139
140 edited
141 EOF
142 '
143
144 test_expect_success 'skipping fixup -C after fixup gives correct message' '
145 test_when_finished "test_might_fail git rebase --abort" &&
146 git checkout --detach A3 &&
147 test_must_fail env FAKE_LINES="1 fixup 2 fixup_-C 4" git rebase -i A &&
148 git reset --hard &&
149 FAKE_COMMIT_AMEND=edited git rebase --continue &&
150 test_commit_message HEAD -m "B"
151 '
152
153 test_expect_success 'sequence of fixup, fixup -C & squash --signoff works' '
154 git checkout --detach B3 &&
155 FAKE_LINES="1 fixup 2 fixup_-C 3 fixup_-C 4 squash 5 fixup_-C 6" \
156 FAKE_COMMIT_AMEND=squashed \
157 FAKE_MESSAGE_COPY=actual-squash-message \
158 git -c commit.status=false rebase -ik --signoff A &&
159 git diff-tree --exit-code --patch HEAD B3 -- &&
160 test_cmp_rev HEAD^ A &&
161 test_cmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
162 actual-squash-message
163 '
164
165 test_expect_success 'first fixup -C commented out in sequence fixup fixup -C fixup -C' '
166 test_when_finished "test_might_fail git rebase --abort" &&
167 git checkout --detach B2~ &&
168 git log -1 --pretty=format:%b >expected-message &&
169 FAKE_LINES="1 fixup 2 fixup_-C 3 fixup_-C 4" git rebase -i A &&
170 test_cmp_rev HEAD^ A &&
171 test_commit_message HEAD expected-message
172 '
173
174 test_expect_success 'multiple fixup -c opens editor once' '
175 test_when_finished "test_might_fail git rebase --abort" &&
176 git checkout --detach A3 &&
177 git log -1 --pretty=format:%B >expected-message &&
178 test_write_lines "" "Modified-A3" >>expected-message &&
179 FAKE_COMMIT_AMEND="Modified-A3" \
180 FAKE_LINES="1 fixup_-C 2 fixup_-c 3 fixup_-c 4" \
181 EXPECT_HEADER_COUNT=4 \
182 git rebase -i A &&
183 test_cmp_rev HEAD^ A &&
184 get_author HEAD >actual-author &&
185 test_cmp expected-author actual-author &&
186 test_commit_message HEAD expected-message
187 '
188
189 test_expect_success 'fixup -c is remembered after skipping final fixup' '
190 test_when_finished "test_might_fail git rebase --abort" &&
191 cat >todo <<-\EOF &&
192 pick B
193 fixup -c A1
194 fixup A3
195 EOF
196 (
197 set_fake_editor &&
198 set_replace_editor todo &&
199 test_must_fail git rebase -i A A &&
200 git show && cat .git/rebase-merge/message-squash &&
201 FAKE_COMMIT_AMEND=edited git rebase --skip
202 ) &&
203 test_commit_message HEAD <<-\EOF
204 new subject
205
206 new
207 body
208
209 edited
210 EOF
211 '
212 test_expect_success 'fixup -c is remembered after skipping later fixup' '
213 test_when_finished "test_might_fail git rebase --abort" &&
214 cat >todo <<-\EOF &&
215 pick B
216 fixup -c A1
217 fixup A3
218 fixup A2
219 EOF
220 (
221 set_fake_editor &&
222 set_replace_editor todo &&
223 test_must_fail git rebase -i A A &&
224 FAKE_COMMIT_AMEND=edited git rebase --skip
225 ) &&
226 test_commit_message HEAD <<-\EOF
227 new subject
228
229 new
230 body
231
232 edited
233 EOF
234 '
235
236 test_expect_success 'sequence squash, fixup & fixup -c gives combined message' '
237 test_when_finished "test_might_fail git rebase --abort" &&
238 git checkout --detach A3 &&
239 FAKE_LINES="1 squash 2 fixup 3 fixup_-c 4" \
240 FAKE_MESSAGE_COPY=actual-combined-message \
241 git -c commit.status=false rebase -i A &&
242 test_cmp "$TEST_DIRECTORY/t3437/expected-combined-message" \
243 actual-combined-message &&
244 test_cmp_rev HEAD^ A
245 '
246
247 test_expect_success 'fixup -C works upon --autosquash with amend!' '
248 git checkout --detach B3 &&
249 FAKE_COMMIT_AMEND=squashed \
250 FAKE_MESSAGE_COPY=actual-squash-message \
251 git -c commit.status=false rebase -ik --autosquash \
252 --signoff A &&
253 git diff-tree --exit-code --patch HEAD B3 -- &&
254 test_cmp_rev HEAD^ A &&
255 test_cmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
256 actual-squash-message
257 '
258
259 test_expect_success 'fixup -[Cc]<commit> works' '
260 test_when_finished "test_might_fail git rebase --abort" &&
261 cat >todo <<-\EOF &&
262 pick A
263 fixup -CA1
264 pick B
265 fixup -cA2
266 EOF
267 (
268 set_replace_editor todo &&
269 FAKE_COMMIT_MESSAGE="edited and fixed up" \
270 git rebase -i initial initial
271 ) &&
272 git log --pretty=format:%B initial.. >actual &&
273 cat >expect <<-EOF &&
274 edited and fixed up
275 $EMPTY
276 new subject
277 $EMPTY
278 new
279 body
280 EOF
281 test_cmp expect actual
282 '
283
284 test_done