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 | dryrun=dryrun, cwd=cwd) |
|
1242 | dryrun=dryrun, cwd=cwd) | |
1243 | if rename and not dryrun: |
|
1243 | if rename and not dryrun: | |
1244 | if not after and srcexists and not samefile: |
|
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 | wctx.forget([abssrc]) |
|
1247 | wctx.forget([abssrc]) | |
1247 |
|
1248 | |||
1248 | # pat: ossep |
|
1249 | # pat: ossep | |
@@ -2269,7 +2270,9 b' def remove(ui, repo, m, prefix, after, f' | |||||
2269 | for f in list: |
|
2270 | for f in list: | |
2270 | if f in added: |
|
2271 | if f in added: | |
2271 | continue # we never unlink added files on remove |
|
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 | repo[None].forget(list) |
|
2276 | repo[None].forget(list) | |
2274 |
|
2277 | |||
2275 | if warn: |
|
2278 | if warn: | |
@@ -3029,7 +3032,8 b' def _performrevert(repo, parents, ctx, a' | |||||
3029 |
|
3032 | |||
3030 | def doremove(f): |
|
3033 | def doremove(f): | |
3031 | try: |
|
3034 | try: | |
3032 | repo.wvfs.unlinkpath(f) |
|
3035 | rmdir = repo.ui.configbool('experimental', 'removeemptydirs') | |
|
3036 | repo.wvfs.unlinkpath(f, rmdir=rmdir) | |||
3033 | except OSError: |
|
3037 | except OSError: | |
3034 | pass |
|
3038 | pass | |
3035 | repo.dirstate.remove(f) |
|
3039 | repo.dirstate.remove(f) |
@@ -566,6 +566,9 b" coreconfigitem('experimental', 'obsmarke" | |||||
566 | coreconfigitem('experimental', 'remotenames', |
|
566 | coreconfigitem('experimental', 'remotenames', | |
567 | default=False, |
|
567 | default=False, | |
568 | ) |
|
568 | ) | |
|
569 | coreconfigitem('experimental', 'removeemptydirs', | |||
|
570 | default=True, | |||
|
571 | ) | |||
569 | coreconfigitem('experimental', 'revlogv2', |
|
572 | coreconfigitem('experimental', 'revlogv2', | |
570 | default=None, |
|
573 | default=None, | |
571 | ) |
|
574 | ) |
@@ -1707,7 +1707,9 b' class workingfilectx(committablefilectx)' | |||||
1707 |
|
1707 | |||
1708 | def remove(self, ignoremissing=False): |
|
1708 | def remove(self, ignoremissing=False): | |
1709 | """wraps unlink for a repo's working directory""" |
|
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 | def write(self, data, flags, backgroundclose=False, **kwargs): |
|
1714 | def write(self, data, flags, backgroundclose=False, **kwargs): | |
1713 | """wraps repo.wwrite""" |
|
1715 | """wraps repo.wwrite""" |
@@ -497,7 +497,8 b' class fsbackend(abstractbackend):' | |||||
497 | self.opener.setflags(fname, False, True) |
|
497 | self.opener.setflags(fname, False, True) | |
498 |
|
498 | |||
499 | def unlink(self, fname): |
|
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 | def writerej(self, fname, failed, total, lines): |
|
503 | def writerej(self, fname, failed, total, lines): | |
503 | fname = fname + ".rej" |
|
504 | fname = fname + ".rej" |
@@ -2139,12 +2139,13 b' class atomictempfile(object):' | |||||
2139 | else: |
|
2139 | else: | |
2140 | self.close() |
|
2140 | self.close() | |
2141 |
|
2141 | |||
2142 | def unlinkpath(f, ignoremissing=False): |
|
2142 | def unlinkpath(f, ignoremissing=False, rmdir=True): | |
2143 | """unlink and remove the directory if it is empty""" |
|
2143 | """unlink and remove the directory if it is empty""" | |
2144 | if ignoremissing: |
|
2144 | if ignoremissing: | |
2145 | tryunlink(f) |
|
2145 | tryunlink(f) | |
2146 | else: |
|
2146 | else: | |
2147 | unlink(f) |
|
2147 | unlink(f) | |
|
2148 | if rmdir: | |||
2148 | # try removing directories that might now be empty |
|
2149 | # try removing directories that might now be empty | |
2149 | try: |
|
2150 | try: | |
2150 | removedirs(os.path.dirname(f)) |
|
2151 | removedirs(os.path.dirname(f)) |
@@ -246,8 +246,9 b' class abstractvfs(object):' | |||||
246 | """Attempt to remove a file, ignoring missing file errors.""" |
|
246 | """Attempt to remove a file, ignoring missing file errors.""" | |
247 | util.tryunlink(self.join(path)) |
|
247 | util.tryunlink(self.join(path)) | |
248 |
|
248 | |||
249 | def unlinkpath(self, path=None, ignoremissing=False): |
|
249 | def unlinkpath(self, path=None, ignoremissing=False, rmdir=True): | |
250 |
return util.unlinkpath(self.join(path), ignoremissing=ignoremissing |
|
250 | return util.unlinkpath(self.join(path), ignoremissing=ignoremissing, | |
|
251 | rmdir=rmdir) | |||
251 |
|
252 | |||
252 | def utime(self, path=None, t=None): |
|
253 | def utime(self, path=None, t=None): | |
253 | return os.utime(self.join(path), t) |
|
254 | return os.utime(self.join(path), t) |
General Comments 0
You need to be logged in to leave comments.
Login now