t / t3507-cherry-pick-conflict.shon commit Merge branch 'jk/maint-fetch-submodule-check-fix' into maint (e2d0a2e)
   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 'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD' '
  81        pristine_detach initial &&
  82        (
  83                GIT_CHERRY_PICK_HELP="and then do something else" &&
  84                export GIT_CHERRY_PICK_HELP &&
  85                test_must_fail git cherry-pick picked
  86        ) &&
  87        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
  88'
  89
  90test_expect_success 'git reset clears CHERRY_PICK_HEAD' '
  91        pristine_detach initial &&
  92
  93        test_must_fail git cherry-pick picked &&
  94        git reset &&
  95
  96        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
  97'
  98
  99test_expect_success 'failed commit does not clear CHERRY_PICK_HEAD' '
 100        pristine_detach initial &&
 101
 102        test_must_fail git cherry-pick picked &&
 103        test_must_fail git commit &&
 104
 105        test_cmp_rev picked CHERRY_PICK_HEAD
 106'
 107
 108test_expect_success 'cancelled commit does not clear CHERRY_PICK_HEAD' '
 109        pristine_detach initial &&
 110
 111        test_must_fail git cherry-pick picked &&
 112        echo resolved >foo &&
 113        git add foo &&
 114        git update-index --refresh -q &&
 115        test_must_fail git diff-index --exit-code HEAD &&
 116        (
 117                GIT_EDITOR=false &&
 118                export GIT_EDITOR &&
 119                test_must_fail git commit
 120        ) &&
 121
 122        test_cmp_rev picked CHERRY_PICK_HEAD
 123'
 124
 125test_expect_success 'successful commit clears CHERRY_PICK_HEAD' '
 126        pristine_detach initial &&
 127
 128        test_must_fail git cherry-pick picked &&
 129        echo resolved >foo &&
 130        git add foo &&
 131        git commit &&
 132
 133        test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
 134'
 135
 136test_expect_success 'failed cherry-pick produces dirty index' '
 137        pristine_detach initial &&
 138
 139        test_must_fail git cherry-pick picked &&
 140
 141        test_must_fail git update-index --refresh -q &&
 142        test_must_fail git diff-index --exit-code HEAD
 143'
 144
 145test_expect_success 'failed cherry-pick registers participants in index' '
 146        pristine_detach initial &&
 147        {
 148                git checkout base -- foo &&
 149                git ls-files --stage foo &&
 150                git checkout initial -- foo &&
 151                git ls-files --stage foo &&
 152                git checkout picked -- foo &&
 153                git ls-files --stage foo
 154        } > stages &&
 155        sed "
 156                1 s/ 0  / 1     /
 157                2 s/ 0  / 2     /
 158                3 s/ 0  / 3     /
 159        " < stages > expected &&
 160        git read-tree -u --reset HEAD &&
 161
 162        test_must_fail git cherry-pick picked &&
 163        git ls-files --stage --unmerged > actual &&
 164
 165        test_cmp expected actual
 166'
 167
 168test_expect_success 'failed cherry-pick describes conflict in work tree' '
 169        pristine_detach initial &&
 170        cat <<-EOF > expected &&
 171        <<<<<<< HEAD
 172        a
 173        =======
 174        c
 175        >>>>>>> objid picked
 176        EOF
 177
 178        test_must_fail git cherry-pick picked &&
 179
 180        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 181        test_cmp expected actual
 182'
 183
 184test_expect_success 'diff3 -m style' '
 185        pristine_detach initial &&
 186        git config merge.conflictstyle diff3 &&
 187        cat <<-EOF > expected &&
 188        <<<<<<< HEAD
 189        a
 190        ||||||| parent of objid picked
 191        b
 192        =======
 193        c
 194        >>>>>>> objid picked
 195        EOF
 196
 197        test_must_fail git cherry-pick picked &&
 198
 199        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 200        test_cmp expected actual
 201'
 202
 203test_expect_success 'revert also handles conflicts sanely' '
 204        git config --unset merge.conflictstyle &&
 205        pristine_detach initial &&
 206        cat <<-EOF > expected &&
 207        <<<<<<< HEAD
 208        a
 209        =======
 210        b
 211        >>>>>>> parent of objid picked
 212        EOF
 213        {
 214                git checkout picked -- foo &&
 215                git ls-files --stage foo &&
 216                git checkout initial -- foo &&
 217                git ls-files --stage foo &&
 218                git checkout base -- foo &&
 219                git ls-files --stage foo
 220        } > stages &&
 221        sed "
 222                1 s/ 0  / 1     /
 223                2 s/ 0  / 2     /
 224                3 s/ 0  / 3     /
 225        " < stages > expected-stages &&
 226        git read-tree -u --reset HEAD &&
 227
 228        head=$(git rev-parse HEAD) &&
 229        test_must_fail git revert picked &&
 230        newhead=$(git rev-parse HEAD) &&
 231        git ls-files --stage --unmerged > actual-stages &&
 232
 233        test "$head" = "$newhead" &&
 234        test_must_fail git update-index --refresh -q &&
 235        test_must_fail git diff-index --exit-code HEAD &&
 236        test_cmp expected-stages actual-stages &&
 237        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 238        test_cmp expected actual
 239'
 240
 241test_expect_success 'revert conflict, diff3 -m style' '
 242        pristine_detach initial &&
 243        git config merge.conflictstyle diff3 &&
 244        cat <<-EOF > expected &&
 245        <<<<<<< HEAD
 246        a
 247        ||||||| objid picked
 248        c
 249        =======
 250        b
 251        >>>>>>> parent of objid picked
 252        EOF
 253
 254        test_must_fail git revert picked &&
 255
 256        sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
 257        test_cmp expected actual
 258'
 259
 260test_done