Skip to content

Commit 446cc55

Browse files
newrengitster
authored andcommitted
t2500: add various tests for nuking untracked files
Noting that unpack_trees treats reset=1 & update=1 as license to nuke untracked files, I looked for code paths that use this combination and tried to generate testcases which demonstrated unintentional loss of untracked files and directories. I found several. I also include testcases for `git reset --{hard,merge,keep}`. A hard reset is perhaps the most direct test of unpack_tree's reset=1 behavior, but we cannot make `git reset --hard` preserve untracked files without some migration work. Also, the two commands `checkout --force` (because of the --force) and `read-tree --reset` (because it's plumbing and we need to keep it backward compatible) were left out as we expect those to continue removing untracked files and directories. Signed-off-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 04d3761 commit 446cc55

File tree

1 file changed

+244
-0
lines changed

1 file changed

+244
-0
lines changed

t/t2500-untracked-overwriting.sh

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
#!/bin/sh
2+
3+
test_description='Test handling of overwriting untracked files'
4+
5+
. ./test-lib.sh
6+
7+
test_setup_reset () {
8+
git init reset_$1 &&
9+
(
10+
cd reset_$1 &&
11+
test_commit init &&
12+
13+
git branch stable &&
14+
git branch work &&
15+
16+
git checkout work &&
17+
test_commit foo &&
18+
19+
git checkout stable
20+
)
21+
}
22+
23+
test_expect_success 'reset --hard will nuke untracked files/dirs' '
24+
test_setup_reset hard &&
25+
(
26+
cd reset_hard &&
27+
git ls-tree -r stable &&
28+
git log --all --name-status --oneline &&
29+
git ls-tree -r work &&
30+
31+
mkdir foo.t &&
32+
echo precious >foo.t/file &&
33+
echo foo >expect &&
34+
35+
git reset --hard work &&
36+
37+
# check that untracked directory foo.t/ was nuked
38+
test_path_is_file foo.t &&
39+
test_cmp expect foo.t
40+
)
41+
'
42+
43+
test_expect_success 'reset --merge will preserve untracked files/dirs' '
44+
test_setup_reset merge &&
45+
(
46+
cd reset_merge &&
47+
48+
mkdir foo.t &&
49+
echo precious >foo.t/file &&
50+
cp foo.t/file expect &&
51+
52+
test_must_fail git reset --merge work 2>error &&
53+
test_cmp expect foo.t/file &&
54+
grep "Updating .foo.t. would lose untracked files" error
55+
)
56+
'
57+
58+
test_expect_success 'reset --keep will preserve untracked files/dirs' '
59+
test_setup_reset keep &&
60+
(
61+
cd reset_keep &&
62+
63+
mkdir foo.t &&
64+
echo precious >foo.t/file &&
65+
cp foo.t/file expect &&
66+
67+
test_must_fail git reset --merge work 2>error &&
68+
test_cmp expect foo.t/file &&
69+
grep "Updating.*foo.t.*would lose untracked files" error
70+
)
71+
'
72+
73+
test_setup_checkout_m () {
74+
git init checkout &&
75+
(
76+
cd checkout &&
77+
test_commit init &&
78+
79+
test_write_lines file has some >filler &&
80+
git add filler &&
81+
git commit -m filler &&
82+
83+
git branch stable &&
84+
85+
git switch -c work &&
86+
echo stuff >notes.txt &&
87+
test_write_lines file has some words >filler &&
88+
git add notes.txt filler &&
89+
git commit -m filler &&
90+
91+
git checkout stable
92+
)
93+
}
94+
95+
test_expect_failure 'checkout -m does not nuke untracked file' '
96+
test_setup_checkout_m &&
97+
(
98+
cd checkout &&
99+
100+
# Tweak filler
101+
test_write_lines this file has some >filler &&
102+
# Make an untracked file, save its contents in "expect"
103+
echo precious >notes.txt &&
104+
cp notes.txt expect &&
105+
106+
test_must_fail git checkout -m work &&
107+
test_cmp expect notes.txt
108+
)
109+
'
110+
111+
test_setup_sequencing () {
112+
git init sequencing_$1 &&
113+
(
114+
cd sequencing_$1 &&
115+
test_commit init &&
116+
117+
test_write_lines this file has some words >filler &&
118+
git add filler &&
119+
git commit -m filler &&
120+
121+
mkdir -p foo/bar &&
122+
test_commit foo/bar/baz &&
123+
124+
git branch simple &&
125+
git branch fooey &&
126+
127+
git checkout fooey &&
128+
git rm foo/bar/baz.t &&
129+
echo stuff >>filler &&
130+
git add -u &&
131+
git commit -m "changes" &&
132+
133+
git checkout simple &&
134+
echo items >>filler &&
135+
echo newstuff >>newfile &&
136+
git add filler newfile &&
137+
git commit -m another
138+
)
139+
}
140+
141+
test_expect_failure 'git rebase --abort and untracked files' '
142+
test_setup_sequencing rebase_abort_and_untracked &&
143+
(
144+
cd sequencing_rebase_abort_and_untracked &&
145+
git checkout fooey &&
146+
test_must_fail git rebase simple &&
147+
148+
cat init.t &&
149+
git rm init.t &&
150+
echo precious >init.t &&
151+
cp init.t expect &&
152+
git status --porcelain &&
153+
test_must_fail git rebase --abort &&
154+
test_cmp expect init.t
155+
)
156+
'
157+
158+
test_expect_failure 'git rebase fast forwarding and untracked files' '
159+
test_setup_sequencing rebase_fast_forward_and_untracked &&
160+
(
161+
cd sequencing_rebase_fast_forward_and_untracked &&
162+
git checkout init &&
163+
echo precious >filler &&
164+
cp filler expect &&
165+
test_must_fail git rebase init simple &&
166+
test_cmp expect filler
167+
)
168+
'
169+
170+
test_expect_failure 'git rebase --autostash and untracked files' '
171+
test_setup_sequencing rebase_autostash_and_untracked &&
172+
(
173+
cd sequencing_rebase_autostash_and_untracked &&
174+
git checkout simple &&
175+
git rm filler &&
176+
mkdir filler &&
177+
echo precious >filler/file &&
178+
cp filler/file expect &&
179+
git rebase --autostash init &&
180+
test_path_is_file filler/file
181+
)
182+
'
183+
184+
test_expect_failure 'git stash and untracked files' '
185+
test_setup_sequencing stash_and_untracked_files &&
186+
(
187+
cd sequencing_stash_and_untracked_files &&
188+
git checkout simple &&
189+
git rm filler &&
190+
mkdir filler &&
191+
echo precious >filler/file &&
192+
cp filler/file expect &&
193+
git status --porcelain &&
194+
git stash push &&
195+
git status --porcelain &&
196+
test_path_is_file filler/file
197+
)
198+
'
199+
200+
test_expect_failure 'git am --abort and untracked dir vs. unmerged file' '
201+
test_setup_sequencing am_abort_and_untracked &&
202+
(
203+
cd sequencing_am_abort_and_untracked &&
204+
git format-patch -1 --stdout fooey >changes.mbox &&
205+
test_must_fail git am --3way changes.mbox &&
206+
207+
# Delete the conflicted file; we will stage and commit it later
208+
rm filler &&
209+
210+
# Put an unrelated untracked directory there
211+
mkdir filler &&
212+
echo foo >filler/file1 &&
213+
echo bar >filler/file2 &&
214+
215+
test_must_fail git am --abort 2>errors &&
216+
test_path_is_dir filler &&
217+
grep "Updating .filler. would lose untracked files in it" errors
218+
)
219+
'
220+
221+
test_expect_failure 'git am --skip and untracked dir vs deleted file' '
222+
test_setup_sequencing am_skip_and_untracked &&
223+
(
224+
cd sequencing_am_skip_and_untracked &&
225+
git checkout fooey &&
226+
git format-patch -1 --stdout simple >changes.mbox &&
227+
test_must_fail git am --3way changes.mbox &&
228+
229+
# Delete newfile
230+
rm newfile &&
231+
232+
# Put an unrelated untracked directory there
233+
mkdir newfile &&
234+
echo foo >newfile/file1 &&
235+
echo bar >newfile/file2 &&
236+
237+
# Change our mind about resolutions, just skip this patch
238+
test_must_fail git am --skip 2>errors &&
239+
test_path_is_dir newfile &&
240+
grep "Updating .newfile. would lose untracked files in it" errors
241+
)
242+
'
243+
244+
test_done

0 commit comments

Comments
 (0)