Mercurial > public > mercurial-scm > hg
annotate mercurial/dirstate.py @ 1224:cc61d366bc3b
Fix Windows status problem from new dirstate walk code
author | mpm@selenic.com |
---|---|
date | Thu, 08 Sep 2005 15:01:33 -0700 |
parents | d9e85a75dbda |
children | db950da49539 |
rev | line source |
---|---|
1089 | 1 """ |
2 dirstate.py - working directory tracking for mercurial | |
3 | |
4 Copyright 2005 Matt Mackall <mpm@selenic.com> | |
5 | |
6 This software may be used and distributed according to the terms | |
7 of the GNU General Public License, incorporated herein by reference. | |
8 """ | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
9 |
1094 | 10 import struct, os |
11 from node import * | |
262 | 12 from demandload import * |
1104 | 13 demandload(globals(), "time bisect stat util re") |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
14 |
220 | 15 class dirstate: |
244 | 16 def __init__(self, opener, ui, root): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
17 self.opener = opener |
244 | 18 self.root = root |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
19 self.dirty = 0 |
20 | 20 self.ui = ui |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
21 self.map = None |
227 | 22 self.pl = None |
363 | 23 self.copies = {} |
723 | 24 self.ignorefunc = None |
1183 | 25 self.blockignore = False |
723 | 26 |
27 def wjoin(self, f): | |
28 return os.path.join(self.root, f) | |
29 | |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
839
diff
changeset
|
30 def getcwd(self): |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
839
diff
changeset
|
31 cwd = os.getcwd() |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
839
diff
changeset
|
32 if cwd == self.root: return '' |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
839
diff
changeset
|
33 return cwd[len(self.root) + 1:] |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
839
diff
changeset
|
34 |
723 | 35 def ignore(self, f): |
1183 | 36 if self.blockignore: |
37 return False | |
723 | 38 if not self.ignorefunc: |
39 bigpat = [] | |
40 try: | |
41 l = file(self.wjoin(".hgignore")) | |
42 for pat in l: | |
911
d46af8e6b858
Fix .hgignore parsing if last line has no EOL, ignore trailing white space.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
903
diff
changeset
|
43 p = pat.rstrip() |
d46af8e6b858
Fix .hgignore parsing if last line has no EOL, ignore trailing white space.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
903
diff
changeset
|
44 if p: |
723 | 45 try: |
886
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
46 re.compile(p) |
723 | 47 except: |
48 self.ui.warn("ignoring invalid ignore" | |
49 + " regular expression '%s'\n" % p) | |
50 else: | |
886
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
51 bigpat.append(p) |
723 | 52 except IOError: pass |
53 | |
735
3433b228bbb3
An empty .hgignore file must cause us to ignore nothing, not everything!
Bryan O'Sullivan <bos@serpentine.com>
parents:
730
diff
changeset
|
54 if bigpat: |
3433b228bbb3
An empty .hgignore file must cause us to ignore nothing, not everything!
Bryan O'Sullivan <bos@serpentine.com>
parents:
730
diff
changeset
|
55 s = "(?:%s)" % (")|(?:".join(bigpat)) |
3433b228bbb3
An empty .hgignore file must cause us to ignore nothing, not everything!
Bryan O'Sullivan <bos@serpentine.com>
parents:
730
diff
changeset
|
56 r = re.compile(s) |
3433b228bbb3
An empty .hgignore file must cause us to ignore nothing, not everything!
Bryan O'Sullivan <bos@serpentine.com>
parents:
730
diff
changeset
|
57 self.ignorefunc = r.search |
3433b228bbb3
An empty .hgignore file must cause us to ignore nothing, not everything!
Bryan O'Sullivan <bos@serpentine.com>
parents:
730
diff
changeset
|
58 else: |
3433b228bbb3
An empty .hgignore file must cause us to ignore nothing, not everything!
Bryan O'Sullivan <bos@serpentine.com>
parents:
730
diff
changeset
|
59 self.ignorefunc = util.never |
723 | 60 |
61 return self.ignorefunc(f) | |
220 | 62 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
63 def __del__(self): |
220 | 64 if self.dirty: |
65 self.write() | |
66 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
67 def __getitem__(self, key): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
68 try: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
69 return self.map[key] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
70 except TypeError: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
71 self.read() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
72 return self[key] |
220 | 73 |
74 def __contains__(self, key): | |
75 if not self.map: self.read() | |
76 return key in self.map | |
77 | |
227 | 78 def parents(self): |
79 if not self.pl: | |
80 self.read() | |
81 return self.pl | |
82 | |
723 | 83 def markdirty(self): |
84 if not self.dirty: | |
85 self.dirty = 1 | |
86 | |
1062 | 87 def setparents(self, p1, p2=nullid): |
723 | 88 self.markdirty() |
227 | 89 self.pl = p1, p2 |
90 | |
220 | 91 def state(self, key): |
92 try: | |
93 return self[key][0] | |
94 except KeyError: | |
95 return "?" | |
96 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
97 def read(self): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
98 if self.map is not None: return self.map |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
99 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
100 self.map = {} |
227 | 101 self.pl = [nullid, nullid] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
102 try: |
220 | 103 st = self.opener("dirstate").read() |
311 | 104 if not st: return |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
105 except: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
106 |
227 | 107 self.pl = [st[:20], st[20: 40]] |
108 | |
109 pos = 40 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
110 while pos < len(st): |
220 | 111 e = struct.unpack(">cllll", st[pos:pos+17]) |
112 l = e[4] | |
113 pos += 17 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
114 f = st[pos:pos + l] |
515 | 115 if '\0' in f: |
363 | 116 f, c = f.split('\0') |
117 self.copies[f] = c | |
220 | 118 self.map[f] = e[:4] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
119 pos += l |
363 | 120 |
121 def copy(self, source, dest): | |
122 self.read() | |
723 | 123 self.markdirty() |
363 | 124 self.copies[dest] = source |
125 | |
126 def copied(self, file): | |
127 return self.copies.get(file, None) | |
515 | 128 |
862
d70c1c31fd45
Fix 3-way-merge of original parent, workdir and new parent.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
861
diff
changeset
|
129 def update(self, files, state, **kw): |
220 | 130 ''' current states: |
131 n normal | |
231 | 132 m needs merging |
220 | 133 r marked for removal |
134 a marked for addition''' | |
135 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
136 if not files: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
137 self.read() |
723 | 138 self.markdirty() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
139 for f in files: |
220 | 140 if state == "r": |
141 self.map[f] = ('r', 0, 0, 0) | |
142 else: | |
253 | 143 s = os.stat(os.path.join(self.root, f)) |
862
d70c1c31fd45
Fix 3-way-merge of original parent, workdir and new parent.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
861
diff
changeset
|
144 st_size = kw.get('st_size', s.st_size) |
d70c1c31fd45
Fix 3-way-merge of original parent, workdir and new parent.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
861
diff
changeset
|
145 st_mtime = kw.get('st_mtime', s.st_mtime) |
865
2d2fee33ec68
Cleanup after previous changes:
Thomas Arendsen Hein <thomas@intevation.de>
parents:
863
diff
changeset
|
146 self.map[f] = (state, s.st_mode, st_size, st_mtime) |
1117 | 147 if self.copies.has_key(f): |
148 del self.copies[f] | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
149 |
220 | 150 def forget(self, files): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
151 if not files: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
152 self.read() |
723 | 153 self.markdirty() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
154 for f in files: |
20 | 155 try: |
156 del self.map[f] | |
157 except KeyError: | |
220 | 158 self.ui.warn("not in dirstate: %s!\n" % f) |
20 | 159 pass |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
160 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
161 def clear(self): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
162 self.map = {} |
723 | 163 self.markdirty() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
164 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
165 def write(self): |
220 | 166 st = self.opener("dirstate", "w") |
227 | 167 st.write("".join(self.pl)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
168 for f, e in self.map.items(): |
363 | 169 c = self.copied(f) |
170 if c: | |
171 f = f + "\0" + c | |
220 | 172 e = struct.pack(">cllll", e[0], e[1], e[2], e[3], len(f)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
173 st.write(e + f) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
174 self.dirty = 0 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
175 |
879 | 176 def filterfiles(self, files): |
177 ret = {} | |
178 unknown = [] | |
179 | |
180 for x in files: | |
181 if x is '.': | |
182 return self.map.copy() | |
183 if x not in self.map: | |
184 unknown.append(x) | |
185 else: | |
186 ret[x] = self.map[x] | |
919 | 187 |
879 | 188 if not unknown: |
189 return ret | |
190 | |
191 b = self.map.keys() | |
192 b.sort() | |
193 blen = len(b) | |
194 | |
195 for x in unknown: | |
196 bs = bisect.bisect(b, x) | |
919 | 197 if bs != 0 and b[bs-1] == x: |
879 | 198 ret[x] = self.map[x] |
199 continue | |
200 while bs < blen: | |
201 s = b[bs] | |
202 if len(s) > len(x) and s.startswith(x) and s[len(x)] == '/': | |
203 ret[s] = self.map[s] | |
204 else: | |
205 break | |
206 bs += 1 | |
207 return ret | |
208 | |
1062 | 209 def walk(self, files=None, match=util.always, dc=None): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
210 self.read() |
879 | 211 |
723 | 212 # walk all files by default |
879 | 213 if not files: |
214 files = [self.root] | |
215 if not dc: | |
216 dc = self.map.copy() | |
217 elif not dc: | |
218 dc = self.filterfiles(files) | |
919 | 219 |
1183 | 220 def statmatch(file, stat): |
1224
cc61d366bc3b
Fix Windows status problem from new dirstate walk code
mpm@selenic.com
parents:
1183
diff
changeset
|
221 file = util.pconvert(file) |
1183 | 222 if file not in dc and self.ignore(file): |
223 return False | |
224 return match(file) | |
1224
cc61d366bc3b
Fix Windows status problem from new dirstate walk code
mpm@selenic.com
parents:
1183
diff
changeset
|
225 |
1183 | 226 return self.walkhelper(files=files, statmatch=statmatch, dc=dc) |
227 | |
228 # walk recursively through the directory tree, finding all files | |
229 # matched by the statmatch function | |
1224
cc61d366bc3b
Fix Windows status problem from new dirstate walk code
mpm@selenic.com
parents:
1183
diff
changeset
|
230 # |
1183 | 231 # results are yielded in a tuple (src, filename), where src is one of: |
232 # 'f' the file was found in the directory tree | |
233 # 'm' the file was only in the dirstate and not in the tree | |
234 # | |
235 # dc is an optional arg for the current dirstate. dc is not modified | |
236 # directly by this function, but might be modified by your statmatch call. | |
237 # | |
238 def walkhelper(self, files, statmatch, dc): | |
239 # recursion free walker, faster than os.walk. | |
240 def findfiles(s): | |
241 retfiles = [] | |
242 work = [s] | |
243 while work: | |
244 top = work.pop() | |
245 names = os.listdir(top) | |
246 names.sort() | |
247 # nd is the top of the repository dir tree | |
248 nd = util.normpath(top[len(self.root) + 1:]) | |
249 if nd == '.': nd = '' | |
250 for f in names: | |
251 np = os.path.join(nd, f) | |
252 if seen(np): | |
253 continue | |
254 p = os.path.join(top, f) | |
255 st = os.stat(p) | |
256 if stat.S_ISDIR(st.st_mode): | |
257 ds = os.path.join(nd, f +'/') | |
258 if statmatch(ds, st): | |
259 work.append(p) | |
260 else: | |
261 if statmatch(np, st): | |
262 yield np | |
263 | |
821
72d9bd4841f3
Ensure that dirstate.walk only yields names once.
Bryan O'Sullivan <bos@serpentine.com>
parents:
820
diff
changeset
|
264 known = {'.hg': 1} |
72d9bd4841f3
Ensure that dirstate.walk only yields names once.
Bryan O'Sullivan <bos@serpentine.com>
parents:
820
diff
changeset
|
265 def seen(fn): |
72d9bd4841f3
Ensure that dirstate.walk only yields names once.
Bryan O'Sullivan <bos@serpentine.com>
parents:
820
diff
changeset
|
266 if fn in known: return True |
72d9bd4841f3
Ensure that dirstate.walk only yields names once.
Bryan O'Sullivan <bos@serpentine.com>
parents:
820
diff
changeset
|
267 known[fn] = 1 |
1183 | 268 |
269 # step one, find all files that match our criteria | |
270 files.sort() | |
271 for ff in util.unique(files): | |
272 f = os.path.join(self.root, ff) | |
273 try: | |
274 st = os.stat(f) | |
275 except OSError, inst: | |
276 if ff not in dc: self.ui.warn('%s: %s\n' % ( | |
277 util.pathto(self.getcwd(), ff), | |
278 inst.strerror)) | |
279 continue | |
280 if stat.S_ISDIR(st.st_mode): | |
281 sorted = [ x for x in findfiles(f) ] | |
282 sorted.sort() | |
283 for fl in sorted: | |
284 yield 'f', fl | |
285 elif stat.S_ISREG(st.st_mode): | |
286 ff = util.normpath(ff) | |
287 if seen(ff): | |
884
087771ebe2e6
Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents:
883
diff
changeset
|
288 continue |
1183 | 289 found = False |
290 self.blockignore = True | |
291 if statmatch(ff, st): | |
292 found = True | |
293 self.blockignore = False | |
294 if found: | |
884
087771ebe2e6
Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents:
883
diff
changeset
|
295 yield 'f', ff |
1183 | 296 else: |
297 kind = 'unknown' | |
298 if stat.S_ISCHR(st.st_mode): kind = 'character device' | |
299 elif stat.S_ISBLK(st.st_mode): kind = 'block device' | |
300 elif stat.S_ISFIFO(st.st_mode): kind = 'fifo' | |
301 elif stat.S_ISLNK(st.st_mode): kind = 'symbolic link' | |
302 elif stat.S_ISSOCK(st.st_mode): kind = 'socket' | |
303 self.ui.warn('%s: unsupported file type (type is %s)\n' % ( | |
304 util.pathto(self.getcwd(), ff), | |
305 kind)) | |
536 | 306 |
1183 | 307 # step two run through anything left in the dc hash and yield |
308 # if we haven't already seen it | |
309 ks = dc.keys() | |
310 ks.sort() | |
311 for k in ks: | |
312 if not seen(k) and (statmatch(k, None)): | |
726
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
313 yield 'm', k |
669
8aa2a282eda4
.hgignore speedups patch incorporating Matt's feedback.
mwilli2@localhost.localdomain
parents:
667
diff
changeset
|
314 |
861
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
315 def changes(self, files=None, match=util.always): |
723 | 316 self.read() |
879 | 317 if not files: |
1183 | 318 files = [self.root] |
879 | 319 dc = self.map.copy() |
320 else: | |
321 dc = self.filterfiles(files) | |
861
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
322 lookup, modified, added, unknown = [], [], [], [] |
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
323 removed, deleted = [], [] |
723 | 324 |
1183 | 325 # statmatch function to eliminate entries from the dirstate copy |
326 # and put files into the appropriate array. This gets passed | |
327 # to the walking code | |
328 def statmatch(fn, s): | |
1224
cc61d366bc3b
Fix Windows status problem from new dirstate walk code
mpm@selenic.com
parents:
1183
diff
changeset
|
329 fn = util.pconvert(fn) |
1183 | 330 def checkappend(l, fn): |
331 if match is util.always or match(fn): | |
332 l.append(fn) | |
1224
cc61d366bc3b
Fix Windows status problem from new dirstate walk code
mpm@selenic.com
parents:
1183
diff
changeset
|
333 |
1183 | 334 if not s or stat.S_ISDIR(s.st_mode): |
335 return self.ignore(fn) and False or match(fn) | |
336 | |
861
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
337 if not stat.S_ISREG(s.st_mode): |
1183 | 338 return False |
339 c = dc.pop(fn, None) | |
861
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
340 if c: |
1183 | 341 type, mode, size, time = c |
342 # check the common case first | |
343 if type == 'n': | |
344 if size != s.st_size or (mode ^ s.st_mode) & 0100: | |
345 checkappend(modified, fn) | |
346 elif time != s.st_mtime: | |
347 checkappend(lookup, fn) | |
348 elif type == 'm': | |
349 checkappend(modified, fn) | |
350 elif type == 'a': | |
351 checkappend(added, fn) | |
352 elif type == 'r': | |
353 checkappend(unknown, fn) | |
354 else: | |
355 if not self.ignore(fn) and match(fn): | |
536 | 356 unknown.append(fn) |
1183 | 357 # return false because we've already handled all cases above. |
358 # there's no need for the walking code to process the file | |
359 # any further. | |
360 return False | |
536 | 361 |
1183 | 362 # because our statmatch always returns false, self.walk will only |
363 # return files in the dirstate map that are not present in the FS. | |
364 # But, we still need to iterate through the results to force the | |
365 # walk to complete | |
366 for src, fn in self.walkhelper(files, statmatch, dc): | |
367 pass | |
368 | |
369 # anything left in dc didn't exist in the filesystem | |
861
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
370 for fn, c in [(fn, c) for fn, c in dc.items() if match(fn)]: |
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
371 if c[0] == 'r': |
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
372 removed.append(fn) |
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
373 else: |
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
374 deleted.append(fn) |
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
375 return (lookup, modified, added, removed + deleted, unknown) |