t / t3507-cherry-pick-conflict.shon commit Merge branch 'km/empty-repo-is-still-a-repo' (4ab701b)
   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 'failed cherry-pick describes conflict in work tree' '
 198        pristine_detach initial &&
 199        cat <<-EOF > expected &&
 200        <<<<<<< HEAD
 201        a
 202        =======
 203        c
 204        >>>>>>> objid picked
 205        EOF
 206
 207        test_must_fail git cherry-pick picked &&
 208
 209        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 210        test_cmp expected actual
 211'
 212
 213test_expect_success 'diff3 -m style' '
 214        pristine_detach initial &&
 215        git config merge.conflictstyle diff3 &&
 216        cat <<-EOF > expected &&
 217        <<<<<<< HEAD
 218        a
 219        ||||||| parent of objid picked
 220        b
 221        =======
 222        c
 223        >>>>>>> objid picked
 224        EOF
 225
 226        test_must_fail git cherry-pick picked &&
 227
 228        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 229        test_cmp expected actual
 230'
 231
 232test_expect_success 'revert also handles conflicts sanely' '
 233        git config --unset merge.conflictstyle &&
 234        pristine_detach initial &&
 235        cat <<-EOF > expected &&
 236        <<<<<<< HEAD
 237        a
 238        =======
 239        b
 240        >>>>>>> parent of objid picked
 241        EOF
 242        {
 243                git checkout picked -- foo &&
 244                git ls-files --stage foo &&
 245                git checkout initial -- foo &&
 246                git ls-files --stage foo &&
 247                git checkout base -- foo &&
 248                git ls-files --stage foo
 249        } > stages &&
 250        sed "
 251                1 s/ 0  / 1     /
 252                2 s/ 0  / 2     /
 253                3 s/ 0  / 3     /
 254        " < stages > expected-stages &&
 255        git read-tree -u --reset HEAD &&
 256
 257        head=$(git rev-parse HEAD) &&
 258        test_must_fail git revert picked &&
 259        newhead=$(git rev-parse HEAD) &&
 260        git ls-files --stage --unmerged > actual-stages &&
 261
 262        test "$head" = "$newhead" &&
 263        test_must_fail git update-index --refresh -q &&
 264        test_must_fail git diff-index --exit-code HEAD &&
 265        test_cmp expected-stages actual-stages &&
 266        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 267        test_cmp expected actual
 268'
 269
 270test_expect_success 'failed revert sets REVERT_HEAD' '
 271        pristine_detach initial &&
 272        test_must_fail git revert picked &&
 273        test_cmp_rev picked REVERT_HEAD
 274'
 275
 276test_expect_success 'successful revert does not set REVERT_HEAD' '
 277        pristine_detach base &&
 278        git revert base &&
 279        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
 280        test_must_fail git rev-parse --verify REVERT_HEAD
 281'
 282
 283test_expect_success 'revert --no-commit sets REVERT_HEAD' '
 284        pristine_detach base &&
 285        git revert --no-commit base &&
 286        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
 287        test_cmp_rev base REVERT_HEAD
 288'
 289
 290test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
 291        pristine_detach base &&
 292        echo foo > foo &&
 293        test_must_fail git revert base &&
 294        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
 295        test_must_fail git rev-parse --verify REVERT_HEAD
 296'
 297
 298test_expect_success 'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD' '
 299        pristine_detach initial &&
 300        (
 301                GIT_CHERRY_PICK_HELP="and then do something else" &&
 302                GIT_REVERT_HELP="and then do something else, again" &&
 303                export GIT_CHERRY_PICK_HELP GIT_REVERT_HELP &&
 304                test_must_fail git revert picked
 305        ) &&
 306        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
 307        test_cmp_rev picked REVERT_HEAD
 308'
 309
 310test_expect_success 'git reset clears REVERT_HEAD' '
 311        pristine_detach initial &&
 312        test_must_fail git revert picked &&
 313        git reset &&
 314        test_must_fail git rev-parse --verify REVERT_HEAD
 315'
 316
 317test_expect_success 'failed commit does not clear REVERT_HEAD' '
 318        pristine_detach initial &&
 319        test_must_fail git revert picked &&
 320        test_must_fail git commit &&
 321        test_cmp_rev picked REVERT_HEAD
 322'
 323
 324test_expect_success 'revert conflict, diff3 -m style' '
 325        pristine_detach initial &&
 326        git config merge.conflictstyle diff3 &&
 327        cat <<-EOF > expected &&
 328        <<<<<<< HEAD
 329        a
 330        ||||||| objid picked
 331        c
 332        =======
 333        b
 334        >>>>>>> parent of objid picked
 335        EOF
 336
 337        test_must_fail git revert picked &&
 338
 339        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 340        test_cmp expected actual
 341'
 342
 343test_expect_success 'failed cherry-pick does not forget -s' '
 344        pristine_detach initial &&
 345        test_must_fail git cherry-pick -s picked &&
 346        test_i18ngrep -e "Signed-off-by" .git/MERGE_MSG
 347'
 348
 349test_expect_success 'commit after failed cherry-pick does not add duplicated -s' '
 350        pristine_detach initial &&
 351        test_must_fail git cherry-pick -s picked-signed &&
 352        git commit -a -s &&
 353        test $(git show -s |grep -c "Signed-off-by") = 1
 354'
 355
 356test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
 357        pristine_detach initial &&
 358        test_must_fail git cherry-pick picked &&
 359
 360        git commit -a -s &&
 361
 362        # Do S-o-b and Conflicts appear in the right order?
 363        cat <<-\EOF >expect &&
 364        Signed-off-by: C O Mitter <committer@example.com>
 365        # Conflicts:
 366        EOF
 367        grep -e "^# Conflicts:" -e '^Signed-off-by' <.git/COMMIT_EDITMSG >actual &&
 368        test_cmp expect actual &&
 369
 370        cat <<-\EOF >expected &&
 371        picked
 372
 373        Signed-off-by: C O Mitter <committer@example.com>
 374        EOF
 375
 376        git show -s --pretty=format:%B >actual &&
 377        test_cmp expected actual
 378'
 379
 380test_expect_success 'commit --amend -s places the sign-off at the right place' '
 381        pristine_detach initial &&
 382        test_must_fail git cherry-pick picked &&
 383
 384        # emulate old-style conflicts block
 385        mv .git/MERGE_MSG .git/MERGE_MSG+ &&
 386        sed -e "/^# Conflicts:/,\$s/^# *//" <.git/MERGE_MSG+ >.git/MERGE_MSG &&
 387
 388        git commit -a &&
 389        git commit --amend -s &&
 390
 391        # Do S-o-b and Conflicts appear in the right order?
 392        cat <<-\EOF >expect &&
 393        Signed-off-by: C O Mitter <committer@example.com>
 394        Conflicts:
 395        EOF
 396        grep -e "^Conflicts:" -e '^Signed-off-by' <.git/COMMIT_EDITMSG >actual &&
 397        test_cmp expect actual
 398'
 399
 400test_expect_success 'cherry-pick preserves sparse-checkout' '
 401        pristine_detach initial &&
 402        test_config core.sparseCheckout true &&
 403        test_when_finished "
 404                echo \"/*\" >.git/info/sparse-checkout
 405                git read-tree --reset -u HEAD
 406                rm .git/info/sparse-checkout" &&
 407        echo /unrelated >.git/info/sparse-checkout &&
 408        git read-tree --reset -u HEAD &&
 409        test_must_fail git cherry-pick -Xours picked>actual &&
 410        test_i18ngrep ! "Changes not staged for commit:" actual
 411'
 412
 413test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '
 414        test_when_finished "git cherry-pick --abort || :" &&
 415        pristine_detach initial &&
 416        test_must_fail git cherry-pick --keep-redundant-commits picked redundant &&
 417        echo c >foo &&
 418        git add foo &&
 419        git cherry-pick --continue
 420'
 421
 422test_expect_success 'cherry-pick --continue remembers --allow-empty and --allow-empty-message' '
 423        test_when_finished "git cherry-pick --abort || :" &&
 424        pristine_detach initial &&
 425        test_must_fail git cherry-pick --allow-empty --allow-empty-message \
 426                                       picked empty &&
 427        echo c >foo &&
 428        git add foo &&
 429        git cherry-pick --continue
 430'
 431
 432test_done