t / t3507-cherry-pick-conflict.shon commit Merge branch 'jk/untracked-cache-more-fixes' (5b5def9)
   1#!/bin/sh
   2
   3test_description='test cherry-pick and revert with conflicts
   4
   5  -
   6  + picked: rewrites foo to c
   7  + base: rewrites foo to b
   8  + initial: writes foo as a, unrelated as unrelated
   9
  10'
  11
  12. ./test-lib.sh
  13
  14pristine_detach () {
  15        git checkout -f "$1^0" &&
  16        git read-tree -u --reset HEAD &&
  17        git clean -d -f -f -q -x
  18}
  19
  20test_expect_success setup '
  21
  22        echo unrelated >unrelated &&
  23        git add unrelated &&
  24        test_commit initial foo a &&
  25        test_commit base foo b &&
  26        test_commit picked foo c &&
  27        test_commit --signoff picked-signed foo d &&
  28        git checkout -b topic initial &&
  29        test_commit redundant-pick foo c redundant &&
  30        git commit --allow-empty --allow-empty-message &&
  31        git tag empty &&
  32        git checkout master &&
  33        git config advice.detachedhead false
  34
  35'
  36
  37test_expect_success 'failed cherry-pick does not advance HEAD' '
  38        pristine_detach initial &&
  39
  40        head=$(git rev-parse HEAD) &&
  41        test_must_fail git cherry-pick picked &&
  42        newhead=$(git rev-parse HEAD) &&
  43
  44        test "$head" = "$newhead"
  45'
  46
  47test_expect_success 'advice from failed cherry-pick' "
  48        pristine_detach initial &&
  49
  50        picked=\$(git rev-parse --short picked) &&
  51        cat <<-EOF >expected &&
  52        error: could not apply \$picked... picked
  53        hint: after resolving the conflicts, mark the corrected paths
  54        hint: with 'git add <paths>' or 'git rm <paths>'
  55        hint: and commit the result with 'git commit'
  56        EOF
  57        test_must_fail git cherry-pick picked 2>actual &&
  58
  59        test_i18ncmp expected actual
  60"
  61
  62test_expect_success 'advice from failed cherry-pick --no-commit' "
  63        pristine_detach initial &&
  64
  65        picked=\$(git rev-parse --short picked) &&
  66        cat <<-EOF >expected &&
  67        error: could not apply \$picked... picked
  68        hint: after resolving the conflicts, mark the corrected paths
  69        hint: with 'git add <paths>' or 'git rm <paths>'
  70        EOF
  71        test_must_fail git cherry-pick --no-commit picked 2>actual &&
  72
  73        test_i18ncmp expected actual
  74"
  75
  76test_expect_success 'failed cherry-pick sets CHERRY_PICK_HEAD' '
  77        pristine_detach initial &&
  78        test_must_fail git cherry-pick picked &&
  79        test_cmp_rev picked CHERRY_PICK_HEAD
  80'
  81
  82test_expect_success 'successful cherry-pick does not set CHERRY_PICK_HEAD' '
  83        pristine_detach initial &&
  84        git cherry-pick base &&
  85        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
  86'
  87
  88test_expect_success 'cherry-pick --no-commit does not set CHERRY_PICK_HEAD' '
  89        pristine_detach initial &&
  90        git cherry-pick --no-commit base &&
  91        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
  92'
  93
  94test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' '
  95        pristine_detach initial &&
  96        echo foo >foo &&
  97        test_must_fail git cherry-pick base &&
  98        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
  99'
 100
 101test_expect_success \
 102        'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD' '
 103        pristine_detach initial &&
 104        echo foo >foo &&
 105        test_must_fail git cherry-pick --strategy=resolve base &&
 106        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
 107'
 108
 109test_expect_success 'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD' '
 110        pristine_detach initial &&
 111        (
 112                GIT_CHERRY_PICK_HELP="and then do something else" &&
 113                export GIT_CHERRY_PICK_HELP &&
 114                test_must_fail git cherry-pick picked
 115        ) &&
 116        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
 117'
 118
 119test_expect_success 'git reset clears CHERRY_PICK_HEAD' '
 120        pristine_detach initial &&
 121
 122        test_must_fail git cherry-pick picked &&
 123        git reset &&
 124
 125        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
 126'
 127
 128test_expect_success 'failed commit does not clear CHERRY_PICK_HEAD' '
 129        pristine_detach initial &&
 130
 131        test_must_fail git cherry-pick picked &&
 132        test_must_fail git commit &&
 133
 134        test_cmp_rev picked CHERRY_PICK_HEAD
 135'
 136
 137test_expect_success 'cancelled commit does not clear CHERRY_PICK_HEAD' '
 138        pristine_detach initial &&
 139
 140        test_must_fail git cherry-pick picked &&
 141        echo resolved >foo &&
 142        git add foo &&
 143        git update-index --refresh -q &&
 144        test_must_fail git diff-index --exit-code HEAD &&
 145        (
 146                GIT_EDITOR=false &&
 147                export GIT_EDITOR &&
 148                test_must_fail git commit
 149        ) &&
 150
 151        test_cmp_rev picked CHERRY_PICK_HEAD
 152'
 153
 154test_expect_success 'successful commit clears CHERRY_PICK_HEAD' '
 155        pristine_detach initial &&
 156
 157        test_must_fail git cherry-pick picked &&
 158        echo resolved >foo &&
 159        git add foo &&
 160        git commit &&
 161
 162        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
 163'
 164
 165test_expect_success 'failed cherry-pick produces dirty index' '
 166        pristine_detach initial &&
 167
 168        test_must_fail git cherry-pick picked &&
 169
 170        test_must_fail git update-index --refresh -q &&
 171        test_must_fail git diff-index --exit-code HEAD
 172'
 173
 174test_expect_success 'failed cherry-pick registers participants in index' '
 175        pristine_detach initial &&
 176        {
 177                git checkout base -- foo &&
 178                git ls-files --stage foo &&
 179                git checkout initial -- foo &&
 180                git ls-files --stage foo &&
 181                git checkout picked -- foo &&
 182                git ls-files --stage foo
 183        } >stages &&
 184        sed "
 185                1 s/ 0  / 1     /
 186                2 s/ 0  / 2     /
 187                3 s/ 0  / 3     /
 188        " stages >expected &&
 189        git read-tree -u --reset HEAD &&
 190
 191        test_must_fail git cherry-pick picked &&
 192        git ls-files --stage --unmerged >actual &&
 193
 194        test_cmp expected actual
 195'
 196
 197test_expect_success \
 198        'cherry-pick conflict, ensure commit.cleanup = scissors places scissors line properly' '
 199        pristine_detach initial &&
 200        git config commit.cleanup scissors &&
 201        cat <<-EOF >expected &&
 202                picked
 203
 204                # ------------------------ >8 ------------------------
 205                # Do not modify or remove the line above.
 206                # Everything below it will be ignored.
 207                #
 208                # Conflicts:
 209                #       foo
 210                EOF
 211
 212        test_must_fail git cherry-pick picked &&
 213
 214        test_i18ncmp expected .git/MERGE_MSG
 215'
 216
 217test_expect_success \
 218        'cherry-pick conflict, ensure cleanup=scissors places scissors line properly' '
 219        pristine_detach initial &&
 220        git config --unset commit.cleanup &&
 221        cat <<-EOF >expected &&
 222                picked
 223
 224                # ------------------------ >8 ------------------------
 225                # Do not modify or remove the line above.
 226                # Everything below it will be ignored.
 227                #
 228                # Conflicts:
 229                #       foo
 230                EOF
 231
 232        test_must_fail git cherry-pick --cleanup=scissors picked &&
 233
 234        test_i18ncmp expected .git/MERGE_MSG
 235'
 236
 237test_expect_success 'failed cherry-pick describes conflict in work tree' '
 238        pristine_detach initial &&
 239        cat <<-EOF >expected &&
 240        <<<<<<< HEAD
 241        a
 242        =======
 243        c
 244        >>>>>>> objid picked
 245        EOF
 246
 247        test_must_fail git cherry-pick picked &&
 248
 249        sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
 250        test_cmp expected actual
 251'
 252
 253test_expect_success 'diff3 -m style' '
 254        pristine_detach initial &&
 255        git config merge.conflictstyle diff3 &&
 256        cat <<-EOF >expected &&
 257        <<<<<<< HEAD
 258        a
 259        ||||||| parent of objid picked
 260        b
 261        =======
 262        c
 263        >>>>>>> objid picked
 264        EOF
 265
 266        test_must_fail git cherry-pick picked &&
 267
 268        sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
 269        test_cmp expected actual
 270'
 271
 272test_expect_success 'revert also handles conflicts sanely' '
 273        git config --unset merge.conflictstyle &&
 274        pristine_detach initial &&
 275        cat <<-EOF >expected &&
 276        <<<<<<< HEAD
 277        a
 278        =======
 279        b
 280        >>>>>>> parent of objid picked
 281        EOF
 282        {
 283                git checkout picked -- foo &&
 284                git ls-files --stage foo &&
 285                git checkout initial -- foo &&
 286                git ls-files --stage foo &&
 287                git checkout base -- foo &&
 288                git ls-files --stage foo
 289        } >stages &&
 290        sed "
 291                1 s/ 0  / 1     /
 292                2 s/ 0  / 2     /
 293                3 s/ 0  / 3     /
 294        " stages >expected-stages &&
 295        git read-tree -u --reset HEAD &&
 296
 297        head=$(git rev-parse HEAD) &&
 298        test_must_fail git revert picked &&
 299        newhead=$(git rev-parse HEAD) &&
 300        git ls-files --stage --unmerged >actual-stages &&
 301
 302        test "$head" = "$newhead" &&
 303        test_must_fail git update-index --refresh -q &&
 304        test_must_fail git diff-index --exit-code HEAD &&
 305        test_cmp expected-stages actual-stages &&
 306        sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
 307        test_cmp expected actual
 308'
 309
 310test_expect_success 'failed revert sets REVERT_HEAD' '
 311        pristine_detach initial &&
 312        test_must_fail git revert picked &&
 313        test_cmp_rev picked REVERT_HEAD
 314'
 315
 316test_expect_success 'successful revert does not set REVERT_HEAD' '
 317        pristine_detach base &&
 318        git revert base &&
 319        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
 320        test_must_fail git rev-parse --verify REVERT_HEAD
 321'
 322
 323test_expect_success 'revert --no-commit sets REVERT_HEAD' '
 324        pristine_detach base &&
 325        git revert --no-commit base &&
 326        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
 327        test_cmp_rev base REVERT_HEAD
 328'
 329
 330test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
 331        pristine_detach base &&
 332        echo foo >foo &&
 333        test_must_fail git revert base &&
 334        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
 335        test_must_fail git rev-parse --verify REVERT_HEAD
 336'
 337
 338test_expect_success 'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD' '
 339        pristine_detach initial &&
 340        (
 341                GIT_CHERRY_PICK_HELP="and then do something else" &&
 342                GIT_REVERT_HELP="and then do something else, again" &&
 343                export GIT_CHERRY_PICK_HELP GIT_REVERT_HELP &&
 344                test_must_fail git revert picked
 345        ) &&
 346        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
 347        test_cmp_rev picked REVERT_HEAD
 348'
 349
 350test_expect_success 'git reset clears REVERT_HEAD' '
 351        pristine_detach initial &&
 352        test_must_fail git revert picked &&
 353        git reset &&
 354        test_must_fail git rev-parse --verify REVERT_HEAD
 355'
 356
 357test_expect_success 'failed commit does not clear REVERT_HEAD' '
 358        pristine_detach initial &&
 359        test_must_fail git revert picked &&
 360        test_must_fail git commit &&
 361        test_cmp_rev picked REVERT_HEAD
 362'
 363
 364test_expect_success 'revert conflict, diff3 -m style' '
 365        pristine_detach initial &&
 366        git config merge.conflictstyle diff3 &&
 367        cat <<-EOF >expected &&
 368        <<<<<<< HEAD
 369        a
 370        ||||||| objid picked
 371        c
 372        =======
 373        b
 374        >>>>>>> parent of objid picked
 375        EOF
 376
 377        test_must_fail git revert picked &&
 378
 379        sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
 380        test_cmp expected actual
 381'
 382
 383test_expect_success \
 384        'revert conflict, ensure commit.cleanup = scissors places scissors line properly' '
 385        pristine_detach initial &&
 386        git config commit.cleanup scissors &&
 387        cat >expected <<-EOF &&
 388                Revert "picked"
 389
 390                This reverts commit OBJID.
 391
 392                # ------------------------ >8 ------------------------
 393                # Do not modify or remove the line above.
 394                # Everything below it will be ignored.
 395                #
 396                # Conflicts:
 397                #       foo
 398                EOF
 399
 400        test_must_fail git revert picked &&
 401
 402        sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
 403        test_i18ncmp expected actual
 404'
 405
 406test_expect_success \
 407        'revert conflict, ensure cleanup=scissors places scissors line properly' '
 408        pristine_detach initial &&
 409        git config --unset commit.cleanup &&
 410        cat >expected <<-EOF &&
 411                Revert "picked"
 412
 413                This reverts commit OBJID.
 414
 415                # ------------------------ >8 ------------------------
 416                # Do not modify or remove the line above.
 417                # Everything below it will be ignored.
 418                #
 419                # Conflicts:
 420                #       foo
 421                EOF
 422
 423        test_must_fail git revert --cleanup=scissors picked &&
 424
 425        sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
 426        test_i18ncmp expected actual
 427'
 428
 429test_expect_success 'failed cherry-pick does not forget -s' '
 430        pristine_detach initial &&
 431        test_must_fail git cherry-pick -s picked &&
 432        test_i18ngrep -e "Signed-off-by" .git/MERGE_MSG
 433'
 434
 435test_expect_success 'commit after failed cherry-pick does not add duplicated -s' '
 436        pristine_detach initial &&
 437        test_must_fail git cherry-pick -s picked-signed &&
 438        git commit -a -s &&
 439        test $(git show -s >tmp && grep -c "Signed-off-by" tmp && rm tmp) = 1
 440'
 441
 442test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
 443        pristine_detach initial &&
 444        test_must_fail git cherry-pick picked &&
 445
 446        git commit -a -s &&
 447
 448        # Do S-o-b and Conflicts appear in the right order?
 449        cat <<-\EOF >expect &&
 450        Signed-off-by: C O Mitter <committer@example.com>
 451        # Conflicts:
 452        EOF
 453        grep -e "^# Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual &&
 454        test_cmp expect actual &&
 455
 456        cat <<-\EOF >expected &&
 457        picked
 458
 459        Signed-off-by: C O Mitter <committer@example.com>
 460        EOF
 461
 462        git show -s --pretty=format:%B >actual &&
 463        test_cmp expected actual
 464'
 465
 466test_expect_success 'commit --amend -s places the sign-off at the right place' '
 467        pristine_detach initial &&
 468        test_must_fail git cherry-pick picked &&
 469
 470        # emulate old-style conflicts block
 471        mv .git/MERGE_MSG .git/MERGE_MSG+ &&
 472        sed -e "/^# Conflicts:/,\$s/^# *//" .git/MERGE_MSG+ >.git/MERGE_MSG &&
 473
 474        git commit -a &&
 475        git commit --amend -s &&
 476
 477        # Do S-o-b and Conflicts appear in the right order?
 478        cat <<-\EOF >expect &&
 479        Signed-off-by: C O Mitter <committer@example.com>
 480        Conflicts:
 481        EOF
 482        grep -e "^Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual &&
 483        test_cmp expect actual
 484'
 485
 486test_expect_success 'cherry-pick preserves sparse-checkout' '
 487        pristine_detach initial &&
 488        test_config core.sparseCheckout true &&
 489        test_when_finished "
 490                echo \"/*\" >.git/info/sparse-checkout
 491                git read-tree --reset -u HEAD
 492                rm .git/info/sparse-checkout" &&
 493        echo /unrelated >.git/info/sparse-checkout &&
 494        git read-tree --reset -u HEAD &&
 495        test_must_fail git cherry-pick -Xours picked>actual &&
 496        test_i18ngrep ! "Changes not staged for commit:" actual
 497'
 498
 499test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '
 500        test_when_finished "git cherry-pick --abort || :" &&
 501        pristine_detach initial &&
 502        test_must_fail git cherry-pick --keep-redundant-commits picked redundant &&
 503        echo c >foo &&
 504        git add foo &&
 505        git cherry-pick --continue
 506'
 507
 508test_expect_success 'cherry-pick --continue remembers --allow-empty and --allow-empty-message' '
 509        test_when_finished "git cherry-pick --abort || :" &&
 510        pristine_detach initial &&
 511        test_must_fail git cherry-pick --allow-empty --allow-empty-message \
 512                                       picked empty &&
 513        echo c >foo &&
 514        git add foo &&
 515        git cherry-pick --continue
 516'
 517
 518test_done