3 # Copyright (c) 2018 Phillip Wood
6 test_description='git rebase interactive fixup options
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.
19 . "$TEST_DIRECTORY"/lib-rebase.sh
23 # test_commit_message <rev> -m <msg>
24 # test_commit_message <rev> <path>
25 # Verify that the commit message of <rev> matches
26 # <msg> or the content of <path>.
27 test_commit_message () {
28 git show --no-patch --pretty=format:%B "$1" >actual &&
32 test_cmp expect actual ;;
34 test_cmp "$2" actual ;;
40 git log -1 --pretty=format:"%an %ae %at" "$rev"
43 test_expect_success 'setup' '
44 cat >message <<-EOF &&
55 get_author HEAD >expected-author &&
56 ORIG_AUTHOR_NAME="$GIT_AUTHOR_NAME" &&
57 ORIG_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" &&
58 GIT_AUTHOR_NAME="Amend Author" &&
59 GIT_AUTHOR_EMAIL="amend@example.com" &&
60 test_commit "$(cat message)" A A1 A1 &&
63 GIT_AUTHOR_NAME="$ORIG_AUTHOR_NAME" &&
64 GIT_AUTHOR_EMAIL="$ORIG_AUTHOR_EMAIL" &&
65 git checkout -b conflicts-branch A &&
66 test_commit conflicts A &&
69 git checkout -b branch B &&
72 git commit --fixup=HEAD -a &&
74 git commit --allow-empty -F - <<-EOF &&
82 git commit --allow-empty -F - <<-EOF &&
93 FAKE_COMMIT_AMEND="edited squash" git commit --squash=HEAD -a &&
96 git commit -a -F - <<-EOF &&
97 amend! amend! amend! B
108 GIT_AUTHOR_NAME="Rebase Author" &&
109 GIT_AUTHOR_EMAIL="rebase.author@example.com" &&
110 GIT_COMMITTER_NAME="Rebase Committer" &&
111 GIT_COMMITTER_EMAIL="rebase.committer@example.com"
114 test_expect_success 'simple fixup -C works' '
115 test_when_finished "test_might_fail git rebase --abort" &&
116 git checkout --detach A2 &&
117 FAKE_LINES="1 fixup_-C 2" git rebase -i B &&
118 test_cmp_rev HEAD^ B &&
119 test_cmp_rev HEAD^{tree} A2^{tree} &&
120 test_commit_message HEAD -m "A2"
123 test_expect_success 'simple fixup -c works' '
124 test_when_finished "test_might_fail git rebase --abort" &&
125 git checkout --detach A2 &&
126 git log -1 --pretty=format:%B >expected-fixup-message &&
127 test_write_lines "" "Modified A2" >>expected-fixup-message &&
128 FAKE_LINES="1 fixup_-c 2" \
129 FAKE_COMMIT_AMEND="Modified A2" \
131 test_cmp_rev HEAD^ B &&
132 test_cmp_rev HEAD^{tree} A2^{tree} &&
133 test_commit_message HEAD expected-fixup-message
136 test_expect_success 'fixup -C removes amend! from message' '
137 test_when_finished "test_might_fail git rebase --abort" &&
138 git checkout --detach A1 &&
139 git log -1 --pretty=format:%b >expected-message &&
140 FAKE_LINES="1 fixup_-C 2" git rebase -i A &&
141 test_cmp_rev HEAD^ A &&
142 test_cmp_rev HEAD^{tree} A1^{tree} &&
143 test_commit_message HEAD expected-message &&
144 get_author HEAD >actual-author &&
145 test_cmp expected-author actual-author
148 test_expect_success 'fixup -C with conflicts gives correct message' '
149 test_when_finished "test_might_fail git rebase --abort" &&
150 git checkout --detach A1 &&
151 git log -1 --pretty=format:%b >expected-message &&
152 test_write_lines "" "edited" >>expected-message &&
153 test_must_fail env FAKE_LINES="1 fixup_-C 2" git rebase -i conflicts &&
154 git checkout --theirs -- A &&
156 FAKE_COMMIT_AMEND=edited git rebase --continue &&
157 test_cmp_rev HEAD^ conflicts &&
158 test_cmp_rev HEAD^{tree} A1^{tree} &&
159 test_commit_message HEAD expected-message &&
160 get_author HEAD >actual-author &&
161 test_cmp expected-author actual-author
164 test_expect_success 'skipping fixup -C after fixup gives correct message' '
165 test_when_finished "test_might_fail git rebase --abort" &&
166 git checkout --detach A3 &&
167 test_must_fail env FAKE_LINES="1 fixup 2 fixup_-C 4" git rebase -i A &&
169 FAKE_COMMIT_AMEND=edited git rebase --continue &&
170 test_commit_message HEAD -m "B"
173 test_expect_success 'sequence of fixup, fixup -C & squash --signoff works' '
174 git checkout --detach branch &&
175 FAKE_LINES="1 fixup 2 fixup_-C 3 fixup_-C 4 squash 5 fixup_-C 6" \
176 FAKE_COMMIT_AMEND=squashed \
177 FAKE_MESSAGE_COPY=actual-squash-message \
178 git -c commit.status=false rebase -ik --signoff A &&
179 git diff-tree --exit-code --patch HEAD branch -- &&
180 test_cmp_rev HEAD^ A &&
181 test_i18ncmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
182 actual-squash-message
185 test_expect_success 'first fixup -C commented out in sequence fixup fixup -C fixup -C' '
186 test_when_finished "test_might_fail git rebase --abort" &&
187 git checkout branch && git checkout --detach branch~2 &&
188 git log -1 --pretty=format:%b >expected-message &&
189 FAKE_LINES="1 fixup 2 fixup_-C 3 fixup_-C 4" git rebase -i A &&
190 test_cmp_rev HEAD^ A &&
191 test_commit_message HEAD expected-message
194 test_expect_success 'multiple fixup -c opens editor once' '
195 test_when_finished "test_might_fail git rebase --abort" &&
196 git checkout --detach A3 &&
197 base=$(git rev-parse HEAD~4) &&
198 FAKE_COMMIT_MESSAGE="Modified-A3" \
199 FAKE_LINES="1 fixup_-C 2 fixup_-c 3 fixup_-c 4" \
200 EXPECT_HEADER_COUNT=4 \
201 git rebase -i $base &&
202 test_cmp_rev $base HEAD^ &&
203 get_author HEAD >actual-author &&
204 test_cmp expected-author actual-author &&
205 test 1 = $(git show | grep Modified-A3 | wc -l)
208 test_expect_success 'sequence squash, fixup & fixup -c gives combined message' '
209 test_when_finished "test_might_fail git rebase --abort" &&
210 git checkout --detach A3 &&
211 FAKE_LINES="1 squash 2 fixup 3 fixup_-c 4" \
212 FAKE_MESSAGE_COPY=actual-combined-message \
213 git -c commit.status=false rebase -i A &&
214 test_i18ncmp "$TEST_DIRECTORY/t3437/expected-combined-message" \
215 actual-combined-message &&
219 test_expect_success 'fixup -C works upon --autosquash with amend!' '
220 git checkout --detach branch &&
221 FAKE_COMMIT_AMEND=squashed \
222 FAKE_MESSAGE_COPY=actual-squash-message \
223 git -c commit.status=false rebase -ik --autosquash \
225 git diff-tree --exit-code --patch HEAD branch -- &&
226 test_cmp_rev HEAD^ A &&
227 test_i18ncmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
228 actual-squash-message