annotate mercurial/dirstate.py @ 1276:25e5b1086624

Fix dirstate.changes for ignored directories. Do a second walking pass to examine any leftover files in the dirstate map that are in the .hgignore file but match our search criteria. This fixes the case of entire directories never being examined due to their presence in the .hgignore file, and should hopefully not add any significant overhead.
author Bryan O'Sullivan <bos@serpentine.com>
date Sun, 18 Sep 2005 15:03:07 -0700
parents 9ab14ca22e37
children 32d8068b3e36
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
1 """
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
2 dirstate.py - working directory tracking for mercurial
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
3
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
4 Copyright 2005 Matt Mackall <mpm@selenic.com>
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
5
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
6 This software may be used and distributed according to the terms
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
7 of the GNU General Public License, incorporated herein by reference.
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
8 """
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
9
1094
221b5252864c Adjust some imports
mpm@selenic.com
parents: 1089
diff changeset
10 import struct, os
221b5252864c Adjust some imports
mpm@selenic.com
parents: 1089
diff changeset
11 from node import *
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
12 from demandload import *
1104
98988cc3723a Fix dirstate imports
mpm@selenic.com
parents: 1094
diff changeset
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
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
15 class dirstate:
244
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
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
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
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
a664c2b624cf The actual hg remove fix from Thomas Hein
mpm@selenic.com
parents: 19
diff changeset
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
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
22 self.pl = None
363
ae96b7e1318d Add hg copy
mpm@selenic.com
parents: 360
diff changeset
23 self.copies = {}
723
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
24 self.ignorefunc = None
1183
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
25 self.blockignore = False
723
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
26
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
27 def wjoin(self, f):
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
28 return os.path.join(self.root, f)
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
84 if self.blockignore:
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
85 return False
723
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
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
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
94
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
95 def __del__(self):
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
96 if self.dirty:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
97 self.write()
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
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
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
105
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
106 def __contains__(self, key):
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
107 if not self.map: self.read()
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
108 return key in self.map
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
109
227
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
110 def parents(self):
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
111 if not self.pl:
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
112 self.read()
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
113 return self.pl
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
114
723
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
115 def markdirty(self):
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
116 if not self.dirty:
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
117 self.dirty = 1
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
118
1062
6d5a62a549fa pep-0008 cleanup
benoit.boissinot@ens-lyon.fr
parents: 1040
diff changeset
119 def setparents(self, p1, p2=nullid):
723
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
120 self.markdirty()
227
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
121 self.pl = p1, p2
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
122
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
123 def state(self, key):
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
124 try:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
125 return self[key][0]
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
126 except KeyError:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
127 return "?"
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
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
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
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
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
135 st = self.opener("dirstate").read()
311
3b17056b72dc fix KeyErrors from reading empty dirstate
mpm@selenic.com
parents: 308
diff changeset
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
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
139 self.pl = [st[:20], st[20: 40]]
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
140
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
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
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
143 e = struct.unpack(">cllll", st[pos:pos+17])
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
144 l = e[4]
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
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
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 514
diff changeset
147 if '\0' in f:
363
ae96b7e1318d Add hg copy
mpm@selenic.com
parents: 360
diff changeset
148 f, c = f.split('\0')
ae96b7e1318d Add hg copy
mpm@selenic.com
parents: 360
diff changeset
149 self.copies[f] = c
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
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
ae96b7e1318d Add hg copy
mpm@selenic.com
parents: 360
diff changeset
152
ae96b7e1318d Add hg copy
mpm@selenic.com
parents: 360
diff changeset
153 def copy(self, source, dest):
ae96b7e1318d Add hg copy
mpm@selenic.com
parents: 360
diff changeset
154 self.read()
723
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
155 self.markdirty()
363
ae96b7e1318d Add hg copy
mpm@selenic.com
parents: 360
diff changeset
156 self.copies[dest] = source
ae96b7e1318d Add hg copy
mpm@selenic.com
parents: 360
diff changeset
157
ae96b7e1318d Add hg copy
mpm@selenic.com
parents: 360
diff changeset
158 def copied(self, file):
ae96b7e1318d Add hg copy
mpm@selenic.com
parents: 360
diff changeset
159 return self.copies.get(file, None)
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 514
diff changeset
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
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
162 ''' current states:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
163 n normal
231
15e7c6cee929 add 'm' state to dirstates
mpm@selenic.com
parents: 230
diff changeset
164 m needs merging
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
165 r marked for removal
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
166 a marked for addition'''
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
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
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
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
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
172 if state == "r":
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
173 self.map[f] = ('r', 0, 0, 0)
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
174 else:
1230
6eac821c202c dirstate: two more stat -> lstat changes
mpm@selenic.com
parents: 1228
diff changeset
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
30ab5b8ee8ec fix some rename/copy bugs
mpm@selenic.com
parents: 1104
diff changeset
179 if self.copies.has_key(f):
30ab5b8ee8ec fix some rename/copy bugs
mpm@selenic.com
parents: 1104
diff changeset
180 del self.copies[f]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
181
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
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
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
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
a664c2b624cf The actual hg remove fix from Thomas Hein
mpm@selenic.com
parents: 19
diff changeset
187 try:
a664c2b624cf The actual hg remove fix from Thomas Hein
mpm@selenic.com
parents: 19
diff changeset
188 del self.map[f]
a664c2b624cf The actual hg remove fix from Thomas Hein
mpm@selenic.com
parents: 19
diff changeset
189 except KeyError:
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
190 self.ui.warn("not in dirstate: %s!\n" % f)
20
a664c2b624cf The actual hg remove fix from Thomas Hein
mpm@selenic.com
parents: 19
diff changeset
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
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
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
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
198 st = self.opener("dirstate", "w")
227
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
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
ae96b7e1318d Add hg copy
mpm@selenic.com
parents: 360
diff changeset
201 c = self.copied(f)
ae96b7e1318d Add hg copy
mpm@selenic.com
parents: 360
diff changeset
202 if c:
ae96b7e1318d Add hg copy
mpm@selenic.com
parents: 360
diff changeset
203 f = f + "\0" + c
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
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
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
208 def filterfiles(self, files):
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
209 ret = {}
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
210 unknown = []
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
211
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
212 for x in files:
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
213 if x is '.':
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
214 return self.map.copy()
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
215 if x not in self.map:
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
216 unknown.append(x)
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
217 else:
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
218 ret[x] = self.map[x]
919
1458d20df2a8 whitespace cleanup
mpm@selenic.com
parents: 911
diff changeset
219
879
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
220 if not unknown:
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
221 return ret
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
222
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
223 b = self.map.keys()
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
224 b.sort()
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
225 blen = len(b)
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
226
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
227 for x in unknown:
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
228 bs = bisect.bisect(b, x)
919
1458d20df2a8 whitespace cleanup
mpm@selenic.com
parents: 911
diff changeset
229 if bs != 0 and b[bs-1] == x:
879
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
230 ret[x] = self.map[x]
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
231 continue
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
232 while bs < blen:
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
233 s = b[bs]
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
234 if len(s) > len(x) and s.startswith(x) and s[len(x)] == '/':
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
235 ret[s] = self.map[s]
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
236 else:
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
237 break
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
238 bs += 1
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
239 return ret
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
240
1062
6d5a62a549fa pep-0008 cleanup
benoit.boissinot@ens-lyon.fr
parents: 1040
diff changeset
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
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
243
723
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
244 # walk all files by default
879
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
245 if not files:
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
246 files = [self.root]
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
247 if not dc:
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
248 dc = self.map.copy()
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
249 elif not dc:
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
250 dc = self.filterfiles(files)
919
1458d20df2a8 whitespace cleanup
mpm@selenic.com
parents: 911
diff changeset
251
1183
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
254 if file not in dc and self.ignore(file):
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
255 return False
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
256 return match(file)
1224
cc61d366bc3b Fix Windows status problem from new dirstate walk code
mpm@selenic.com
parents: 1183
diff changeset
257
1183
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
258 return self.walkhelper(files=files, statmatch=statmatch, dc=dc)
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
259
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
260 # walk recursively through the directory tree, finding all files
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
263 # results are yielded in a tuple (src, filename), where src is one of:
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
264 # 'f' the file was found in the directory tree
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
265 # 'm' the file was only in the dirstate and not in the tree
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
266 #
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
267 # dc is an optional arg for the current dirstate. dc is not modified
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
268 # directly by this function, but might be modified by your statmatch call.
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
269 #
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
270 def walkhelper(self, files, statmatch, dc):
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
271 # recursion free walker, faster than os.walk.
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
272 def findfiles(s):
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
273 retfiles = []
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
274 work = [s]
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
275 while work:
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
276 top = work.pop()
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
277 names = os.listdir(top)
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
278 names.sort()
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
279 # nd is the top of the repository dir tree
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
280 nd = util.normpath(top[len(self.root) + 1:])
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
281 if nd == '.': nd = ''
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
282 for f in names:
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
283 np = os.path.join(nd, f)
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
284 if seen(np):
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
285 continue
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
289 if stat.S_ISDIR(st.st_mode):
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
290 ds = os.path.join(nd, f +'/')
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
291 if statmatch(ds, st):
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
292 work.append(p)
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
293 else:
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
301
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
302 # step one, find all files that match our criteria
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
303 files.sort()
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
304 for ff in util.unique(files):
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
305 f = os.path.join(self.root, ff)
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
306 try:
1230
6eac821c202c dirstate: two more stat -> lstat changes
mpm@selenic.com
parents: 1228
diff changeset
307 st = os.lstat(f)
1183
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
308 except OSError, inst:
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
309 if ff not in dc: self.ui.warn('%s: %s\n' % (
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
310 util.pathto(self.getcwd(), ff),
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
311 inst.strerror))
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
312 continue
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
313 if stat.S_ISDIR(st.st_mode):
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
314 sorted = [ x for x in findfiles(f) ]
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
315 sorted.sort()
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
316 for fl in sorted:
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
317 yield 'f', fl
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
318 elif stat.S_ISREG(st.st_mode):
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
319 ff = util.normpath(ff)
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
322 found = False
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
323 self.blockignore = True
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
324 if statmatch(ff, st):
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
325 found = True
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
326 self.blockignore = False
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
329 else:
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
330 kind = 'unknown'
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
331 if stat.S_ISCHR(st.st_mode): kind = 'character device'
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
332 elif stat.S_ISBLK(st.st_mode): kind = 'block device'
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
333 elif stat.S_ISFIFO(st.st_mode): kind = 'fifo'
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
334 elif stat.S_ISLNK(st.st_mode): kind = 'symbolic link'
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
335 elif stat.S_ISSOCK(st.st_mode): kind = 'socket'
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
336 self.ui.warn('%s: unsupported file type (type is %s)\n' % (
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
337 util.pathto(self.getcwd(), ff),
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
338 kind))
536
c15b4bc0a11c Refactor diffrevs/diffdir into changes
mpm@selenic.com
parents: 529
diff changeset
339
1183
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
340 # step two run through anything left in the dc hash and yield
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
341 # if we haven't already seen it
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
342 ks = dc.keys()
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
343 ks.sort()
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
344 for k in ks:
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
349 self.read()
879
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
350 if not files:
1183
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
351 files = [self.root]
879
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
352 dc = self.map.copy()
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
353 else:
953ccddd57bd dirstate walking optimizations
mason@suse.com
parents: 871
diff changeset
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
9e0f3ba4a9c2 Work on walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
357
1183
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
358 # statmatch function to eliminate entries from the dirstate copy
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
359 # and put files into the appropriate array. This gets passed
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
360 # to the walking code
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
363 def checkappend(l, fn):
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
364 if match is util.always or match(fn):
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
365 l.append(fn)
1224
cc61d366bc3b Fix Windows status problem from new dirstate walk code
mpm@selenic.com
parents: 1183
diff changeset
366
1183
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
372 return False
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
375 type, mode, size, time = c
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
376 # check the common case first
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
377 if type == 'n':
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
378 if size != s.st_size or (mode ^ s.st_mode) & 0100:
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
379 checkappend(modified, fn)
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
380 elif time != s.st_mtime:
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
381 checkappend(lookup, fn)
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
382 elif type == 'm':
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
383 checkappend(modified, fn)
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
384 elif type == 'a':
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
385 checkappend(added, fn)
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
386 elif type == 'r':
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
390 # return false because we've already handled all cases above.
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
391 # there's no need for the walking code to process the file
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
392 # any further.
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
393 return False
536
c15b4bc0a11c Refactor diffrevs/diffdir into changes
mpm@selenic.com
parents: 529
diff changeset
394
1183
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
395 # because our statmatch always returns false, self.walk will only
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
396 # return files in the dirstate map that are not present in the FS.
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
397 # But, we still need to iterate through the results to force the
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
398 # walk to complete
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
399 for src, fn in self.walkhelper(files, statmatch, dc):
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
400 pass
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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
d9e85a75dbda Optimize dirstate walking
mason@suse.com
parents: 1117
diff changeset
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)