| 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 |