t / t3510-cherry-pick-sequence.shon commit Merge branch 'lh/gitweb-site-html-head' (208a1cc)
   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 --reset &&
  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 '--reset does not complain when no cherry-pick is in progress' '
  74        pristine_detach initial &&
  75        git cherry-pick --reset
  76'
  77
  78test_expect_success '--reset cleans up sequencer state' '
  79        pristine_detach initial &&
  80        test_must_fail git cherry-pick base..picked &&
  81        git cherry-pick --reset &&
  82        test_path_is_missing .git/sequencer
  83'
  84
  85test_expect_success 'cherry-pick cleans up sequencer state when one commit is left' '
  86        pristine_detach initial &&
  87        test_must_fail git cherry-pick base..picked &&
  88        test_path_is_missing .git/sequencer &&
  89        echo "resolved" >foo &&
  90        git add foo &&
  91        git commit &&
  92        {
  93                git rev-list HEAD |
  94                git diff-tree --root --stdin |
  95                sed "s/$_x40/OBJID/g"
  96        } >actual &&
  97        cat >expect <<-\EOF &&
  98        OBJID
  99        :100644 100644 OBJID OBJID M    foo
 100        OBJID
 101        :100644 100644 OBJID OBJID M    unrelated
 102        OBJID
 103        :000000 100644 OBJID OBJID A    foo
 104        :000000 100644 OBJID OBJID A    unrelated
 105        EOF
 106        test_cmp expect actual
 107'
 108
 109test_expect_success 'cherry-pick does not implicitly stomp an existing operation' '
 110        pristine_detach initial &&
 111        test_must_fail git cherry-pick base..anotherpick &&
 112        test-chmtime -v +0 .git/sequencer >expect &&
 113        test_must_fail git cherry-pick unrelatedpick &&
 114        test-chmtime -v +0 .git/sequencer >actual &&
 115        test_cmp expect actual
 116'
 117
 118test_expect_success '--continue complains when no cherry-pick is in progress' '
 119        pristine_detach initial &&
 120        test_must_fail git cherry-pick --continue
 121'
 122
 123test_expect_success '--continue complains when there are unresolved conflicts' '
 124        pristine_detach initial &&
 125        test_must_fail git cherry-pick base..anotherpick &&
 126        test_must_fail git cherry-pick --continue
 127'
 128
 129test_expect_success '--continue continues after conflicts are resolved' '
 130        pristine_detach initial &&
 131        test_must_fail git cherry-pick base..anotherpick &&
 132        echo "c" >foo &&
 133        git add foo &&
 134        git commit &&
 135        git cherry-pick --continue &&
 136        test_path_is_missing .git/sequencer &&
 137        {
 138                git rev-list HEAD |
 139                git diff-tree --root --stdin |
 140                sed "s/$_x40/OBJID/g"
 141        } >actual &&
 142        cat >expect <<-\EOF &&
 143        OBJID
 144        :100644 100644 OBJID OBJID M    foo
 145        OBJID
 146        :100644 100644 OBJID OBJID M    foo
 147        OBJID
 148        :100644 100644 OBJID OBJID M    unrelated
 149        OBJID
 150        :000000 100644 OBJID OBJID A    foo
 151        :000000 100644 OBJID OBJID A    unrelated
 152        EOF
 153        test_cmp expect actual
 154'
 155
 156test_expect_success '--continue respects opts' '
 157        pristine_detach initial &&
 158        test_must_fail git cherry-pick -x base..anotherpick &&
 159        echo "c" >foo &&
 160        git add foo &&
 161        git commit &&
 162        git cherry-pick --continue &&
 163        test_path_is_missing .git/sequencer &&
 164        git cat-file commit HEAD >anotherpick_msg &&
 165        git cat-file commit HEAD~1 >picked_msg &&
 166        git cat-file commit HEAD~2 >unrelatedpick_msg &&
 167        git cat-file commit HEAD~3 >initial_msg &&
 168        test_must_fail grep "cherry picked from" initial_msg &&
 169        grep "cherry picked from" unrelatedpick_msg &&
 170        grep "cherry picked from" picked_msg &&
 171        grep "cherry picked from" anotherpick_msg
 172'
 173
 174test_expect_success '--signoff is not automatically propagated to resolved conflict' '
 175        pristine_detach initial &&
 176        test_must_fail git cherry-pick --signoff base..anotherpick &&
 177        echo "c" >foo &&
 178        git add foo &&
 179        git commit &&
 180        git cherry-pick --continue &&
 181        test_path_is_missing .git/sequencer &&
 182        git cat-file commit HEAD >anotherpick_msg &&
 183        git cat-file commit HEAD~1 >picked_msg &&
 184        git cat-file commit HEAD~2 >unrelatedpick_msg &&
 185        git cat-file commit HEAD~3 >initial_msg &&
 186        test_must_fail grep "Signed-off-by:" initial_msg &&
 187        grep "Signed-off-by:" unrelatedpick_msg &&
 188        test_must_fail grep "Signed-off-by:" picked_msg &&
 189        grep "Signed-off-by:" anotherpick_msg
 190'
 191
 192test_expect_success 'malformed instruction sheet 1' '
 193        pristine_detach initial &&
 194        test_must_fail git cherry-pick base..anotherpick &&
 195        echo "resolved" >foo &&
 196        git add foo &&
 197        git commit &&
 198        sed "s/pick /pick/" .git/sequencer/todo >new_sheet &&
 199        cp new_sheet .git/sequencer/todo &&
 200        test_must_fail git cherry-pick --continue
 201'
 202
 203test_expect_success 'malformed instruction sheet 2' '
 204        pristine_detach initial &&
 205        test_must_fail git cherry-pick base..anotherpick &&
 206        echo "resolved" >foo &&
 207        git add foo &&
 208        git commit &&
 209        sed "s/pick/revert/" .git/sequencer/todo >new_sheet &&
 210        cp new_sheet .git/sequencer/todo &&
 211        test_must_fail git cherry-pick --continue
 212'
 213
 214test_done