t / t2016-checkout-patch.shon commit Merge branch 'maint' (01ddb1f)
   1#!/bin/sh
   2
   3test_description='git checkout --patch'
   4
   5. ./lib-patch-mode.sh
   6
   7test_expect_success 'setup' '
   8        mkdir dir &&
   9        echo parent > dir/foo &&
  10        echo dummy > bar &&
  11        git add bar dir/foo &&
  12        git commit -m initial &&
  13        test_tick &&
  14        test_commit second dir/foo head &&
  15        set_and_save_state bar bar_work bar_index &&
  16        save_head
  17'
  18
  19# note: bar sorts before dir/foo, so the first 'n' is always to skip 'bar'
  20
  21test_expect_success 'saying "n" does nothing' '
  22        set_and_save_state dir/foo work head &&
  23        (echo n; echo n) | git checkout -p &&
  24        verify_saved_state bar &&
  25        verify_saved_state dir/foo
  26'
  27
  28test_expect_success 'git checkout -p' '
  29        (echo n; echo y) | git checkout -p &&
  30        verify_saved_state bar &&
  31        verify_state dir/foo head head
  32'
  33
  34test_expect_success 'git checkout -p with staged changes' '
  35        set_state dir/foo work index
  36        (echo n; echo y) | git checkout -p &&
  37        verify_saved_state bar &&
  38        verify_state dir/foo index index
  39'
  40
  41test_expect_success 'git checkout -p HEAD with NO staged changes: abort' '
  42        set_and_save_state dir/foo work head &&
  43        (echo n; echo y; echo n) | git checkout -p HEAD &&
  44        verify_saved_state bar &&
  45        verify_saved_state dir/foo
  46'
  47
  48test_expect_success 'git checkout -p HEAD with NO staged changes: apply' '
  49        (echo n; echo y; echo y) | git checkout -p HEAD &&
  50        verify_saved_state bar &&
  51        verify_state dir/foo head head
  52'
  53
  54test_expect_success 'git checkout -p HEAD with change already staged' '
  55        set_state dir/foo index index
  56        # the third n is to get out in case it mistakenly does not apply
  57        (echo n; echo y; echo n) | git checkout -p HEAD &&
  58        verify_saved_state bar &&
  59        verify_state dir/foo head head
  60'
  61
  62test_expect_success 'git checkout -p HEAD^' '
  63        # the third n is to get out in case it mistakenly does not apply
  64        (echo n; echo y; echo n) | git checkout -p HEAD^ &&
  65        verify_saved_state bar &&
  66        verify_state dir/foo parent parent
  67'
  68
  69# The idea in the rest is that bar sorts first, so we always say 'y'
  70# first and if the path limiter fails it'll apply to bar instead of
  71# dir/foo.  There's always an extra 'n' to reject edits to dir/foo in
  72# the failure case (and thus get out of the loop).
  73
  74test_expect_success 'path limiting works: dir' '
  75        set_state dir/foo work head &&
  76        (echo y; echo n) | git checkout -p dir &&
  77        verify_saved_state bar &&
  78        verify_state dir/foo head head
  79'
  80
  81test_expect_success 'path limiting works: -- dir' '
  82        set_state dir/foo work head &&
  83        (echo y; echo n) | git checkout -p -- dir &&
  84        verify_saved_state bar &&
  85        verify_state dir/foo head head
  86'
  87
  88test_expect_success 'path limiting works: HEAD^ -- dir' '
  89        # the third n is to get out in case it mistakenly does not apply
  90        (echo y; echo n; echo n) | git checkout -p HEAD^ -- dir &&
  91        verify_saved_state bar &&
  92        verify_state dir/foo parent parent
  93'
  94
  95test_expect_success 'path limiting works: foo inside dir' '
  96        set_state dir/foo work head &&
  97        # the third n is to get out in case it mistakenly does not apply
  98        (echo y; echo n; echo n) | (cd dir && git checkout -p foo) &&
  99        verify_saved_state bar &&
 100        verify_state dir/foo head head
 101'
 102
 103test_expect_success 'none of this moved HEAD' '
 104        verify_saved_head
 105'
 106
 107test_done