Mercurial > hg > mercurial-crew-with-dirclash
annotate mercurial/dirstate.py @ 1279:8ab1c07d4e0b
Add checks for programs which are required for the test suite to run.
All prerequisite programs are checked for existance, and if any are
missing,
a list of missing programs is printed, and the test suite is aborted.
All programs currently used in the tests, except those in core-utils,
are checked.
author | eric@localhost.localdomain |
---|---|
date | Mon, 19 Sep 2005 18:24:37 -0700 |
parents | 25e5b1086624 |
children | 32d8068b3e36 |
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 |
1270
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
35 def hgignore(self): |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
36 '''return the contents of .hgignore as a list of patterns. |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
37 |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
38 trailing white space is dropped. |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
39 the escape character is backslash. |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
40 comments start with #. |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
41 empty lines are skipped. |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
42 |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
43 lines can be of the following formats: |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
44 |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
45 syntax: regexp # defaults following lines to non-rooted regexps |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
46 syntax: glob # defaults following lines to non-rooted globs |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
47 re:pattern # non-rooted regular expression |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
48 glob:pattern # non-rooted glob |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
49 pattern # pattern of the current default type''' |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
50 syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:'} |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
51 def parselines(fp): |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
52 for line in fp: |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
53 escape = False |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
54 for i in xrange(len(line)): |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
55 if escape: escape = False |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
56 elif line[i] == '\\': escape = True |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
57 elif line[i] == '#': break |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
58 line = line[:i].rstrip() |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
59 if line: yield line |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
60 pats = [] |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
61 try: |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
62 fp = open(self.wjoin('.hgignore')) |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
63 syntax = 'relre:' |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
64 for line in parselines(fp): |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
65 if line.startswith('syntax:'): |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
66 s = line[7:].strip() |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
67 try: |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
68 syntax = syntaxes[s] |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
69 except KeyError: |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
70 self.ui.warn("ignoring invalid syntax '%s'\n" % s) |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
71 continue |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
72 pat = syntax + line |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
73 for s in syntaxes.values(): |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
74 if line.startswith(s): |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
75 pat = line |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
76 break |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
77 pats.append(pat) |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
78 except IOError: pass |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
79 return pats |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
80 |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
81 def ignore(self, fn): |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
82 '''default match function used by dirstate and localrepository. |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
83 this honours the .hgignore file, and nothing more.''' |
1183 | 84 if self.blockignore: |
85 return False | |
723 | 86 if not self.ignorefunc: |
1271
9ab14ca22e37
Fix ignore regression.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1270
diff
changeset
|
87 ignore = self.hgignore() |
9ab14ca22e37
Fix ignore regression.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1270
diff
changeset
|
88 if ignore: |
9ab14ca22e37
Fix ignore regression.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1270
diff
changeset
|
89 files, self.ignorefunc, anypats = util.matcher(self.root, |
9ab14ca22e37
Fix ignore regression.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1270
diff
changeset
|
90 inc=ignore) |
9ab14ca22e37
Fix ignore regression.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1270
diff
changeset
|
91 else: |
9ab14ca22e37
Fix ignore regression.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1270
diff
changeset
|
92 self.ignorefunc = util.never |
1270
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
93 return self.ignorefunc(fn) |
220 | 94 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
95 def __del__(self): |
220 | 96 if self.dirty: |
97 self.write() | |
98 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
99 def __getitem__(self, key): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
100 try: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
101 return self.map[key] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
102 except TypeError: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
103 self.read() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
104 return self[key] |
220 | 105 |
106 def __contains__(self, key): | |
107 if not self.map: self.read() | |
108 return key in self.map | |
109 | |
227 | 110 def parents(self): |
111 if not self.pl: | |
112 self.read() | |
113 return self.pl | |
114 | |
723 | 115 def markdirty(self): |
116 if not self.dirty: | |
117 self.dirty = 1 | |
118 | |
1062 | 119 def setparents(self, p1, p2=nullid): |
723 | 120 self.markdirty() |
227 | 121 self.pl = p1, p2 |
122 | |
220 | 123 def state(self, key): |
124 try: | |
125 return self[key][0] | |
126 except KeyError: | |
127 return "?" | |
128 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
129 def read(self): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
130 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
|
131 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
132 self.map = {} |
227 | 133 self.pl = [nullid, nullid] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
134 try: |
220 | 135 st = self.opener("dirstate").read() |
311 | 136 if not st: return |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
137 except: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
138 |
227 | 139 self.pl = [st[:20], st[20: 40]] |
140 | |
141 pos = 40 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
142 while pos < len(st): |
220 | 143 e = struct.unpack(">cllll", st[pos:pos+17]) |
144 l = e[4] | |
145 pos += 17 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
146 f = st[pos:pos + l] |
515 | 147 if '\0' in f: |
363 | 148 f, c = f.split('\0') |
149 self.copies[f] = c | |
220 | 150 self.map[f] = e[:4] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
151 pos += l |
363 | 152 |
153 def copy(self, source, dest): | |
154 self.read() | |
723 | 155 self.markdirty() |
363 | 156 self.copies[dest] = source |
157 | |
158 def copied(self, file): | |
159 return self.copies.get(file, None) | |
515 | 160 |
862
d70c1c31fd45
Fix 3-way-merge of original parent, workdir and new parent.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
861
diff
changeset
|
161 def update(self, files, state, **kw): |
220 | 162 ''' current states: |
163 n normal | |
231 | 164 m needs merging |
220 | 165 r marked for removal |
166 a marked for addition''' | |
167 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
168 if not files: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
169 self.read() |
723 | 170 self.markdirty() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
171 for f in files: |
220 | 172 if state == "r": |
173 self.map[f] = ('r', 0, 0, 0) | |
174 else: | |
1230 | 175 s = os.lstat(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
|
176 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
|
177 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
|
178 self.map[f] = (state, s.st_mode, st_size, st_mtime) |
1117 | 179 if self.copies.has_key(f): |
180 del self.copies[f] | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
181 |
220 | 182 def forget(self, files): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
183 if not files: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
184 self.read() |
723 | 185 self.markdirty() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
186 for f in files: |
20 | 187 try: |
188 del self.map[f] | |
189 except KeyError: | |
220 | 190 self.ui.warn("not in dirstate: %s!\n" % f) |
20 | 191 pass |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
192 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
193 def clear(self): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
194 self.map = {} |
723 | 195 self.markdirty() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
196 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
197 def write(self): |
220 | 198 st = self.opener("dirstate", "w") |
227 | 199 st.write("".join(self.pl)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
200 for f, e in self.map.items(): |
363 | 201 c = self.copied(f) |
202 if c: | |
203 f = f + "\0" + c | |
220 | 204 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
|
205 st.write(e + f) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
206 self.dirty = 0 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
207 |
879 | 208 def filterfiles(self, files): |
209 ret = {} | |
210 unknown = [] | |
211 | |
212 for x in files: | |
213 if x is '.': | |
214 return self.map.copy() | |
215 if x not in self.map: | |
216 unknown.append(x) | |
217 else: | |
218 ret[x] = self.map[x] | |
919 | 219 |
879 | 220 if not unknown: |
221 return ret | |
222 | |
223 b = self.map.keys() | |
224 b.sort() | |
225 blen = len(b) | |
226 | |
227 for x in unknown: | |
228 bs = bisect.bisect(b, x) | |
919 | 229 if bs != 0 and b[bs-1] == x: |
879 | 230 ret[x] = self.map[x] |
231 continue | |
232 while bs < blen: | |
233 s = b[bs] | |
234 if len(s) > len(x) and s.startswith(x) and s[len(x)] == '/': | |
235 ret[s] = self.map[s] | |
236 else: | |
237 break | |
238 bs += 1 | |
239 return ret | |
240 | |
1062 | 241 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
|
242 self.read() |
879 | 243 |
723 | 244 # walk all files by default |
879 | 245 if not files: |
246 files = [self.root] | |
247 if not dc: | |
248 dc = self.map.copy() | |
249 elif not dc: | |
250 dc = self.filterfiles(files) | |
919 | 251 |
1183 | 252 def statmatch(file, stat): |
1224
cc61d366bc3b
Fix Windows status problem from new dirstate walk code
mpm@selenic.com
parents:
1183
diff
changeset
|
253 file = util.pconvert(file) |
1183 | 254 if file not in dc and self.ignore(file): |
255 return False | |
256 return match(file) | |
1224
cc61d366bc3b
Fix Windows status problem from new dirstate walk code
mpm@selenic.com
parents:
1183
diff
changeset
|
257 |
1183 | 258 return self.walkhelper(files=files, statmatch=statmatch, dc=dc) |
259 | |
260 # walk recursively through the directory tree, finding all files | |
261 # matched by the statmatch function | |
1224
cc61d366bc3b
Fix Windows status problem from new dirstate walk code
mpm@selenic.com
parents:
1183
diff
changeset
|
262 # |
1183 | 263 # results are yielded in a tuple (src, filename), where src is one of: |
264 # 'f' the file was found in the directory tree | |
265 # 'm' the file was only in the dirstate and not in the tree | |
266 # | |
267 # dc is an optional arg for the current dirstate. dc is not modified | |
268 # directly by this function, but might be modified by your statmatch call. | |
269 # | |
270 def walkhelper(self, files, statmatch, dc): | |
271 # recursion free walker, faster than os.walk. | |
272 def findfiles(s): | |
273 retfiles = [] | |
274 work = [s] | |
275 while work: | |
276 top = work.pop() | |
277 names = os.listdir(top) | |
278 names.sort() | |
279 # nd is the top of the repository dir tree | |
280 nd = util.normpath(top[len(self.root) + 1:]) | |
281 if nd == '.': nd = '' | |
282 for f in names: | |
283 np = os.path.join(nd, f) | |
284 if seen(np): | |
285 continue | |
286 p = os.path.join(top, f) | |
1228
db950da49539
Fix dangling symlink bug in dirstate walk code
mpm@selenic.com
parents:
1224
diff
changeset
|
287 # don't trip over symlinks |
db950da49539
Fix dangling symlink bug in dirstate walk code
mpm@selenic.com
parents:
1224
diff
changeset
|
288 st = os.lstat(p) |
1183 | 289 if stat.S_ISDIR(st.st_mode): |
290 ds = os.path.join(nd, f +'/') | |
291 if statmatch(ds, st): | |
292 work.append(p) | |
293 else: | |
294 if statmatch(np, st): | |
1245
d0a960b437a8
Files not getting added appropiately
Chris Mason <mason@suse.com>
parents:
1230
diff
changeset
|
295 yield util.pconvert(np) |
1183 | 296 |
821
72d9bd4841f3
Ensure that dirstate.walk only yields names once.
Bryan O'Sullivan <bos@serpentine.com>
parents:
820
diff
changeset
|
297 known = {'.hg': 1} |
72d9bd4841f3
Ensure that dirstate.walk only yields names once.
Bryan O'Sullivan <bos@serpentine.com>
parents:
820
diff
changeset
|
298 def seen(fn): |
72d9bd4841f3
Ensure that dirstate.walk only yields names once.
Bryan O'Sullivan <bos@serpentine.com>
parents:
820
diff
changeset
|
299 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
|
300 known[fn] = 1 |
1183 | 301 |
302 # step one, find all files that match our criteria | |
303 files.sort() | |
304 for ff in util.unique(files): | |
305 f = os.path.join(self.root, ff) | |
306 try: | |
1230 | 307 st = os.lstat(f) |
1183 | 308 except OSError, inst: |
309 if ff not in dc: self.ui.warn('%s: %s\n' % ( | |
310 util.pathto(self.getcwd(), ff), | |
311 inst.strerror)) | |
312 continue | |
313 if stat.S_ISDIR(st.st_mode): | |
314 sorted = [ x for x in findfiles(f) ] | |
315 sorted.sort() | |
316 for fl in sorted: | |
317 yield 'f', fl | |
318 elif stat.S_ISREG(st.st_mode): | |
319 ff = util.normpath(ff) | |
320 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
|
321 continue |
1183 | 322 found = False |
323 self.blockignore = True | |
324 if statmatch(ff, st): | |
325 found = True | |
326 self.blockignore = False | |
327 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
|
328 yield 'f', ff |
1183 | 329 else: |
330 kind = 'unknown' | |
331 if stat.S_ISCHR(st.st_mode): kind = 'character device' | |
332 elif stat.S_ISBLK(st.st_mode): kind = 'block device' | |
333 elif stat.S_ISFIFO(st.st_mode): kind = 'fifo' | |
334 elif stat.S_ISLNK(st.st_mode): kind = 'symbolic link' | |
335 elif stat.S_ISSOCK(st.st_mode): kind = 'socket' | |
336 self.ui.warn('%s: unsupported file type (type is %s)\n' % ( | |
337 util.pathto(self.getcwd(), ff), | |
338 kind)) | |
536 | 339 |
1183 | 340 # step two run through anything left in the dc hash and yield |
341 # if we haven't already seen it | |
342 ks = dc.keys() | |
343 ks.sort() | |
344 for k in ks: | |
345 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
|
346 yield 'm', k |
669
8aa2a282eda4
.hgignore speedups patch incorporating Matt's feedback.
mwilli2@localhost.localdomain
parents:
667
diff
changeset
|
347 |
861
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
348 def changes(self, files=None, match=util.always): |
723 | 349 self.read() |
879 | 350 if not files: |
1183 | 351 files = [self.root] |
879 | 352 dc = self.map.copy() |
353 else: | |
354 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
|
355 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
|
356 removed, deleted = [], [] |
723 | 357 |
1183 | 358 # statmatch function to eliminate entries from the dirstate copy |
359 # and put files into the appropriate array. This gets passed | |
360 # to the walking code | |
361 def statmatch(fn, s): | |
1224
cc61d366bc3b
Fix Windows status problem from new dirstate walk code
mpm@selenic.com
parents:
1183
diff
changeset
|
362 fn = util.pconvert(fn) |
1183 | 363 def checkappend(l, fn): |
364 if match is util.always or match(fn): | |
365 l.append(fn) | |
1224
cc61d366bc3b
Fix Windows status problem from new dirstate walk code
mpm@selenic.com
parents:
1183
diff
changeset
|
366 |
1183 | 367 if not s or stat.S_ISDIR(s.st_mode): |
1268
c631f26346ca
Fix performance of dirstate.changes with ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1245
diff
changeset
|
368 if self.ignore(fn): return False |
c631f26346ca
Fix performance of dirstate.changes with ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1245
diff
changeset
|
369 return match(fn) |
1183 | 370 |
861
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
371 if not stat.S_ISREG(s.st_mode): |
1183 | 372 return False |
373 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
|
374 if c: |
1183 | 375 type, mode, size, time = c |
376 # check the common case first | |
377 if type == 'n': | |
378 if size != s.st_size or (mode ^ s.st_mode) & 0100: | |
379 checkappend(modified, fn) | |
380 elif time != s.st_mtime: | |
381 checkappend(lookup, fn) | |
382 elif type == 'm': | |
383 checkappend(modified, fn) | |
384 elif type == 'a': | |
385 checkappend(added, fn) | |
386 elif type == 'r': | |
387 checkappend(unknown, fn) | |
1270
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
388 elif not self.ignore(fn) and match(fn): |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1268
diff
changeset
|
389 unknown.append(fn) |
1183 | 390 # return false because we've already handled all cases above. |
391 # there's no need for the walking code to process the file | |
392 # any further. | |
393 return False | |
536 | 394 |
1183 | 395 # because our statmatch always returns false, self.walk will only |
396 # return files in the dirstate map that are not present in the FS. | |
397 # But, we still need to iterate through the results to force the | |
398 # walk to complete | |
399 for src, fn in self.walkhelper(files, statmatch, dc): | |
400 pass | |
401 | |
1276
25e5b1086624
Fix dirstate.changes for ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1271
diff
changeset
|
402 # there may be patterns in the .hgignore file that prevent us |
25e5b1086624
Fix dirstate.changes for ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1271
diff
changeset
|
403 # from examining entire directories in the dirstate map, so we |
25e5b1086624
Fix dirstate.changes for ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1271
diff
changeset
|
404 # go back and explicitly examine any matching files we've |
25e5b1086624
Fix dirstate.changes for ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1271
diff
changeset
|
405 # ignored |
25e5b1086624
Fix dirstate.changes for ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1271
diff
changeset
|
406 unexamined = [fn for fn in dc.iterkeys() |
25e5b1086624
Fix dirstate.changes for ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1271
diff
changeset
|
407 if self.ignore(fn) and match(fn)] |
25e5b1086624
Fix dirstate.changes for ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1271
diff
changeset
|
408 |
25e5b1086624
Fix dirstate.changes for ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1271
diff
changeset
|
409 for src, fn in self.walkhelper(unexamined, statmatch, dc): |
25e5b1086624
Fix dirstate.changes for ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1271
diff
changeset
|
410 pass |
25e5b1086624
Fix dirstate.changes for ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1271
diff
changeset
|
411 |
1183 | 412 # anything left in dc didn't exist in the filesystem |
1276
25e5b1086624
Fix dirstate.changes for ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1271
diff
changeset
|
413 for fn, c in dc.iteritems(): |
25e5b1086624
Fix dirstate.changes for ignored directories.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1271
diff
changeset
|
414 if not match(fn): continue |
861
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
415 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
|
416 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
|
417 else: |
cbe5c4d016b7
dirstate.changes() now distinguishes 'hg remove'd or just deleted files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
856
diff
changeset
|
418 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
|
419 return (lookup, modified, added, removed + deleted, unknown) |