Merge branch 'jt/fetch-pack-request-fix' into jt/push-negotiation
[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         FAKE_COMMIT_AMEND="edited 1" git commit --fixup=reword:B &&
76         test_tick &&
77         FAKE_COMMIT_AMEND="edited 2" git commit --fixup=reword:HEAD &&
78         echo B2 >B &&
79         test_tick &&
80         FAKE_COMMIT_AMEND="edited squash" git commit --squash=HEAD -a &&
81         git tag B2 &&
82         echo B3 >B &&
83         test_tick &&
84         FAKE_COMMIT_AMEND="edited 3" git commit -a --fixup=amend:HEAD^ &&
85         git tag B3 &&
86
87         GIT_AUTHOR_NAME="Rebase Author" &&
88         GIT_AUTHOR_EMAIL="rebase.author@example.com" &&
89         GIT_COMMITTER_NAME="Rebase Committer" &&
90         GIT_COMMITTER_EMAIL="rebase.committer@example.com"
91 '
92
93 test_expect_success 'simple fixup -C works' '
94         test_when_finished "test_might_fail git rebase --abort" &&
95         git checkout --detach A2 &&
96         FAKE_LINES="1 fixup_-C 2" git rebase -i B &&
97         test_cmp_rev HEAD^ B &&
98         test_cmp_rev HEAD^{tree} A2^{tree} &&
99         test_commit_message HEAD -m "A2"
100 '
101
102 test_expect_success 'simple fixup -c works' '
103         test_when_finished "test_might_fail git rebase --abort" &&
104         git checkout --detach A2 &&
105         git log -1 --pretty=format:%B >expected-fixup-message &&
106         test_write_lines "" "Modified A2" >>expected-fixup-message &&
107         FAKE_LINES="1 fixup_-c 2" \
108                 FAKE_COMMIT_AMEND="Modified A2" \
109                 git rebase -i B &&
110         test_cmp_rev HEAD^ B &&
111         test_cmp_rev HEAD^{tree} A2^{tree} &&
112         test_commit_message HEAD expected-fixup-message
113 '
114
115 test_expect_success 'fixup -C removes amend! from message' '
116         test_when_finished "test_might_fail git rebase --abort" &&
117         git checkout --detach A1 &&
118         git log -1 --pretty=format:%b >expected-message &&
119         FAKE_LINES="1 fixup_-C 2" git rebase -i A &&
120         test_cmp_rev HEAD^ A &&
121         test_cmp_rev HEAD^{tree} A1^{tree} &&
122         test_commit_message HEAD expected-message &&
123         get_author HEAD >actual-author &&
124         test_cmp expected-author actual-author
125 '
126
127 test_expect_success 'fixup -C with conflicts gives correct message' '
128         test_when_finished "test_might_fail git rebase --abort" &&
129         git checkout --detach A1 &&
130         git log -1 --pretty=format:%b >expected-message &&
131         test_write_lines "" "edited" >>expected-message &&
132         test_must_fail env FAKE_LINES="1 fixup_-C 2" git rebase -i conflicts &&
133         git checkout --theirs -- A &&
134         git add A &&
135         FAKE_COMMIT_AMEND=edited git rebase --continue &&
136         test_cmp_rev HEAD^ conflicts &&
137         test_cmp_rev HEAD^{tree} A1^{tree} &&
138         test_commit_message HEAD expected-message &&
139         get_author HEAD >actual-author &&
140         test_cmp expected-author actual-author
141 '
142
143 test_expect_success 'skipping fixup -C after fixup gives correct message' '
144         test_when_finished "test_might_fail git rebase --abort" &&
145         git checkout --detach A3 &&
146         test_must_fail env FAKE_LINES="1 fixup 2 fixup_-C 4" git rebase -i A &&
147         git reset --hard &&
148         FAKE_COMMIT_AMEND=edited git rebase --continue &&
149         test_commit_message HEAD -m "B"
150 '
151
152 test_expect_success 'sequence of fixup, fixup -C & squash --signoff works' '
153         git checkout --detach B3 &&
154         FAKE_LINES="1 fixup 2 fixup_-C 3 fixup_-C 4 squash 5 fixup_-C 6" \
155                 FAKE_COMMIT_AMEND=squashed \
156                 FAKE_MESSAGE_COPY=actual-squash-message \
157                 git -c commit.status=false rebase -ik --signoff A &&
158         git diff-tree --exit-code --patch HEAD B3 -- &&
159         test_cmp_rev HEAD^ A &&
160         test_i18ncmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
161                 actual-squash-message
162 '
163
164 test_expect_success 'first fixup -C commented out in sequence fixup fixup -C fixup -C' '
165         test_when_finished "test_might_fail git rebase --abort" &&
166         git checkout --detach B2~ &&
167         git log -1 --pretty=format:%b >expected-message &&
168         FAKE_LINES="1 fixup 2 fixup_-C 3 fixup_-C 4" git rebase -i A &&
169         test_cmp_rev HEAD^ A &&
170         test_commit_message HEAD expected-message
171 '
172
173 test_expect_success 'multiple fixup -c opens editor once' '
174         test_when_finished "test_might_fail git rebase --abort" &&
175         git checkout --detach A3 &&
176         git log -1 --pretty=format:%B >expected-message &&
177         test_write_lines "" "Modified-A3" >>expected-message &&
178         FAKE_COMMIT_AMEND="Modified-A3" \
179                 FAKE_LINES="1 fixup_-C 2 fixup_-c 3 fixup_-c 4" \
180                 EXPECT_HEADER_COUNT=4 \
181                 git rebase -i A &&
182         test_cmp_rev HEAD^ A &&
183         get_author HEAD >actual-author &&
184         test_cmp expected-author actual-author &&
185         test_commit_message HEAD expected-message
186 '
187
188 test_expect_success 'sequence squash, fixup & fixup -c gives combined message' '
189         test_when_finished "test_might_fail git rebase --abort" &&
190         git checkout --detach A3 &&
191         FAKE_LINES="1 squash 2 fixup 3 fixup_-c 4" \
192                 FAKE_MESSAGE_COPY=actual-combined-message \
193                 git -c commit.status=false rebase -i A &&
194         test_i18ncmp "$TEST_DIRECTORY/t3437/expected-combined-message" \
195                 actual-combined-message &&
196         test_cmp_rev HEAD^ A
197 '
198
199 test_expect_success 'fixup -C works upon --autosquash with amend!' '
200         git checkout --detach B3 &&
201         FAKE_COMMIT_AMEND=squashed \
202                 FAKE_MESSAGE_COPY=actual-squash-message \
203                 git -c commit.status=false rebase -ik --autosquash \
204                                                 --signoff A &&
205         git diff-tree --exit-code --patch HEAD B3 -- &&
206         test_cmp_rev HEAD^ A &&
207         test_i18ncmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
208                 actual-squash-message
209 '
210
211 test_done