bb67cdcb5d8b0ddb611ea112258e6f9b35896851
   1#!/bin/sh
   2
   3test_description='Test cherry-pick continuation features
   4
   5  + anotherpick: rewrites foo to d
   6  + picked: rewrites foo to c
   7  + unrelatedpick: rewrites unrelated to reallyunrelated
   8  + base: rewrites foo to b
   9  + initial: writes foo as a, unrelated as unrelated
  10
  11'
  12
  13. ./test-lib.sh
  14
  15pristine_detach () {
  16        git cherry-pick --quit &&
  17        git checkout -f "$1^0" &&
  18        git read-tree -u --reset HEAD &&
  19        git clean -d -f -f -q -x
  20}
  21
  22test_expect_success setup '
  23        echo unrelated >unrelated &&
  24        git add unrelated &&
  25        test_commit initial foo a &&
  26        test_commit base foo b &&
  27        test_commit unrelatedpick unrelated reallyunrelated &&
  28        test_commit picked foo c &&
  29        test_commit anotherpick foo d &&
  30        git config advice.detachedhead false
  31
  32'
  33
  34test_expect_success 'cherry-pick persists data on failure' '
  35        pristine_detach initial &&
  36        test_must_fail git cherry-pick -s base..anotherpick &&
  37        test_path_is_dir .git/sequencer &&
  38        test_path_is_file .git/sequencer/head &&
  39        test_path_is_file .git/sequencer/todo &&
  40        test_path_is_file .git/sequencer/opts
  41'
  42
  43test_expect_success 'cherry-pick persists opts correctly' '
  44        pristine_detach initial &&
  45        test_must_fail git cherry-pick -s -m 1 --strategy=recursive -X patience -X ours base..anotherpick &&
  46        test_path_is_dir .git/sequencer &&
  47        test_path_is_file .git/sequencer/head &&
  48        test_path_is_file .git/sequencer/todo &&
  49        test_path_is_file .git/sequencer/opts &&
  50        echo "true" >expect &&
  51        git config --file=.git/sequencer/opts --get-all options.signoff >actual &&
  52        test_cmp expect actual &&
  53        echo "1" >expect &&
  54        git config --file=.git/sequencer/opts --get-all options.mainline >actual &&
  55        test_cmp expect actual &&
  56        echo "recursive" >expect &&
  57        git config --file=.git/sequencer/opts --get-all options.strategy >actual &&
  58        test_cmp expect actual &&
  59        cat >expect <<-\EOF &&
  60        patience
  61        ours
  62        EOF
  63        git config --file=.git/sequencer/opts --get-all options.strategy-option >actual &&
  64        test_cmp expect actual
  65'
  66
  67test_expect_success 'cherry-pick cleans up sequencer state upon success' '
  68        pristine_detach initial &&
  69        git cherry-pick initial..picked &&
  70        test_path_is_missing .git/sequencer
  71'
  72
  73test_expect_success '--quit does not complain when no cherry-pick is in progress' '
  74        pristine_detach initial &&
  75        git cherry-pick --quit
  76'
  77
  78test_expect_success '--quit cleans up sequencer state' '
  79        pristine_detach initial &&
  80        test_must_fail git cherry-pick base..picked &&
  81        git cherry-pick --quit &&
  82        test_path_is_missing .git/sequencer
  83'
  84
  85test_expect_success 'cherry-pick --reset (another name for --quit)' '
  86        pristine_detach initial &&
  87        cat >expect <<-\EOF &&
  88        OBJID
  89        :100644 100644 OBJID OBJID M    unrelated
  90        OBJID
  91        :000000 100644 OBJID OBJID A    foo
  92        :000000 100644 OBJID OBJID A    unrelated
  93        EOF
  94        test_must_fail git cherry-pick base..picked &&
  95        git cherry-pick --reset &&
  96        test_path_is_missing .git/sequencer &&
  97        test_must_fail git update-index --refresh &&
  98        {
  99                git rev-list HEAD |
 100                git diff-tree --root --stdin |
 101                sed "s/$_x40/OBJID/g"
 102        } >actual &&
 103        test_cmp expect actual
 104'
 105
 106test_expect_success 'cherry-pick cleans up sequencer state when one commit is left' '
 107        pristine_detach initial &&
 108        test_must_fail git cherry-pick base..picked &&
 109        test_path_is_missing .git/sequencer &&
 110        echo "resolved" >foo &&
 111        git add foo &&
 112        git commit &&
 113        {
 114                git rev-list HEAD |
 115                git diff-tree --root --stdin |
 116                sed "s/$_x40/OBJID/g"
 117        } >actual &&
 118        cat >expect <<-\EOF &&
 119        OBJID
 120        :100644 100644 OBJID OBJID M    foo
 121        OBJID
 122        :100644 100644 OBJID OBJID M    unrelated
 123        OBJID
 124        :000000 100644 OBJID OBJID A    foo
 125        :000000 100644 OBJID OBJID A    unrelated
 126        EOF
 127        test_cmp expect actual
 128'
 129
 130test_expect_success 'cherry-pick does not implicitly stomp an existing operation' '
 131        pristine_detach initial &&
 132        test_must_fail git cherry-pick base..anotherpick &&
 133        test-chmtime -v +0 .git/sequencer >expect &&
 134        test_must_fail git cherry-pick unrelatedpick &&
 135        test-chmtime -v +0 .git/sequencer >actual &&
 136        test_cmp expect actual
 137'
 138
 139test_expect_success '--continue complains when no cherry-pick is in progress' '
 140        pristine_detach initial &&
 141        test_must_fail git cherry-pick --continue
 142'
 143
 144test_expect_success '--continue complains when there are unresolved conflicts' '
 145        pristine_detach initial &&
 146        test_must_fail git cherry-pick base..anotherpick &&
 147        test_must_fail git cherry-pick --continue
 148'
 149
 150test_expect_success '--continue continues after conflicts are resolved' '
 151        pristine_detach initial &&
 152        test_must_fail git cherry-pick base..anotherpick &&
 153        echo "c" >foo &&
 154        git add foo &&
 155        git commit &&
 156        git cherry-pick --continue &&
 157        test_path_is_missing .git/sequencer &&
 158        {
 159                git rev-list HEAD |
 160                git diff-tree --root --stdin |
 161                sed "s/$_x40/OBJID/g"
 162        } >actual &&
 163        cat >expect <<-\EOF &&
 164        OBJID
 165        :100644 100644 OBJID OBJID M    foo
 166        OBJID
 167        :100644 100644 OBJID OBJID M    foo
 168        OBJID
 169        :100644 100644 OBJID OBJID M    unrelated
 170        OBJID
 171        :000000 100644 OBJID OBJID A    foo
 172        :000000 100644 OBJID OBJID A    unrelated
 173        EOF
 174        test_cmp expect actual
 175'
 176
 177test_expect_success '--continue respects opts' '
 178        pristine_detach initial &&
 179        test_must_fail git cherry-pick -x base..anotherpick &&
 180        echo "c" >foo &&
 181        git add foo &&
 182        git commit &&
 183        git cherry-pick --continue &&
 184        test_path_is_missing .git/sequencer &&
 185        git cat-file commit HEAD >anotherpick_msg &&
 186        git cat-file commit HEAD~1 >picked_msg &&
 187        git cat-file commit HEAD~2 >unrelatedpick_msg &&
 188        git cat-file commit HEAD~3 >initial_msg &&
 189        test_must_fail grep "cherry picked from" initial_msg &&
 190        grep "cherry picked from" unrelatedpick_msg &&
 191        grep "cherry picked from" picked_msg &&
 192        grep "cherry picked from" anotherpick_msg
 193'
 194
 195test_expect_success '--signoff is not automatically propagated to resolved conflict' '
 196        pristine_detach initial &&
 197        test_must_fail git cherry-pick --signoff base..anotherpick &&
 198        echo "c" >foo &&
 199        git add foo &&
 200        git commit &&
 201        git cherry-pick --continue &&
 202        test_path_is_missing .git/sequencer &&
 203        git cat-file commit HEAD >anotherpick_msg &&
 204        git cat-file commit HEAD~1 >picked_msg &&
 205        git cat-file commit HEAD~2 >unrelatedpick_msg &&
 206        git cat-file commit HEAD~3 >initial_msg &&
 207        test_must_fail grep "Signed-off-by:" initial_msg &&
 208        grep "Signed-off-by:" unrelatedpick_msg &&
 209        test_must_fail grep "Signed-off-by:" picked_msg &&
 210        grep "Signed-off-by:" anotherpick_msg
 211'
 212
 213test_expect_success 'malformed instruction sheet 1' '
 214        pristine_detach initial &&
 215        test_must_fail git cherry-pick base..anotherpick &&
 216        echo "resolved" >foo &&
 217        git add foo &&
 218        git commit &&
 219        sed "s/pick /pick/" .git/sequencer/todo >new_sheet &&
 220        cp new_sheet .git/sequencer/todo &&
 221        test_must_fail git cherry-pick --continue
 222'
 223
 224test_expect_success 'malformed instruction sheet 2' '
 225        pristine_detach initial &&
 226        test_must_fail git cherry-pick base..anotherpick &&
 227        echo "resolved" >foo &&
 228        git add foo &&
 229        git commit &&
 230        sed "s/pick/revert/" .git/sequencer/todo >new_sheet &&
 231        cp new_sheet .git/sequencer/todo &&
 232        test_must_fail git cherry-pick --continue
 233'
 234
 235test_done