t / t3507-cherry-pick-conflict.shon commit Merge branch 'nd/war-on-nul-in-commit' (f35ccd9)
   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 'failed cherry-pick sets CHERRY_PICK_HEAD' '
  63        pristine_detach initial &&
  64        test_must_fail git cherry-pick picked &&
  65        test_cmp_rev picked CHERRY_PICK_HEAD
  66'
  67
  68test_expect_success 'successful cherry-pick does not set CHERRY_PICK_HEAD' '
  69        pristine_detach initial &&
  70        git cherry-pick base &&
  71        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
  72'
  73
  74test_expect_success 'cherry-pick --no-commit does not set CHERRY_PICK_HEAD' '
  75        pristine_detach initial &&
  76        git cherry-pick --no-commit base &&
  77        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
  78'
  79
  80test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' '
  81        pristine_detach initial &&
  82        echo foo > foo &&
  83        test_must_fail git cherry-pick base &&
  84        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
  85'
  86
  87test_expect_success \
  88        'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD' '
  89        pristine_detach initial &&
  90        echo foo > foo &&
  91        test_must_fail git cherry-pick --strategy=resolve base &&
  92        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
  93'
  94
  95test_expect_success 'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD' '
  96        pristine_detach initial &&
  97        (
  98                GIT_CHERRY_PICK_HELP="and then do something else" &&
  99                export GIT_CHERRY_PICK_HELP &&
 100                test_must_fail git cherry-pick picked
 101        ) &&
 102        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
 103'
 104
 105test_expect_success 'git reset clears CHERRY_PICK_HEAD' '
 106        pristine_detach initial &&
 107
 108        test_must_fail git cherry-pick picked &&
 109        git reset &&
 110
 111        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
 112'
 113
 114test_expect_success 'failed commit does not clear CHERRY_PICK_HEAD' '
 115        pristine_detach initial &&
 116
 117        test_must_fail git cherry-pick picked &&
 118        test_must_fail git commit &&
 119
 120        test_cmp_rev picked CHERRY_PICK_HEAD
 121'
 122
 123test_expect_success 'cancelled commit does not clear CHERRY_PICK_HEAD' '
 124        pristine_detach initial &&
 125
 126        test_must_fail git cherry-pick picked &&
 127        echo resolved >foo &&
 128        git add foo &&
 129        git update-index --refresh -q &&
 130        test_must_fail git diff-index --exit-code HEAD &&
 131        (
 132                GIT_EDITOR=false &&
 133                export GIT_EDITOR &&
 134                test_must_fail git commit
 135        ) &&
 136
 137        test_cmp_rev picked CHERRY_PICK_HEAD
 138'
 139
 140test_expect_success 'successful commit clears CHERRY_PICK_HEAD' '
 141        pristine_detach initial &&
 142
 143        test_must_fail git cherry-pick picked &&
 144        echo resolved >foo &&
 145        git add foo &&
 146        git commit &&
 147
 148        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
 149'
 150
 151test_expect_success 'failed cherry-pick produces dirty index' '
 152        pristine_detach initial &&
 153
 154        test_must_fail git cherry-pick picked &&
 155
 156        test_must_fail git update-index --refresh -q &&
 157        test_must_fail git diff-index --exit-code HEAD
 158'
 159
 160test_expect_success 'failed cherry-pick registers participants in index' '
 161        pristine_detach initial &&
 162        {
 163                git checkout base -- foo &&
 164                git ls-files --stage foo &&
 165                git checkout initial -- foo &&
 166                git ls-files --stage foo &&
 167                git checkout picked -- foo &&
 168                git ls-files --stage foo
 169        } > stages &&
 170        sed "
 171                1 s/ 0  / 1     /
 172                2 s/ 0  / 2     /
 173                3 s/ 0  / 3     /
 174        " < stages > expected &&
 175        git read-tree -u --reset HEAD &&
 176
 177        test_must_fail git cherry-pick picked &&
 178        git ls-files --stage --unmerged > actual &&
 179
 180        test_cmp expected actual
 181'
 182
 183test_expect_success 'failed cherry-pick describes conflict in work tree' '
 184        pristine_detach initial &&
 185        cat <<-EOF > expected &&
 186        <<<<<<< HEAD
 187        a
 188        =======
 189        c
 190        >>>>>>> objid picked
 191        EOF
 192
 193        test_must_fail git cherry-pick picked &&
 194
 195        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 196        test_cmp expected actual
 197'
 198
 199test_expect_success 'diff3 -m style' '
 200        pristine_detach initial &&
 201        git config merge.conflictstyle diff3 &&
 202        cat <<-EOF > expected &&
 203        <<<<<<< HEAD
 204        a
 205        ||||||| parent of objid picked
 206        b
 207        =======
 208        c
 209        >>>>>>> objid picked
 210        EOF
 211
 212        test_must_fail git cherry-pick picked &&
 213
 214        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 215        test_cmp expected actual
 216'
 217
 218test_expect_success 'revert also handles conflicts sanely' '
 219        git config --unset merge.conflictstyle &&
 220        pristine_detach initial &&
 221        cat <<-EOF > expected &&
 222        <<<<<<< HEAD
 223        a
 224        =======
 225        b
 226        >>>>>>> parent of objid picked
 227        EOF
 228        {
 229                git checkout picked -- foo &&
 230                git ls-files --stage foo &&
 231                git checkout initial -- foo &&
 232                git ls-files --stage foo &&
 233                git checkout base -- foo &&
 234                git ls-files --stage foo
 235        } > stages &&
 236        sed "
 237                1 s/ 0  / 1     /
 238                2 s/ 0  / 2     /
 239                3 s/ 0  / 3     /
 240        " < stages > expected-stages &&
 241        git read-tree -u --reset HEAD &&
 242
 243        head=$(git rev-parse HEAD) &&
 244        test_must_fail git revert picked &&
 245        newhead=$(git rev-parse HEAD) &&
 246        git ls-files --stage --unmerged > actual-stages &&
 247
 248        test "$head" = "$newhead" &&
 249        test_must_fail git update-index --refresh -q &&
 250        test_must_fail git diff-index --exit-code HEAD &&
 251        test_cmp expected-stages actual-stages &&
 252        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 253        test_cmp expected actual
 254'
 255
 256test_expect_success 'failed revert sets REVERT_HEAD' '
 257        pristine_detach initial &&
 258        test_must_fail git revert picked &&
 259        test_cmp_rev picked REVERT_HEAD
 260'
 261
 262test_expect_success 'successful revert does not set REVERT_HEAD' '
 263        pristine_detach base &&
 264        git revert base &&
 265        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
 266        test_must_fail git rev-parse --verify REVERT_HEAD
 267'
 268
 269test_expect_success 'revert --no-commit sets REVERT_HEAD' '
 270        pristine_detach base &&
 271        git revert --no-commit base &&
 272        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
 273        test_cmp_rev base REVERT_HEAD
 274'
 275
 276test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
 277        pristine_detach base &&
 278        echo foo > foo &&
 279        test_must_fail git revert base &&
 280        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
 281        test_must_fail git rev-parse --verify REVERT_HEAD
 282'
 283
 284test_expect_success 'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD' '
 285        pristine_detach initial &&
 286        (
 287                GIT_CHERRY_PICK_HELP="and then do something else" &&
 288                GIT_REVERT_HELP="and then do something else, again" &&
 289                export GIT_CHERRY_PICK_HELP GIT_REVERT_HELP &&
 290                test_must_fail git revert picked
 291        ) &&
 292        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
 293        test_cmp_rev picked REVERT_HEAD
 294'
 295
 296test_expect_success 'git reset clears REVERT_HEAD' '
 297        pristine_detach initial &&
 298        test_must_fail git revert picked &&
 299        git reset &&
 300        test_must_fail git rev-parse --verify REVERT_HEAD
 301'
 302
 303test_expect_success 'failed commit does not clear REVERT_HEAD' '
 304        pristine_detach initial &&
 305        test_must_fail git revert picked &&
 306        test_must_fail git commit &&
 307        test_cmp_rev picked REVERT_HEAD
 308'
 309
 310test_expect_success 'revert conflict, diff3 -m style' '
 311        pristine_detach initial &&
 312        git config merge.conflictstyle diff3 &&
 313        cat <<-EOF > expected &&
 314        <<<<<<< HEAD
 315        a
 316        ||||||| objid picked
 317        c
 318        =======
 319        b
 320        >>>>>>> parent of objid picked
 321        EOF
 322
 323        test_must_fail git revert picked &&
 324
 325        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 326        test_cmp expected actual
 327'
 328
 329test_done