Show More
@@ -0,0 +1,242 b'' | |||
|
1 | Tests for experimental.removeemptydirs | |
|
2 | ||
|
3 | $ NO_RM=--config=experimental.removeemptydirs=0 | |
|
4 | $ isdir() { if [ -d $1 ]; then echo yes; else echo no; fi } | |
|
5 | $ isfile() { if [ -f $1 ]; then echo yes; else echo no; fi } | |
|
6 | ||
|
7 | `hg rm` of the last file in a directory: | |
|
8 | $ hg init hgrm | |
|
9 | $ cd hgrm | |
|
10 | $ mkdir somedir | |
|
11 | $ echo hi > somedir/foo | |
|
12 | $ hg ci -qAm foo | |
|
13 | $ isdir somedir | |
|
14 | yes | |
|
15 | $ hg rm somedir/foo | |
|
16 | $ isdir somedir | |
|
17 | no | |
|
18 | $ hg revert -qa | |
|
19 | $ isdir somedir | |
|
20 | yes | |
|
21 | $ hg $NO_RM rm somedir/foo | |
|
22 | $ isdir somedir | |
|
23 | yes | |
|
24 | $ ls somedir | |
|
25 | $ cd $TESTTMP | |
|
26 | ||
|
27 | `hg mv` of the last file in a directory: | |
|
28 | $ hg init hgmv | |
|
29 | $ cd hgmv | |
|
30 | $ mkdir somedir | |
|
31 | $ mkdir destdir | |
|
32 | $ echo hi > somedir/foo | |
|
33 | $ hg ci -qAm foo | |
|
34 | $ isdir somedir | |
|
35 | yes | |
|
36 | $ hg mv somedir/foo destdir/foo | |
|
37 | $ isdir somedir | |
|
38 | no | |
|
39 | $ hg revert -qa | |
|
40 | (revert doesn't get rid of destdir/foo?) | |
|
41 | $ rm destdir/foo | |
|
42 | $ isdir somedir | |
|
43 | yes | |
|
44 | $ hg $NO_RM mv somedir/foo destdir/foo | |
|
45 | $ isdir somedir | |
|
46 | yes | |
|
47 | $ ls somedir | |
|
48 | $ cd $TESTTMP | |
|
49 | ||
|
50 | Updating to a commit that doesn't have the directory: | |
|
51 | $ hg init hgupdate | |
|
52 | $ cd hgupdate | |
|
53 | $ echo hi > r0 | |
|
54 | $ hg ci -qAm r0 | |
|
55 | $ mkdir somedir | |
|
56 | $ echo hi > somedir/foo | |
|
57 | $ hg ci -qAm r1 | |
|
58 | $ isdir somedir | |
|
59 | yes | |
|
60 | $ hg co -q -r ".^" | |
|
61 | $ isdir somedir | |
|
62 | no | |
|
63 | $ hg co -q tip | |
|
64 | $ isdir somedir | |
|
65 | yes | |
|
66 | $ hg $NO_RM co -q -r ".^" | |
|
67 | $ isdir somedir | |
|
68 | yes | |
|
69 | $ ls somedir | |
|
70 | $ cd $TESTTMP | |
|
71 | ||
|
72 | Rebasing across a commit that doesn't have the directory, from inside the | |
|
73 | directory: | |
|
74 | $ hg init hgrebase | |
|
75 | $ cd hgrebase | |
|
76 | $ echo hi > r0 | |
|
77 | $ hg ci -qAm r0 | |
|
78 | $ mkdir somedir | |
|
79 | $ echo hi > somedir/foo | |
|
80 | $ hg ci -qAm first_rebase_source | |
|
81 | $ hg $NO_RM co -q -r ".^" | |
|
82 | $ echo hi > somedir/bar | |
|
83 | $ hg ci -qAm first_rebase_dest | |
|
84 | $ hg $NO_RM co -q -r ".^" | |
|
85 | $ echo hi > somedir/baz | |
|
86 | $ hg ci -qAm second_rebase_dest | |
|
87 | $ hg co -qr 'desc(first_rebase_source)' | |
|
88 | $ cd $TESTTMP/hgrebase/somedir | |
|
89 | $ hg --config extensions.rebase= rebase -qr . -d 'desc(first_rebase_dest)' | |
|
90 | current directory was removed | |
|
91 | (consider changing to repo root: $TESTTMP/hgrebase) | |
|
92 | $ cd $TESTTMP/hgrebase/somedir | |
|
93 | (The current node is the rebased first_rebase_source on top of | |
|
94 | first_rebase_dest) | |
|
95 | This should not output anything about current directory being removed: | |
|
96 | $ hg $NO_RM --config extensions.rebase= rebase -qr . -d 'desc(second_rebase_dest)' | |
|
97 | $ cd $TESTTMP | |
|
98 | ||
|
99 | Histediting across a commit that doesn't have the directory, from inside the | |
|
100 | directory (reordering nodes): | |
|
101 | $ hg init hghistedit | |
|
102 | $ cd hghistedit | |
|
103 | $ echo hi > r0 | |
|
104 | $ hg ci -qAm r0 | |
|
105 | $ echo hi > r1 | |
|
106 | $ hg ci -qAm r1 | |
|
107 | $ echo hi > r2 | |
|
108 | $ hg ci -qAm r2 | |
|
109 | $ mkdir somedir | |
|
110 | $ echo hi > somedir/foo | |
|
111 | $ hg ci -qAm migrating_revision | |
|
112 | $ cat > histedit_commands <<EOF | |
|
113 | > pick 89079fab8aee 0 r0 | |
|
114 | > pick e6d271df3142 1 r1 | |
|
115 | > pick 89e25aa83f0f 3 migrating_revision | |
|
116 | > pick b550aa12d873 2 r2 | |
|
117 | > EOF | |
|
118 | $ cd $TESTTMP/hghistedit/somedir | |
|
119 | $ hg --config extensions.histedit= histedit -q --commands ../histedit_commands | |
|
120 | ||
|
121 | histedit doesn't output anything when the current diretory is removed. We rely | |
|
122 | on the tests being commonly run on machines where the current directory | |
|
123 | disappearing from underneath us actually has an observable effect, such as an | |
|
124 | error or no files listed | |
|
125 | #if linuxormacos | |
|
126 | $ isfile foo | |
|
127 | no | |
|
128 | #endif | |
|
129 | $ cd $TESTTMP/hghistedit/somedir | |
|
130 | $ isfile foo | |
|
131 | yes | |
|
132 | ||
|
133 | $ cd $TESTTMP/hghistedit | |
|
134 | $ cat > histedit_commands <<EOF | |
|
135 | > pick 89079fab8aee 0 r0 | |
|
136 | > pick 7c7a22c6009f 3 migrating_revision | |
|
137 | > pick e6d271df3142 1 r1 | |
|
138 | > pick 40a53c2d4276 2 r2 | |
|
139 | > EOF | |
|
140 | $ cd $TESTTMP/hghistedit/somedir | |
|
141 | $ hg $NO_RM --config extensions.histedit= histedit -q --commands ../histedit_commands | |
|
142 | Regardless of system, we should always get a 'yes' here. | |
|
143 | $ isfile foo | |
|
144 | yes | |
|
145 | $ cd $TESTTMP | |
|
146 | ||
|
147 | This is essentially the exact test from issue5826, just cleaned up a little: | |
|
148 | ||
|
149 | $ hg init issue5826_withrm | |
|
150 | $ cd issue5826_withrm | |
|
151 | ||
|
152 | $ cat >> $HGRCPATH <<EOF | |
|
153 | > [extensions] | |
|
154 | > histedit = | |
|
155 | > EOF | |
|
156 | Commit three revisions that each create a directory: | |
|
157 | ||
|
158 | $ mkdir foo | |
|
159 | $ touch foo/bar | |
|
160 | $ hg commit -qAm "add foo" | |
|
161 | ||
|
162 | $ mkdir bar | |
|
163 | $ touch bar/bar | |
|
164 | $ hg commit -qAm "add bar" | |
|
165 | ||
|
166 | $ mkdir baz | |
|
167 | $ touch baz/bar | |
|
168 | $ hg commit -qAm "add baz" | |
|
169 | ||
|
170 | Enter the first directory: | |
|
171 | ||
|
172 | $ cd foo | |
|
173 | ||
|
174 | Histedit doing 'pick, pick, fold': | |
|
175 | ||
|
176 | $ hg histedit --commands /dev/stdin <<EOF | |
|
177 | > pick 6274c77c93c3 1 add bar | |
|
178 | > pick ff70a87b588f 0 add foo | |
|
179 | > fold 9992bb0ac0db 2 add baz | |
|
180 | > EOF | |
|
181 | abort: $ENOENT$ | |
|
182 | [255] | |
|
183 | ||
|
184 | Go back to the repo root after losing it as part of that operation: | |
|
185 | $ cd $TESTTMP/issue5826_withrm | |
|
186 | ||
|
187 | Note the lack of a non-zero exit code from this function - it exits | |
|
188 | successfully, but doesn't really do anything. | |
|
189 | $ hg histedit --continue | |
|
190 | 9992bb0ac0db: cannot fold - working copy is not a descendant of previous commit 5c806432464a | |
|
191 | saved backup bundle to $TESTTMP/issue5826_withrm/.hg/strip-backup/ff70a87b588f-e94f9789-histedit.hg | |
|
192 | ||
|
193 | $ hg log -T '{rev}:{node|short} {desc}\n' | |
|
194 | 2:94e3f9fae1d6 fold-temp-revision 9992bb0ac0db | |
|
195 | 1:5c806432464a add foo | |
|
196 | 0:d17db4b0303a add bar | |
|
197 | ||
|
198 | Now test that again with experimental.removeemptydirs=false: | |
|
199 | $ hg init issue5826_norm | |
|
200 | $ cd issue5826_norm | |
|
201 | ||
|
202 | $ cat >> $HGRCPATH <<EOF | |
|
203 | > [extensions] | |
|
204 | > histedit = | |
|
205 | > [experimental] | |
|
206 | > removeemptydirs = false | |
|
207 | > EOF | |
|
208 | Commit three revisions that each create a directory: | |
|
209 | ||
|
210 | $ mkdir foo | |
|
211 | $ touch foo/bar | |
|
212 | $ hg commit -qAm "add foo" | |
|
213 | ||
|
214 | $ mkdir bar | |
|
215 | $ touch bar/bar | |
|
216 | $ hg commit -qAm "add bar" | |
|
217 | ||
|
218 | $ mkdir baz | |
|
219 | $ touch baz/bar | |
|
220 | $ hg commit -qAm "add baz" | |
|
221 | ||
|
222 | Enter the first directory: | |
|
223 | ||
|
224 | $ cd foo | |
|
225 | ||
|
226 | Histedit doing 'pick, pick, fold': | |
|
227 | ||
|
228 | $ hg histedit --commands /dev/stdin <<EOF | |
|
229 | > pick 6274c77c93c3 1 add bar | |
|
230 | > pick ff70a87b588f 0 add foo | |
|
231 | > fold 9992bb0ac0db 2 add baz | |
|
232 | > EOF | |
|
233 | saved backup bundle to $TESTTMP/issue5826_withrm/issue5826_norm/.hg/strip-backup/5c806432464a-cd4c8d86-histedit.hg | |
|
234 | ||
|
235 | Note the lack of a 'cd' being necessary here, and we don't need to 'histedit | |
|
236 | --continue' | |
|
237 | ||
|
238 | $ hg log -T '{rev}:{node|short} {desc}\n' | |
|
239 | 1:b9eddaa97cbc add foo | |
|
240 | *** | |
|
241 | add baz | |
|
242 | 0:d17db4b0303a add bar |
@@ -1242,7 +1242,8 b' def copy(ui, repo, pats, opts, rename=Fa' | |||
|
1242 | 1242 | dryrun=dryrun, cwd=cwd) |
|
1243 | 1243 | if rename and not dryrun: |
|
1244 | 1244 | if not after and srcexists and not samefile: |
|
1245 | repo.wvfs.unlinkpath(abssrc) | |
|
1245 | rmdir = repo.ui.configbool('experimental', 'removeemptydirs') | |
|
1246 | repo.wvfs.unlinkpath(abssrc, rmdir=rmdir) | |
|
1246 | 1247 | wctx.forget([abssrc]) |
|
1247 | 1248 | |
|
1248 | 1249 | # pat: ossep |
@@ -2269,7 +2270,9 b' def remove(ui, repo, m, prefix, after, f' | |||
|
2269 | 2270 | for f in list: |
|
2270 | 2271 | if f in added: |
|
2271 | 2272 | continue # we never unlink added files on remove |
|
2272 | repo.wvfs.unlinkpath(f, ignoremissing=True) | |
|
2273 | rmdir = repo.ui.configbool('experimental', | |
|
2274 | 'removeemptydirs') | |
|
2275 | repo.wvfs.unlinkpath(f, ignoremissing=True, rmdir=rmdir) | |
|
2273 | 2276 | repo[None].forget(list) |
|
2274 | 2277 | |
|
2275 | 2278 | if warn: |
@@ -3029,7 +3032,8 b' def _performrevert(repo, parents, ctx, a' | |||
|
3029 | 3032 | |
|
3030 | 3033 | def doremove(f): |
|
3031 | 3034 | try: |
|
3032 | repo.wvfs.unlinkpath(f) | |
|
3035 | rmdir = repo.ui.configbool('experimental', 'removeemptydirs') | |
|
3036 | repo.wvfs.unlinkpath(f, rmdir=rmdir) | |
|
3033 | 3037 | except OSError: |
|
3034 | 3038 | pass |
|
3035 | 3039 | repo.dirstate.remove(f) |
@@ -566,6 +566,9 b" coreconfigitem('experimental', 'obsmarke" | |||
|
566 | 566 | coreconfigitem('experimental', 'remotenames', |
|
567 | 567 | default=False, |
|
568 | 568 | ) |
|
569 | coreconfigitem('experimental', 'removeemptydirs', | |
|
570 | default=True, | |
|
571 | ) | |
|
569 | 572 | coreconfigitem('experimental', 'revlogv2', |
|
570 | 573 | default=None, |
|
571 | 574 | ) |
@@ -1707,7 +1707,9 b' class workingfilectx(committablefilectx)' | |||
|
1707 | 1707 | |
|
1708 | 1708 | def remove(self, ignoremissing=False): |
|
1709 | 1709 | """wraps unlink for a repo's working directory""" |
|
1710 | self._repo.wvfs.unlinkpath(self._path, ignoremissing=ignoremissing) | |
|
1710 | rmdir = self._repo.ui.configbool('experimental', 'removeemptydirs') | |
|
1711 | self._repo.wvfs.unlinkpath(self._path, ignoremissing=ignoremissing, | |
|
1712 | rmdir=rmdir) | |
|
1711 | 1713 | |
|
1712 | 1714 | def write(self, data, flags, backgroundclose=False, **kwargs): |
|
1713 | 1715 | """wraps repo.wwrite""" |
@@ -497,7 +497,8 b' class fsbackend(abstractbackend):' | |||
|
497 | 497 | self.opener.setflags(fname, False, True) |
|
498 | 498 | |
|
499 | 499 | def unlink(self, fname): |
|
500 | self.opener.unlinkpath(fname, ignoremissing=True) | |
|
500 | rmdir = self.ui.configbool('experimental', 'removeemptydirs') | |
|
501 | self.opener.unlinkpath(fname, ignoremissing=True, rmdir=rmdir) | |
|
501 | 502 | |
|
502 | 503 | def writerej(self, fname, failed, total, lines): |
|
503 | 504 | fname = fname + ".rej" |
@@ -2139,17 +2139,18 b' class atomictempfile(object):' | |||
|
2139 | 2139 | else: |
|
2140 | 2140 | self.close() |
|
2141 | 2141 | |
|
2142 | def unlinkpath(f, ignoremissing=False): | |
|
2142 | def unlinkpath(f, ignoremissing=False, rmdir=True): | |
|
2143 | 2143 | """unlink and remove the directory if it is empty""" |
|
2144 | 2144 | if ignoremissing: |
|
2145 | 2145 | tryunlink(f) |
|
2146 | 2146 | else: |
|
2147 | 2147 | unlink(f) |
|
2148 | # try removing directories that might now be empty | |
|
2149 | try: | |
|
2150 | removedirs(os.path.dirname(f)) | |
|
2151 | except OSError: | |
|
2152 | pass | |
|
2148 | if rmdir: | |
|
2149 | # try removing directories that might now be empty | |
|
2150 | try: | |
|
2151 | removedirs(os.path.dirname(f)) | |
|
2152 | except OSError: | |
|
2153 | pass | |
|
2153 | 2154 | |
|
2154 | 2155 | def tryunlink(f): |
|
2155 | 2156 | """Attempt to remove a file, ignoring ENOENT errors.""" |
@@ -246,8 +246,9 b' class abstractvfs(object):' | |||
|
246 | 246 | """Attempt to remove a file, ignoring missing file errors.""" |
|
247 | 247 | util.tryunlink(self.join(path)) |
|
248 | 248 | |
|
249 | def unlinkpath(self, path=None, ignoremissing=False): | |
|
250 |
return util.unlinkpath(self.join(path), ignoremissing=ignoremissing |
|
|
249 | def unlinkpath(self, path=None, ignoremissing=False, rmdir=True): | |
|
250 | return util.unlinkpath(self.join(path), ignoremissing=ignoremissing, | |
|
251 | rmdir=rmdir) | |
|
251 | 252 | |
|
252 | 253 | def utime(self, path=None, t=None): |
|
253 | 254 | return os.utime(self.join(path), t) |
General Comments 0
You need to be logged in to leave comments.
Login now