| 1 | #!/bin/sh |
| 2 | # |
| 3 | # Copyright (c) 2010 Thomas Rast |
| 4 | # |
| 5 | |
| 6 | test_description='Test the post-rewrite hook.' |
| 7 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
| 8 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
| 9 | |
| 10 | . ./test-lib.sh |
| 11 | |
| 12 | test_expect_success 'setup' ' |
| 13 | test_commit A foo A && |
| 14 | test_commit B foo B && |
| 15 | test_commit C foo C && |
| 16 | test_commit D foo D && |
| 17 | git checkout A^0 && |
| 18 | test_commit E bar E && |
| 19 | test_commit F foo F && |
| 20 | git checkout B && |
| 21 | git merge E && |
| 22 | git tag merge-E && |
| 23 | test_commit G G && |
| 24 | test_commit H H && |
| 25 | test_commit I I && |
| 26 | git checkout main && |
| 27 | |
| 28 | test_hook --setup post-rewrite <<-EOF |
| 29 | echo \$@ > "$TRASH_DIRECTORY"/post-rewrite.args |
| 30 | cat > "$TRASH_DIRECTORY"/post-rewrite.data |
| 31 | EOF |
| 32 | ' |
| 33 | |
| 34 | clear_hook_input () { |
| 35 | rm -f post-rewrite.args post-rewrite.data |
| 36 | } |
| 37 | |
| 38 | verify_hook_input () { |
| 39 | test_cmp expected.args "$TRASH_DIRECTORY"/post-rewrite.args && |
| 40 | test_cmp expected.data "$TRASH_DIRECTORY"/post-rewrite.data |
| 41 | } |
| 42 | |
| 43 | test_expect_success 'git commit --amend' ' |
| 44 | clear_hook_input && |
| 45 | echo "D new message" > newmsg && |
| 46 | oldsha=$(git rev-parse HEAD^0) && |
| 47 | git commit -Fnewmsg --amend && |
| 48 | echo amend > expected.args && |
| 49 | echo $oldsha $(git rev-parse HEAD^0) > expected.data && |
| 50 | verify_hook_input |
| 51 | ' |
| 52 | |
| 53 | test_expect_success 'git commit --amend --no-post-rewrite' ' |
| 54 | clear_hook_input && |
| 55 | echo "D new message again" > newmsg && |
| 56 | git commit --no-post-rewrite -Fnewmsg --amend && |
| 57 | test ! -f post-rewrite.args && |
| 58 | test ! -f post-rewrite.data |
| 59 | ' |
| 60 | |
| 61 | test_expect_success 'git rebase --apply' ' |
| 62 | git reset --hard D && |
| 63 | clear_hook_input && |
| 64 | test_must_fail git rebase --apply --onto A B && |
| 65 | echo C > foo && |
| 66 | git add foo && |
| 67 | git rebase --continue && |
| 68 | echo rebase >expected.args && |
| 69 | cat >expected.data <<-EOF && |
| 70 | $(git rev-parse C) $(git rev-parse HEAD^) |
| 71 | $(git rev-parse D) $(git rev-parse HEAD) |
| 72 | EOF |
| 73 | verify_hook_input |
| 74 | ' |
| 75 | |
| 76 | test_expect_success 'git rebase --apply --skip' ' |
| 77 | git reset --hard D && |
| 78 | clear_hook_input && |
| 79 | test_must_fail git rebase --apply --onto A B && |
| 80 | test_must_fail git rebase --skip && |
| 81 | echo D > foo && |
| 82 | git add foo && |
| 83 | git rebase --continue && |
| 84 | echo rebase >expected.args && |
| 85 | cat >expected.data <<-EOF && |
| 86 | $(git rev-parse C) $(git rev-parse HEAD^) |
| 87 | $(git rev-parse D) $(git rev-parse HEAD) |
| 88 | EOF |
| 89 | verify_hook_input |
| 90 | ' |
| 91 | |
| 92 | test_expect_success 'git rebase --apply --skip the last one' ' |
| 93 | git reset --hard F && |
| 94 | clear_hook_input && |
| 95 | test_must_fail git rebase --apply --onto D A && |
| 96 | git rebase --skip && |
| 97 | echo rebase >expected.args && |
| 98 | cat >expected.data <<-EOF && |
| 99 | $(git rev-parse E) $(git rev-parse HEAD) |
| 100 | $(git rev-parse F) $(git rev-parse HEAD) |
| 101 | EOF |
| 102 | verify_hook_input |
| 103 | ' |
| 104 | |
| 105 | test_expect_success 'git rebase -m' ' |
| 106 | git reset --hard D && |
| 107 | clear_hook_input && |
| 108 | test_must_fail git rebase -m --onto A B && |
| 109 | echo C > foo && |
| 110 | git add foo && |
| 111 | git rebase --continue && |
| 112 | echo rebase >expected.args && |
| 113 | cat >expected.data <<-EOF && |
| 114 | $(git rev-parse C) $(git rev-parse HEAD^) |
| 115 | $(git rev-parse D) $(git rev-parse HEAD) |
| 116 | EOF |
| 117 | verify_hook_input |
| 118 | ' |
| 119 | |
| 120 | test_expect_success 'git rebase -m --skip' ' |
| 121 | git reset --hard D && |
| 122 | clear_hook_input && |
| 123 | test_must_fail git rebase -m --onto A B && |
| 124 | test_must_fail git rebase --skip && |
| 125 | echo D > foo && |
| 126 | git add foo && |
| 127 | git rebase --continue && |
| 128 | echo rebase >expected.args && |
| 129 | cat >expected.data <<-EOF && |
| 130 | $(git rev-parse C) $(git rev-parse HEAD^) |
| 131 | $(git rev-parse D) $(git rev-parse HEAD) |
| 132 | EOF |
| 133 | verify_hook_input |
| 134 | ' |
| 135 | |
| 136 | test_expect_success 'git rebase with implicit use of merge backend' ' |
| 137 | git reset --hard D && |
| 138 | clear_hook_input && |
| 139 | test_must_fail git rebase --keep-empty --onto A B && |
| 140 | echo C > foo && |
| 141 | git add foo && |
| 142 | git rebase --continue && |
| 143 | echo rebase >expected.args && |
| 144 | cat >expected.data <<-EOF && |
| 145 | $(git rev-parse C) $(git rev-parse HEAD^) |
| 146 | $(git rev-parse D) $(git rev-parse HEAD) |
| 147 | EOF |
| 148 | verify_hook_input |
| 149 | ' |
| 150 | |
| 151 | test_expect_success 'git rebase --skip with implicit use of merge backend' ' |
| 152 | git reset --hard D && |
| 153 | clear_hook_input && |
| 154 | test_must_fail git rebase --keep-empty --onto A B && |
| 155 | test_must_fail git rebase --skip && |
| 156 | echo D > foo && |
| 157 | git add foo && |
| 158 | git rebase --continue && |
| 159 | echo rebase >expected.args && |
| 160 | cat >expected.data <<-EOF && |
| 161 | $(git rev-parse C) $(git rev-parse HEAD^) |
| 162 | $(git rev-parse D) $(git rev-parse HEAD) |
| 163 | EOF |
| 164 | verify_hook_input |
| 165 | ' |
| 166 | |
| 167 | . "$TEST_DIRECTORY"/lib-rebase.sh |
| 168 | |
| 169 | set_fake_editor |
| 170 | |
| 171 | # Helper to work around the lack of one-shot exporting for |
| 172 | # test_must_fail (as it is a shell function) |
| 173 | test_fail_interactive_rebase () { |
| 174 | ( |
| 175 | FAKE_LINES="$1" && |
| 176 | shift && |
| 177 | export FAKE_LINES && |
| 178 | test_must_fail git rebase -i "$@" |
| 179 | ) |
| 180 | } |
| 181 | |
| 182 | test_expect_success 'git rebase with failed pick' ' |
| 183 | clear_hook_input && |
| 184 | cat >todo <<-\EOF && |
| 185 | exec >bar |
| 186 | merge -C merge-E E |
| 187 | exec >G |
| 188 | pick G |
| 189 | exec >H 2>I |
| 190 | pick H |
| 191 | fixup I |
| 192 | EOF |
| 193 | |
| 194 | ( |
| 195 | set_replace_editor todo && |
| 196 | test_must_fail git rebase -i D D 2>err |
| 197 | ) && |
| 198 | test_grep "would be overwritten" err && |
| 199 | rm bar && |
| 200 | |
| 201 | test_must_fail git rebase --continue 2>err && |
| 202 | test_grep "would be overwritten" err && |
| 203 | rm G && |
| 204 | |
| 205 | test_must_fail git rebase --continue 2>err && |
| 206 | test_grep "would be overwritten" err && |
| 207 | rm H && |
| 208 | |
| 209 | test_must_fail git rebase --continue 2>err && |
| 210 | test_grep "would be overwritten" err && |
| 211 | rm I && |
| 212 | |
| 213 | git rebase --continue && |
| 214 | echo rebase >expected.args && |
| 215 | cat >expected.data <<-EOF && |
| 216 | $(git rev-parse merge-E) $(git rev-parse HEAD~2) |
| 217 | $(git rev-parse G) $(git rev-parse HEAD~1) |
| 218 | $(git rev-parse H) $(git rev-parse HEAD) |
| 219 | $(git rev-parse I) $(git rev-parse HEAD) |
| 220 | EOF |
| 221 | verify_hook_input |
| 222 | ' |
| 223 | |
| 224 | test_expect_success 'git rebase -i (unchanged)' ' |
| 225 | git reset --hard D && |
| 226 | clear_hook_input && |
| 227 | test_fail_interactive_rebase "1 2" --onto A B && |
| 228 | echo C > foo && |
| 229 | git add foo && |
| 230 | git rebase --continue && |
| 231 | echo rebase >expected.args && |
| 232 | cat >expected.data <<-EOF && |
| 233 | $(git rev-parse C) $(git rev-parse HEAD^) |
| 234 | $(git rev-parse D) $(git rev-parse HEAD) |
| 235 | EOF |
| 236 | verify_hook_input |
| 237 | ' |
| 238 | |
| 239 | test_expect_success 'git rebase -i (skip)' ' |
| 240 | git reset --hard D && |
| 241 | clear_hook_input && |
| 242 | test_fail_interactive_rebase "2" --onto A B && |
| 243 | echo D > foo && |
| 244 | git add foo && |
| 245 | git rebase --continue && |
| 246 | echo rebase >expected.args && |
| 247 | cat >expected.data <<-EOF && |
| 248 | $(git rev-parse D) $(git rev-parse HEAD) |
| 249 | EOF |
| 250 | verify_hook_input |
| 251 | ' |
| 252 | |
| 253 | test_expect_success 'git rebase -i (squash)' ' |
| 254 | git reset --hard D && |
| 255 | clear_hook_input && |
| 256 | test_fail_interactive_rebase "1 squash 2" --onto A B && |
| 257 | echo C > foo && |
| 258 | git add foo && |
| 259 | git rebase --continue && |
| 260 | echo rebase >expected.args && |
| 261 | cat >expected.data <<-EOF && |
| 262 | $(git rev-parse C) $(git rev-parse HEAD) |
| 263 | $(git rev-parse D) $(git rev-parse HEAD) |
| 264 | EOF |
| 265 | verify_hook_input |
| 266 | ' |
| 267 | |
| 268 | test_expect_success 'git rebase -i (fixup without conflict)' ' |
| 269 | git reset --hard D && |
| 270 | clear_hook_input && |
| 271 | FAKE_LINES="1 fixup 2" git rebase -i B && |
| 272 | echo rebase >expected.args && |
| 273 | cat >expected.data <<-EOF && |
| 274 | $(git rev-parse C) $(git rev-parse HEAD) |
| 275 | $(git rev-parse D) $(git rev-parse HEAD) |
| 276 | EOF |
| 277 | verify_hook_input |
| 278 | ' |
| 279 | |
| 280 | test_expect_success 'git rebase -i (double edit)' ' |
| 281 | git reset --hard D && |
| 282 | clear_hook_input && |
| 283 | FAKE_LINES="edit 1 edit 2" git rebase -i B && |
| 284 | git rebase --continue && |
| 285 | echo something > foo && |
| 286 | git add foo && |
| 287 | git rebase --continue && |
| 288 | echo rebase >expected.args && |
| 289 | cat >expected.data <<-EOF && |
| 290 | $(git rev-parse C) $(git rev-parse HEAD^) |
| 291 | $(git rev-parse D) $(git rev-parse HEAD) |
| 292 | EOF |
| 293 | verify_hook_input |
| 294 | ' |
| 295 | |
| 296 | test_expect_success 'git rebase -i (exec)' ' |
| 297 | git reset --hard D && |
| 298 | clear_hook_input && |
| 299 | FAKE_LINES="edit 1 exec_false 2" git rebase -i B && |
| 300 | echo something >bar && |
| 301 | git add bar && |
| 302 | # Fails because of exec false |
| 303 | test_must_fail git rebase --continue && |
| 304 | git rebase --continue && |
| 305 | echo rebase >expected.args && |
| 306 | cat >expected.data <<-EOF && |
| 307 | $(git rev-parse C) $(git rev-parse HEAD^) |
| 308 | $(git rev-parse D) $(git rev-parse HEAD) |
| 309 | EOF |
| 310 | verify_hook_input |
| 311 | ' |
| 312 | |
| 313 | test_expect_success 'rebase with commits that become empty' ' |
| 314 | cat >todo <<-\EOF && |
| 315 | pick H |
| 316 | pick E |
| 317 | fixup I |
| 318 | fixup H |
| 319 | pick G |
| 320 | pick I |
| 321 | EOF |
| 322 | ( |
| 323 | set_replace_editor todo && |
| 324 | git rebase -i --empty=drop A A |
| 325 | ) && |
| 326 | echo rebase >expected.args && |
| 327 | cat >expected.data <<-EOF && |
| 328 | $(git rev-parse H) $(git rev-parse HEAD~2) |
| 329 | $(git rev-parse E) $(git rev-parse HEAD~1) |
| 330 | $(git rev-parse I) $(git rev-parse HEAD~1) |
| 331 | $(git rev-parse G) $(git rev-parse HEAD) |
| 332 | EOF |
| 333 | verify_hook_input |
| 334 | ' |
| 335 | |
| 336 | test_done |