1
+#!/bin/sh
2
+
3
+test_description='git checkout --patch'
4
+
5
+. ./lib-patch-mode.sh
6
+
7
+test_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
+
21
+test_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
+
28
+test_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
+
34
+test_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
+
41
+test_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
+
48
+test_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
+
54
+test_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
+
62
+test_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
+
74
+test_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
+
81
+test_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
+
88
+test_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
+
95
+test_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
+
103
+test_expect_success 'none of this moved HEAD' '
104
+ verify_saved_head
105
+'
106
+
107
+test_done