Merge branch 'cm/rebase-i-updates'
[git] / t / t3437-rebase-fixup-options.sh
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 # 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 &&
29         case "$2" in
30         -m)
31                 echo "$3" >expect &&
32                 test_cmp expect actual ;;
33         *)
34                 test_cmp "$2" actual ;;
35         esac
36 }
37
38 get_author () {
39         rev="$1" &&
40         git log -1 --pretty=format:"%an %ae %at" "$rev"
41 }
42
43 test_expect_success 'setup' '
44         cat >message <<-EOF &&
45         amend! B
46         $EMPTY
47         new subject
48         $EMPTY
49         new
50         body
51         EOF
52
53         test_commit A A &&
54         test_commit B B &&
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 &&
61         test_commit A2 A &&
62         test_commit A3 A &&
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 &&
67
68         set_fake_editor &&
69         git checkout -b branch B &&
70         echo B1 >B &&
71         test_tick &&
72         git commit --fixup=HEAD -a &&
73         git tag B1 &&
74         test_tick &&
75         git commit --allow-empty -F - <<-EOF &&
76         amend! B
77         $EMPTY
78         B
79         $EMPTY
80         edited 1
81         EOF
82         test_tick &&
83         git commit --allow-empty -F - <<-EOF &&
84         amend! amend! B
85         $EMPTY
86         B
87         $EMPTY
88         edited 1
89         $EMPTY
90         edited 2
91         EOF
92         echo B2 >B &&
93         test_tick &&
94         FAKE_COMMIT_AMEND="edited squash" git commit --squash=HEAD -a &&
95         git tag B2 &&
96         echo B3 >B &&
97         test_tick &&
98         git commit -a -F - <<-EOF &&
99         amend! amend! amend! B
100         $EMPTY
101         B
102         $EMPTY
103         edited 1
104         $EMPTY
105         edited 2
106         $EMPTY
107         edited 3
108         EOF
109         git tag B3 &&
110
111         GIT_AUTHOR_NAME="Rebase Author" &&
112         GIT_AUTHOR_EMAIL="rebase.author@example.com" &&
113         GIT_COMMITTER_NAME="Rebase Committer" &&
114         GIT_COMMITTER_EMAIL="rebase.committer@example.com"
115 '
116
117 test_expect_success 'simple fixup -C works' '
118         test_when_finished "test_might_fail git rebase --abort" &&
119         git checkout --detach A2 &&
120         FAKE_LINES="1 fixup_-C 2" git rebase -i B &&
121         test_cmp_rev HEAD^ B &&
122         test_cmp_rev HEAD^{tree} A2^{tree} &&
123         test_commit_message HEAD -m "A2"
124 '
125
126 test_expect_success 'simple fixup -c works' '
127         test_when_finished "test_might_fail git rebase --abort" &&
128         git checkout --detach A2 &&
129         git log -1 --pretty=format:%B >expected-fixup-message &&
130         test_write_lines "" "Modified A2" >>expected-fixup-message &&
131         FAKE_LINES="1 fixup_-c 2" \
132                 FAKE_COMMIT_AMEND="Modified A2" \
133                 git rebase -i B &&
134         test_cmp_rev HEAD^ B &&
135         test_cmp_rev HEAD^{tree} A2^{tree} &&
136         test_commit_message HEAD expected-fixup-message
137 '
138
139 test_expect_success 'fixup -C removes amend! from message' '
140         test_when_finished "test_might_fail git rebase --abort" &&
141         git checkout --detach A1 &&
142         git log -1 --pretty=format:%b >expected-message &&
143         FAKE_LINES="1 fixup_-C 2" git rebase -i A &&
144         test_cmp_rev HEAD^ A &&
145         test_cmp_rev HEAD^{tree} A1^{tree} &&
146         test_commit_message HEAD expected-message &&
147         get_author HEAD >actual-author &&
148         test_cmp expected-author actual-author
149 '
150
151 test_expect_success 'fixup -C with conflicts gives correct message' '
152         test_when_finished "test_might_fail git rebase --abort" &&
153         git checkout --detach A1 &&
154         git log -1 --pretty=format:%b >expected-message &&
155         test_write_lines "" "edited" >>expected-message &&
156         test_must_fail env FAKE_LINES="1 fixup_-C 2" git rebase -i conflicts &&
157         git checkout --theirs -- A &&
158         git add A &&
159         FAKE_COMMIT_AMEND=edited git rebase --continue &&
160         test_cmp_rev HEAD^ conflicts &&
161         test_cmp_rev HEAD^{tree} A1^{tree} &&
162         test_commit_message HEAD expected-message &&
163         get_author HEAD >actual-author &&
164         test_cmp expected-author actual-author
165 '
166
167 test_expect_success 'skipping fixup -C after fixup gives correct message' '
168         test_when_finished "test_might_fail git rebase --abort" &&
169         git checkout --detach A3 &&
170         test_must_fail env FAKE_LINES="1 fixup 2 fixup_-C 4" git rebase -i A &&
171         git reset --hard &&
172         FAKE_COMMIT_AMEND=edited git rebase --continue &&
173         test_commit_message HEAD -m "B"
174 '
175
176 test_expect_success 'sequence of fixup, fixup -C & squash --signoff works' '
177         git checkout --detach B3 &&
178         FAKE_LINES="1 fixup 2 fixup_-C 3 fixup_-C 4 squash 5 fixup_-C 6" \
179                 FAKE_COMMIT_AMEND=squashed \
180                 FAKE_MESSAGE_COPY=actual-squash-message \
181                 git -c commit.status=false rebase -ik --signoff A &&
182         git diff-tree --exit-code --patch HEAD B3 -- &&
183         test_cmp_rev HEAD^ A &&
184         test_i18ncmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
185                 actual-squash-message
186 '
187
188 test_expect_success 'first fixup -C commented out in sequence fixup fixup -C fixup -C' '
189         test_when_finished "test_might_fail git rebase --abort" &&
190         git checkout --detach B2~ &&
191         git log -1 --pretty=format:%b >expected-message &&
192         FAKE_LINES="1 fixup 2 fixup_-C 3 fixup_-C 4" git rebase -i A &&
193         test_cmp_rev HEAD^ A &&
194         test_commit_message HEAD expected-message
195 '
196
197 test_expect_success 'multiple fixup -c opens editor once' '
198         test_when_finished "test_might_fail git rebase --abort" &&
199         git checkout --detach A3 &&
200         git log -1 --pretty=format:%B >expected-message &&
201         test_write_lines "" "Modified-A3" >>expected-message &&
202         FAKE_COMMIT_AMEND="Modified-A3" \
203                 FAKE_LINES="1 fixup_-C 2 fixup_-c 3 fixup_-c 4" \
204                 EXPECT_HEADER_COUNT=4 \
205                 git rebase -i A &&
206         test_cmp_rev HEAD^ A &&
207         get_author HEAD >actual-author &&
208         test_cmp expected-author actual-author &&
209         test_commit_message HEAD expected-message
210 '
211
212 test_expect_success 'sequence squash, fixup & fixup -c gives combined message' '
213         test_when_finished "test_might_fail git rebase --abort" &&
214         git checkout --detach A3 &&
215         FAKE_LINES="1 squash 2 fixup 3 fixup_-c 4" \
216                 FAKE_MESSAGE_COPY=actual-combined-message \
217                 git -c commit.status=false rebase -i A &&
218         test_i18ncmp "$TEST_DIRECTORY/t3437/expected-combined-message" \
219                 actual-combined-message &&
220         test_cmp_rev HEAD^ A
221 '
222
223 test_expect_success 'fixup -C works upon --autosquash with amend!' '
224         git checkout --detach B3 &&
225         FAKE_COMMIT_AMEND=squashed \
226                 FAKE_MESSAGE_COPY=actual-squash-message \
227                 git -c commit.status=false rebase -ik --autosquash \
228                                                 --signoff A &&
229         git diff-tree --exit-code --patch HEAD B3 -- &&
230         test_cmp_rev HEAD^ A &&
231         test_i18ncmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
232                 actual-squash-message
233 '
234
235 test_done