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