2313d79bd417858911a9efbf99adaa57f03b5bd0
   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 -c \$picked'
  56        EOF
  57        test_must_fail git cherry-pick picked 2>actual &&
  58
  59        test_cmp expected actual
  60"
  61
  62test_expect_success 'failed cherry-pick produces dirty index' '
  63        pristine_detach initial &&
  64
  65        test_must_fail git cherry-pick picked &&
  66
  67        test_must_fail git update-index --refresh -q &&
  68        test_must_fail git diff-index --exit-code HEAD
  69'
  70
  71test_expect_success 'failed cherry-pick registers participants in index' '
  72        pristine_detach initial &&
  73        {
  74                git checkout base -- foo &&
  75                git ls-files --stage foo &&
  76                git checkout initial -- foo &&
  77                git ls-files --stage foo &&
  78                git checkout picked -- foo &&
  79                git ls-files --stage foo
  80        } > stages &&
  81        sed "
  82                1 s/ 0  / 1     /
  83                2 s/ 0  / 2     /
  84                3 s/ 0  / 3     /
  85        " < stages > expected &&
  86        git read-tree -u --reset HEAD &&
  87
  88        test_must_fail git cherry-pick picked &&
  89        git ls-files --stage --unmerged > actual &&
  90
  91        test_cmp expected actual
  92'
  93
  94test_expect_success 'failed cherry-pick describes conflict in work tree' '
  95        pristine_detach initial &&
  96        cat <<-EOF > expected &&
  97        <<<<<<< HEAD
  98        a
  99        =======
 100        c
 101        >>>>>>> objid picked
 102        EOF
 103
 104        test_must_fail git cherry-pick picked &&
 105
 106        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 107        test_cmp expected actual
 108'
 109
 110test_expect_success 'diff3 -m style' '
 111        pristine_detach initial &&
 112        git config merge.conflictstyle diff3 &&
 113        cat <<-EOF > expected &&
 114        <<<<<<< HEAD
 115        a
 116        ||||||| parent of objid picked
 117        b
 118        =======
 119        c
 120        >>>>>>> objid picked
 121        EOF
 122
 123        test_must_fail git cherry-pick picked &&
 124
 125        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 126        test_cmp expected actual
 127'
 128
 129test_expect_success 'revert also handles conflicts sanely' '
 130        git config --unset merge.conflictstyle &&
 131        pristine_detach initial &&
 132        cat <<-EOF > expected &&
 133        <<<<<<< HEAD
 134        a
 135        =======
 136        b
 137        >>>>>>> parent of objid picked
 138        EOF
 139        {
 140                git checkout picked -- foo &&
 141                git ls-files --stage foo &&
 142                git checkout initial -- foo &&
 143                git ls-files --stage foo &&
 144                git checkout base -- foo &&
 145                git ls-files --stage foo
 146        } > stages &&
 147        sed "
 148                1 s/ 0  / 1     /
 149                2 s/ 0  / 2     /
 150                3 s/ 0  / 3     /
 151        " < stages > expected-stages &&
 152        git read-tree -u --reset HEAD &&
 153
 154        head=$(git rev-parse HEAD) &&
 155        test_must_fail git revert picked &&
 156        newhead=$(git rev-parse HEAD) &&
 157        git ls-files --stage --unmerged > actual-stages &&
 158
 159        test "$head" = "$newhead" &&
 160        test_must_fail git update-index --refresh -q &&
 161        test_must_fail git diff-index --exit-code HEAD &&
 162        test_cmp expected-stages actual-stages &&
 163        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 164        test_cmp expected actual
 165'
 166
 167test_expect_success 'revert conflict, diff3 -m style' '
 168        pristine_detach initial &&
 169        git config merge.conflictstyle diff3 &&
 170        cat <<-EOF > expected &&
 171        <<<<<<< HEAD
 172        a
 173        ||||||| objid picked
 174        c
 175        =======
 176        b
 177        >>>>>>> parent of objid picked
 178        EOF
 179
 180        test_must_fail git revert picked &&
 181
 182        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 183        test_cmp expected actual
 184'
 185
 186test_done