t / t3415-rebase-autosquash.shon commit general improvements (43abf13)
   1#!/bin/sh
   2
   3test_description='auto squash'
   4
   5. ./test-lib.sh
   6
   7. "$TEST_DIRECTORY"/lib-rebase.sh
   8
   9test_expect_success setup '
  10        echo 0 >file0 &&
  11        git add . &&
  12        test_tick &&
  13        git commit -m "initial commit" &&
  14        echo 0 >file1 &&
  15        echo 2 >file2 &&
  16        git add . &&
  17        test_tick &&
  18        git commit -m "first commit" &&
  19        git tag first-commit &&
  20        echo 3 >file3 &&
  21        git add . &&
  22        test_tick &&
  23        git commit -m "second commit" &&
  24        git tag base
  25'
  26
  27test_auto_fixup () {
  28        git reset --hard base &&
  29        echo 1 >file1 &&
  30        git add -u &&
  31        test_tick &&
  32        git commit -m "fixup! first" &&
  33
  34        git tag $1 &&
  35        test_tick &&
  36        git rebase $2 -i HEAD^^^ &&
  37        git log --oneline >actual &&
  38        test_line_count = 3 actual &&
  39        git diff --exit-code $1 &&
  40        test 1 = "$(git cat-file blob HEAD^:file1)" &&
  41        test 1 = $(git cat-file commit HEAD^ | grep first | wc -l)
  42}
  43
  44test_expect_success 'auto fixup (option)' '
  45        test_auto_fixup final-fixup-option --autosquash
  46'
  47
  48test_expect_success 'auto fixup (config)' '
  49        git config rebase.autosquash true &&
  50        test_auto_fixup final-fixup-config-true &&
  51        test_must_fail test_auto_fixup fixup-config-true-no --no-autosquash &&
  52        git config rebase.autosquash false &&
  53        test_must_fail test_auto_fixup final-fixup-config-false
  54'
  55
  56test_auto_squash () {
  57        git reset --hard base &&
  58        echo 1 >file1 &&
  59        git add -u &&
  60        test_tick &&
  61        git commit -m "squash! first" &&
  62
  63        git tag $1 &&
  64        test_tick &&
  65        git rebase $2 -i HEAD^^^ &&
  66        git log --oneline >actual &&
  67        test_line_count = 3 actual &&
  68        git diff --exit-code $1 &&
  69        test 1 = "$(git cat-file blob HEAD^:file1)" &&
  70        test 2 = $(git cat-file commit HEAD^ | grep first | wc -l)
  71}
  72
  73test_expect_success 'auto squash (option)' '
  74        test_auto_squash final-squash --autosquash
  75'
  76
  77test_expect_success 'auto squash (config)' '
  78        git config rebase.autosquash true &&
  79        test_auto_squash final-squash-config-true &&
  80        test_must_fail test_auto_squash squash-config-true-no --no-autosquash &&
  81        git config rebase.autosquash false &&
  82        test_must_fail test_auto_squash final-squash-config-false
  83'
  84
  85test_expect_success 'misspelled auto squash' '
  86        git reset --hard base &&
  87        echo 1 >file1 &&
  88        git add -u &&
  89        test_tick &&
  90        git commit -m "squash! forst" &&
  91        git tag final-missquash &&
  92        test_tick &&
  93        git rebase --autosquash -i HEAD^^^ &&
  94        git log --oneline >actual &&
  95        test_line_count = 4 actual &&
  96        git diff --exit-code final-missquash &&
  97        test 0 = $(git rev-list final-missquash...HEAD | wc -l)
  98'
  99
 100test_expect_success 'auto squash that matches 2 commits' '
 101        git reset --hard base &&
 102        echo 4 >file4 &&
 103        git add file4 &&
 104        test_tick &&
 105        git commit -m "first new commit" &&
 106        echo 1 >file1 &&
 107        git add -u &&
 108        test_tick &&
 109        git commit -m "squash! first" &&
 110        git tag final-multisquash &&
 111        test_tick &&
 112        git rebase --autosquash -i HEAD~4 &&
 113        git log --oneline >actual &&
 114        test_line_count = 4 actual &&
 115        git diff --exit-code final-multisquash &&
 116        test 1 = "$(git cat-file blob HEAD^^:file1)" &&
 117        test 2 = $(git cat-file commit HEAD^^ | grep first | wc -l) &&
 118        test 1 = $(git cat-file commit HEAD | grep first | wc -l)
 119'
 120
 121test_expect_success 'auto squash that matches a commit after the squash' '
 122        git reset --hard base &&
 123        echo 1 >file1 &&
 124        git add -u &&
 125        test_tick &&
 126        git commit -m "squash! third" &&
 127        echo 4 >file4 &&
 128        git add file4 &&
 129        test_tick &&
 130        git commit -m "third commit" &&
 131        git tag final-presquash &&
 132        test_tick &&
 133        git rebase --autosquash -i HEAD~4 &&
 134        git log --oneline >actual &&
 135        test_line_count = 5 actual &&
 136        git diff --exit-code final-presquash &&
 137        test 0 = "$(git cat-file blob HEAD^^:file1)" &&
 138        test 1 = "$(git cat-file blob HEAD^:file1)" &&
 139        test 1 = $(git cat-file commit HEAD | grep third | wc -l) &&
 140        test 1 = $(git cat-file commit HEAD^ | grep third | wc -l)
 141'
 142test_expect_success 'auto squash that matches a sha1' '
 143        git reset --hard base &&
 144        echo 1 >file1 &&
 145        git add -u &&
 146        test_tick &&
 147        git commit -m "squash! $(git rev-parse --short HEAD^)" &&
 148        git tag final-shasquash &&
 149        test_tick &&
 150        git rebase --autosquash -i HEAD^^^ &&
 151        git log --oneline >actual &&
 152        test_line_count = 3 actual &&
 153        git diff --exit-code final-shasquash &&
 154        test 1 = "$(git cat-file blob HEAD^:file1)" &&
 155        test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)
 156'
 157
 158test_expect_success 'auto squash that matches longer sha1' '
 159        git reset --hard base &&
 160        echo 1 >file1 &&
 161        git add -u &&
 162        test_tick &&
 163        git commit -m "squash! $(git rev-parse --short=11 HEAD^)" &&
 164        git tag final-longshasquash &&
 165        test_tick &&
 166        git rebase --autosquash -i HEAD^^^ &&
 167        git log --oneline >actual &&
 168        test_line_count = 3 actual &&
 169        git diff --exit-code final-longshasquash &&
 170        test 1 = "$(git cat-file blob HEAD^:file1)" &&
 171        test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)
 172'
 173
 174test_auto_commit_flags () {
 175        git reset --hard base &&
 176        echo 1 >file1 &&
 177        git add -u &&
 178        test_tick &&
 179        git commit --$1 first-commit &&
 180        git tag final-commit-$1 &&
 181        test_tick &&
 182        git rebase --autosquash -i HEAD^^^ &&
 183        git log --oneline >actual &&
 184        test_line_count = 3 actual &&
 185        git diff --exit-code final-commit-$1 &&
 186        test 1 = "$(git cat-file blob HEAD^:file1)" &&
 187        test $2 = $(git cat-file commit HEAD^ | grep first | wc -l)
 188}
 189
 190test_expect_success 'use commit --fixup' '
 191        test_auto_commit_flags fixup 1
 192'
 193
 194test_expect_success 'use commit --squash' '
 195        test_auto_commit_flags squash 2
 196'
 197
 198test_auto_fixup_fixup () {
 199        git reset --hard base &&
 200        echo 1 >file1 &&
 201        git add -u &&
 202        test_tick &&
 203        git commit -m "$1! first" &&
 204        echo 2 >file1 &&
 205        git add -u &&
 206        test_tick &&
 207        git commit -m "$1! $2! first" &&
 208        git tag "final-$1-$2" &&
 209        test_tick &&
 210        (
 211                set_cat_todo_editor &&
 212                test_must_fail git rebase --autosquash -i HEAD^^^^ >actual &&
 213                cat >expected <<-EOF &&
 214                pick $(git rev-parse --short HEAD^^^) first commit
 215                $1 $(git rev-parse --short HEAD^) $1! first
 216                $1 $(git rev-parse --short HEAD) $1! $2! first
 217                pick $(git rev-parse --short HEAD^^) second commit
 218                EOF
 219                test_cmp expected actual
 220        ) &&
 221        git rebase --autosquash -i HEAD^^^^ &&
 222        git log --oneline >actual &&
 223        test_line_count = 3 actual
 224        git diff --exit-code "final-$1-$2" &&
 225        test 2 = "$(git cat-file blob HEAD^:file1)" &&
 226        if test "$1" = "fixup"
 227        then
 228                test 1 = $(git cat-file commit HEAD^ | grep first | wc -l)
 229        elif test "$1" = "squash"
 230        then
 231                test 3 = $(git cat-file commit HEAD^ | grep first | wc -l)
 232        else
 233                false
 234        fi
 235}
 236
 237test_expect_success C_LOCALE_OUTPUT 'fixup! fixup!' '
 238        test_auto_fixup_fixup fixup fixup
 239'
 240
 241test_expect_success C_LOCALE_OUTPUT 'fixup! squash!' '
 242        test_auto_fixup_fixup fixup squash
 243'
 244
 245test_expect_success C_LOCALE_OUTPUT 'squash! squash!' '
 246        test_auto_fixup_fixup squash squash
 247'
 248
 249test_expect_success C_LOCALE_OUTPUT 'squash! fixup!' '
 250        test_auto_fixup_fixup squash fixup
 251'
 252
 253test_expect_success C_LOCALE_OUTPUT 'autosquash with custom inst format' '
 254        git reset --hard base &&
 255        git config --add rebase.instructionFormat "[%an @ %ar] %s"  &&
 256        echo 2 >file1 &&
 257        git add -u &&
 258        test_tick &&
 259        git commit -m "squash! $(git rev-parse --short HEAD^)" &&
 260        echo 1 >file1 &&
 261        git add -u &&
 262        test_tick &&
 263        git commit -m "squash! $(git log -n 1 --format=%s HEAD~2)" &&
 264        git tag final-squash-instFmt &&
 265        test_tick &&
 266        git rebase --autosquash -i HEAD~4 &&
 267        git log --oneline >actual &&
 268        test_line_count = 3 actual &&
 269        git diff --exit-code final-squash-instFmt &&
 270        test 1 = "$(git cat-file blob HEAD^:file1)" &&
 271        test 2 = $(git cat-file commit HEAD^ | grep squash | wc -l)
 272'
 273
 274test_expect_success 'autosquash with empty custom instructionFormat' '
 275        git reset --hard base &&
 276        test_commit empty-instructionFormat-test &&
 277        (
 278                set_cat_todo_editor &&
 279                test_must_fail git -c rebase.instructionFormat= \
 280                        rebase --autosquash  --force-rebase -i HEAD^ >actual &&
 281                git log -1 --format="pick %h %s" >expect &&
 282                test_cmp expect actual
 283        )
 284'
 285
 286set_backup_editor () {
 287        write_script backup-editor.sh <<-\EOF
 288        cp "$1" .git/backup-"$(basename "$1")"
 289        EOF
 290        test_set_editor "$PWD/backup-editor.sh"
 291}
 292
 293test_expect_success 'autosquash with multiple empty patches' '
 294        test_tick &&
 295        git commit --allow-empty -m "empty" &&
 296        test_tick &&
 297        git commit --allow-empty -m "empty2" &&
 298        test_tick &&
 299        >fixup &&
 300        git add fixup &&
 301        git commit --fixup HEAD^^ &&
 302        (
 303                set_backup_editor &&
 304                GIT_USE_REBASE_HELPER=false \
 305                git rebase -i --force-rebase --autosquash HEAD~4 &&
 306                grep empty2 .git/backup-git-rebase-todo
 307        )
 308'
 309
 310test_expect_success 'extra spaces after fixup!' '
 311        base=$(git rev-parse HEAD) &&
 312        test_commit to-fixup &&
 313        git commit --allow-empty -m "fixup!  to-fixup" &&
 314        git rebase -i --autosquash --keep-empty HEAD~2 &&
 315        parent=$(git rev-parse HEAD^) &&
 316        test $base = $parent
 317'
 318
 319test_expect_success 'wrapped original subject' '
 320        if test -d .git/rebase-merge; then git rebase --abort; fi &&
 321        base=$(git rev-parse HEAD) &&
 322        echo "wrapped subject" >wrapped &&
 323        git add wrapped &&
 324        test_tick &&
 325        git commit --allow-empty -m "$(printf "To\nfixup")" &&
 326        test_tick &&
 327        git commit --allow-empty -m "fixup! To fixup" &&
 328        git rebase -i --autosquash --keep-empty HEAD~2 &&
 329        parent=$(git rev-parse HEAD^) &&
 330        test $base = $parent
 331'
 332
 333test_expect_success 'abort last squash' '
 334        test_when_finished "test_might_fail git rebase --abort" &&
 335        test_when_finished "git checkout master" &&
 336
 337        git checkout -b some-squashes &&
 338        git commit --allow-empty -m first &&
 339        git commit --allow-empty --squash HEAD &&
 340        git commit --allow-empty -m second &&
 341        git commit --allow-empty --squash HEAD &&
 342
 343        test_must_fail git -c core.editor="grep -q ^pick" \
 344                rebase -ki --autosquash HEAD~4 &&
 345        : do not finish the squash, but resolve it manually &&
 346        git commit --allow-empty --amend -m edited-first &&
 347        git rebase --skip &&
 348        git show >actual &&
 349        ! grep first actual
 350'
 351
 352test_done