t / t3507-cherry-pick-conflict.shon commit Merge branch 'dg/run-command-child-cleanup' into maint (cc84144)
   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
  14test_cmp_rev () {
  15        git rev-parse --verify "$1" >expect.rev &&
  16        git rev-parse --verify "$2" >actual.rev &&
  17        test_cmp expect.rev actual.rev
  18}
  19
  20pristine_detach () {
  21        git checkout -f "$1^0" &&
  22        git read-tree -u --reset HEAD &&
  23        git clean -d -f -f -q -x
  24}
  25
  26test_expect_success setup '
  27
  28        echo unrelated >unrelated &&
  29        git add unrelated &&
  30        test_commit initial foo a &&
  31        test_commit base foo b &&
  32        test_commit picked foo c &&
  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_done