##// END OF EJS Templates
remove: work directly off status...
remove: work directly off status This allows us to use a single directory walk and to trivially ignore unknown files. The resulting code is also easier to follow.

File last commit:

r6756:d56ceb82 default
r6761:cb981fc9 default
Show More
dirstate.py
695 lines | 22.1 KiB | text/x-python | PythonLexer
mpm@selenic.com
Break apart hg.py...
r1089 """
dirstate.py - working directory tracking for mercurial
Thomas Arendsen Hein
Updated copyright notices and add "and others" to "hg version"
r4635 Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
mpm@selenic.com
Break apart hg.py...
r1089
This software may be used and distributed according to the terms
of the GNU General Public License, incorporated herein by reference.
"""
Joel Rosdahl
Expand import * to allow Pyflakes to find problems
r6211 from node import nullid
Matt Mackall
Simplify i18n imports
r3891 from i18n import _
Joel Rosdahl
Remove unused imports
r6212 import struct, os, bisect, stat, strutil, util, errno, ignore
Alexis S. L. Carvalho
dirstate: ignore stat data for files that were updated too recently...
r6326 import cStringIO, osutil, sys
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
dirstate: simplify state()
r4610 _unknown = ('?', 0, 0, 0)
_format = ">cllll"
Eric Hopper
Convert all classes to new-style classes by deriving them from object.
r1559 class dirstate(object):
Benoit Boissinot
dirstate: refactor the dirstate binary format, remove magic numbers
r2393
mpm@selenic.com
Break apart hg.py...
r1089 def __init__(self, opener, ui, root):
Matt Mackall
dirstate: hide internal vars...
r4614 self._opener = opener
self._root = root
Matt Mackall
dirstate: use True and false for _dirty
r4903 self._dirty = False
Matt Mackall
Merge with crew
r4965 self._dirtypl = False
Matt Mackall
dirstate: hide internal vars...
r4614 self._ui = ui
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
dirstate: use getattr rather than lazyread
r4603 def __getattr__(self, name):
Matt Mackall
dirstate: hide internal vars...
r4614 if name == '_map':
Matt Mackall
dirstate: hide some more internals
r4615 self._read()
Matt Mackall
dirstate: hide internal vars...
r4614 return self._map
elif name == '_copymap':
Matt Mackall
dirstate: hide some more internals
r4615 self._read()
Matt Mackall
dirstate: hide internal vars...
r4614 return self._copymap
Paul Moore
Add a normalize() method to dirstate...
r6677 elif name == '_foldmap':
_foldmap = {}
for name in self._map:
norm = os.path.normcase(os.path.normpath(name))
_foldmap[norm] = name
self._foldmap = _foldmap
return self._foldmap
Matt Mackall
dirstate: lazify copymap, _branch, and _pl
r4604 elif name == '_branch':
try:
Thomas Arendsen Hein
Cleanup of whitespace, indentation and line continuation.
r4633 self._branch = (self._opener("branch").read().strip()
or "default")
Matt Mackall
dirstate: lazify copymap, _branch, and _pl
r4604 except IOError:
self._branch = "default"
return self._branch
Matt Mackall
dirstate: hide internal vars...
r4614 elif name == '_pl':
self._pl = [nullid, nullid]
Matt Mackall
dirstate: lazify copymap, _branch, and _pl
r4604 try:
Matt Mackall
dirstate: hide internal vars...
r4614 st = self._opener("dirstate").read(40)
Matt Mackall
dirstate: lazify copymap, _branch, and _pl
r4604 if len(st) == 40:
Matt Mackall
dirstate: hide internal vars...
r4614 self._pl = st[:20], st[20:40]
Matt Mackall
dirstate: lazify copymap, _branch, and _pl
r4604 except IOError, err:
if err.errno != errno.ENOENT: raise
Matt Mackall
dirstate: hide internal vars...
r4614 return self._pl
Matt Mackall
dirstate: hide some more internals
r4615 elif name == '_dirs':
self._dirs = {}
Matt Mackall
dirstate: hide internal vars...
r4614 for f in self._map:
Maxim Dounin
Fix file-changed-to-dir and dir-to-file commits (issue660)....
r5487 if self[f] != 'r':
self._incpath(f)
Matt Mackall
dirstate: hide some more internals
r4615 return self._dirs
Matt Mackall
dirstate: move ignore to its own file
r4609 elif name == '_ignore':
Matt Mackall
dirstate: make wjoin function private
r4905 files = [self._join('.hgignore')]
Matt Mackall
dirstate: pull ignore smarts out of ui
r4620 for name, path in self._ui.configitems("ui"):
if name == 'ignore' or name.startswith('ignore.'):
files.append(os.path.expanduser(path))
Matt Mackall
dirstate: hide internal vars...
r4614 self._ignore = ignore.ignore(self._root, files, self._ui.warn)
Matt Mackall
dirstate: move ignore to its own file
r4609 return self._ignore
Matt Mackall
dirstate: lazify and lambdafy _slash
r4611 elif name == '_slash':
Matt Mackall
dirstate: hide internal vars...
r4614 self._slash = self._ui.configbool('ui', 'slash') and os.sep != '/'
Matt Mackall
dirstate: lazify and lambdafy _slash
r4611 return self._slash
Matt Mackall
simplify flag handling...
r6743 elif name == '_checklink':
self._checklink = util.checklink(self._root)
return self._checklink
Alexis S. L. Carvalho
dirstate: ignore mode changes if the fs does not supports the exec bit...
r6257 elif name == '_checkexec':
self._checkexec = util.checkexec(self._root)
return self._checkexec
Matt Mackall
rename checkfolding to checkcase
r6746 elif name == '_checkcase':
self._checkcase = not util.checkcase(self._join('.hg'))
return self._checkcase
Paul Moore
Add a normalize() method to dirstate...
r6677 elif name == 'normalize':
Matt Mackall
rename checkfolding to checkcase
r6746 if self._checkcase:
Paul Moore
Add a normalize() method to dirstate...
r6677 self.normalize = self._normalize
else:
self.normalize = lambda x: x
return self.normalize
Matt Mackall
dirstate: use getattr rather than lazyread
r4603 else:
raise AttributeError, name
Matt Mackall
dirstate: make wjoin function private
r4905 def _join(self, f):
Matt Mackall
dirstate: hide internal vars...
r4614 return os.path.join(self._root, f)
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
simplify flag handling...
r6743 def flagfunc(self, fallback):
if self._checklink:
if self._checkexec:
def f(x):
p = os.path.join(self._root, x)
if os.path.islink(p):
return 'l'
if util.is_exec(p):
return 'x'
return ''
return f
def f(x):
if os.path.islink(os.path.join(self._root, x)):
return 'l'
if 'x' in fallback(x):
return 'x'
return ''
return f
if self._checkexec:
def f(x):
if 'l' in fallback(x):
return 'l'
if util.is_exec(os.path.join(self._root, x)):
return 'x'
return ''
return f
return fallback
mpm@selenic.com
Break apart hg.py...
r1089 def getcwd(self):
cwd = os.getcwd()
Matt Mackall
dirstate: hide internal vars...
r4614 if cwd == self._root: return ''
# self._root ends with a path separator if self._root is '/' or 'C:\'
rootsep = self._root
Shun-ichi GOTO
Add endswithsep() and use it instead of using os.sep and os.altsep directly....
r5843 if not util.endswithsep(rootsep):
Alexis S. L. Carvalho
Fix handling of paths when run outside the repo....
r4230 rootsep += os.sep
if cwd.startswith(rootsep):
return cwd[len(rootsep):]
else:
# we're outside the repo. return an absolute path.
return cwd
mpm@selenic.com
Break apart hg.py...
r1089
Alexis S. L. Carvalho
Add dirstate.pathto and localrepo.pathto....
r4525 def pathto(self, f, cwd=None):
if cwd is None:
cwd = self.getcwd()
Matt Mackall
dirstate: hide internal vars...
r4614 path = util.pathto(self._root, cwd, f)
Alexis S. L. Carvalho
Add ui.slash hgrc setting...
r4527 if self._slash:
Shun-ichi GOTO
Use util.normpath() instead of direct path string operation....
r5842 return util.normpath(path)
Alexis S. L. Carvalho
Add ui.slash hgrc setting...
r4527 return path
Alexis S. L. Carvalho
Add dirstate.pathto and localrepo.pathto....
r4525
mpm@selenic.com
Break apart hg.py...
r1089 def __getitem__(self, key):
Matt Mackall
dirstate: add __contains__ and make __getitem__ more useful...
r4906 ''' current states:
n normal
m needs merging
r marked for removal
a marked for addition
? not tracked'''
return self._map.get(key, ("?",))[0]
mpm@selenic.com
Break apart hg.py...
r1089
def __contains__(self, key):
Matt Mackall
dirstate: hide internal vars...
r4614 return key in self._map
def __iter__(self):
a = self._map.keys()
a.sort()
for x in a:
yield x
mpm@selenic.com
Break apart hg.py...
r1089
def parents(self):
Matt Mackall
dirstate: hide internal vars...
r4614 return self._pl
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
Move branch read/write to dirstate where it belongs
r4179 def branch(self):
return self._branch
mpm@selenic.com
Break apart hg.py...
r1089 def setparents(self, p1, p2=nullid):
Matt Mackall
Merge with crew
r4965 self._dirty = self._dirtypl = True
Matt Mackall
dirstate: hide internal vars...
r4614 self._pl = p1, p2
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
Move branch read/write to dirstate where it belongs
r4179 def setbranch(self, branch):
self._branch = branch
Matt Mackall
dirstate: hide internal vars...
r4614 self._opener("branch", "w").write(branch + '\n')
Matt Mackall
Move branch read/write to dirstate where it belongs
r4179
Matt Mackall
dirstate: hide some more internals
r4615 def _read(self):
Matt Mackall
dirstate: hide internal vars...
r4614 self._map = {}
self._copymap = {}
Alexis S. L. Carvalho
add dirstate._dirtypl variable...
r4952 if not self._dirtypl:
self._pl = [nullid, nullid]
Matt Mackall
dirstate: fold parse into read
r4607 try:
Matt Mackall
dirstate: hide internal vars...
r4614 st = self._opener("dirstate").read()
Matt Mackall
dirstate: fold parse into read
r4607 except IOError, err:
if err.errno != errno.ENOENT: raise
return
if not st:
return
Alexis S. L. Carvalho
add dirstate._dirtypl variable...
r4952 if not self._dirtypl:
self._pl = [st[:20], st[20: 40]]
mpm@selenic.com
Break apart hg.py...
r1089
Vadim Gelfer
dirstate.read: make 15% faster....
r2427 # deref fields so they will be local in loop
Matt Mackall
dirstate: hide internal vars...
r4614 dmap = self._map
copymap = self._copymap
Vadim Gelfer
dirstate.read: make 15% faster....
r2427 unpack = struct.unpack
Matt Mackall
dirstate: simplify state()
r4610 e_size = struct.calcsize(_format)
Matt Mackall
dirstate: speed up read and write...
r5327 pos1 = 40
l = len(st)
Vadim Gelfer
dirstate.read: make 15% faster....
r2427
Matt Mackall
dirstate: speed up read and write...
r5327 # the inner loop
while pos1 < l:
pos2 = pos1 + e_size
e = unpack(">cllll", st[pos1:pos2]) # a literal here is faster
pos1 = pos2 + e[4]
f = st[pos2:pos1]
mpm@selenic.com
Break apart hg.py...
r1089 if '\0' in f:
f, c = f.split('\0')
Matt Mackall
dirstate: add copies function...
r3154 copymap[f] = c
Matt Mackall
dirstate: speed up read and write...
r5327 dmap[f] = e # we hold onto e[4] because making a subtuple is slow
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
localrepo and dirstate: rename reload to invalidate...
r4613 def invalidate(self):
Paul Moore
Add a normalize() method to dirstate...
r6677 for a in "_map _copymap _foldmap _branch _pl _dirs _ignore".split():
Alexis S. L. Carvalho
dirstate.invalidate: avoid rebuilding _map...
r4953 if a in self.__dict__:
delattr(self, a)
Matt Mackall
dirstate: use True and false for _dirty
r4903 self._dirty = False
Bryan O'Sullivan
When reloading the dirstate, recompute ignore information if needed.
r4375
mpm@selenic.com
Break apart hg.py...
r1089 def copy(self, source, dest):
Patrick Mezard
Ignore dummy copies in dirstate and localrepo.filecommit()
r6680 if source == dest:
return
Matt Mackall
dirstate: use True and false for _dirty
r4903 self._dirty = True
Matt Mackall
dirstate: hide internal vars...
r4614 self._copymap[dest] = source
mpm@selenic.com
Break apart hg.py...
r1089
def copied(self, file):
Matt Mackall
dirstate: hide internal vars...
r4614 return self._copymap.get(file, None)
Matt Mackall
dirstate: add copies function...
r3154
def copies(self):
Matt Mackall
dirstate: hide internal vars...
r4614 return self._copymap
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
dirstate: hide some more internals
r4615 def _incpath(self, path):
Matt Mackall
dirstate: make dir collision logic faster...
r5326 c = path.rfind('/')
if c >= 0:
dirs = self._dirs
base = path[:c]
if base not in dirs:
self._incpath(base)
dirs[base] = 1
else:
dirs[base] += 1
Matt Mackall
dirstate: hide some more internals
r4615
def _decpath(self, path):
Maxim Dounin
Fix dir-changed-to-file updates on clean workdir....
r5516 c = path.rfind('/')
if c >= 0:
base = path[:c]
dirs = self._dirs
if dirs[base] == 1:
del dirs[base]
self._decpath(base)
else:
dirs[base] -= 1
Vadim Gelfer
fix issue 322....
r2953
Matt Mackall
dirstate: refactor checkinterfering
r4616 def _incpathcheck(self, f):
if '\r' in f or '\n' in f:
Thomas Arendsen Hein
Report filenames with disallowed characters as suggested by Mika Eloranta...
r6138 raise util.Abort(_("'\\n' and '\\r' disallowed in filenames: %r")
% f)
Matt Mackall
dirstate: refactor checkinterfering
r4616 # shadows
if f in self._dirs:
Bryan O'Sullivan
dirstate: improve error message on file/directory clash
r5045 raise util.Abort(_('directory %r already in dirstate') % f)
Matt Mackall
dirstate: refactor checkinterfering
r4616 for c in strutil.rfindall(f, '/'):
d = f[:c]
if d in self._dirs:
break
Maxim Dounin
Fix file-changed-to-dir and dir-to-file commits (issue660)....
r5487 if d in self._map and self[d] != 'r':
Bryan O'Sullivan
dirstate: improve error message on file/directory clash
r5045 raise util.Abort(_('file %r in dirstate clashes with %r') %
(d, f))
Matt Mackall
dirstate: refactor checkinterfering
r4616 self._incpath(f)
Vadim Gelfer
fix issue 322....
r2953
Maxim Dounin
Fix dir-changed-to-file updates on clean workdir....
r5516 def _changepath(self, f, newstate, relaxed=False):
Maxim Dounin
Fix file-changed-to-dir and dir-to-file commits (issue660)....
r5487 # handle upcoming path changes
oldstate = self[f]
if oldstate not in "?r" and newstate in "?r":
Maxim Dounin
Fix dir-changed-to-file updates on clean workdir....
r5516 if "_dirs" in self.__dict__:
self._decpath(f)
Maxim Dounin
Fix file-changed-to-dir and dir-to-file commits (issue660)....
r5487 return
if oldstate in "?r" and newstate not in "?r":
Maxim Dounin
Fix dir-changed-to-file updates on clean workdir....
r5516 if relaxed and oldstate == '?':
# XXX
# in relaxed mode we assume the caller knows
# what it is doing, workaround for updating
# dir-to-file revisions
if "_dirs" in self.__dict__:
self._incpath(f)
return
Maxim Dounin
Fix file-changed-to-dir and dir-to-file commits (issue660)....
r5487 self._incpathcheck(f)
return
Matt Mackall
dirstate: break update into separate functions
r4904 def normal(self, f):
Alexis S. L. Carvalho
merge: forcefully mark files that we get from the second parent as dirty...
r5210 'mark a file normal and clean'
Matt Mackall
dirstate: break update into separate functions
r4904 self._dirty = True
Maxim Dounin
Fix dir-changed-to-file updates on clean workdir....
r5516 self._changepath(f, 'n', True)
Matt Mackall
dirstate: make wjoin function private
r4905 s = os.lstat(self._join(f))
Matt Mackall
dirstate: speed up read and write...
r5327 self._map[f] = ('n', s.st_mode, s.st_size, s.st_mtime, 0)
Christian Ebert
Prefer i in d over d.has_key(i)
r5915 if f in self._copymap:
Matt Mackall
dirstate: break update into separate functions
r4904 del self._copymap[f]
mpm@selenic.com
Break apart hg.py...
r1089
Alexis S. L. Carvalho
merge: forcefully mark files that we get from the second parent as dirty...
r5210 def normallookup(self, f):
Matt Mackall
dirstate: break update into separate functions
r4904 'mark a file normal, but possibly dirty'
Alexis S. L. Carvalho
normallookup: during merges, restore the state saved by remove
r6298 if self._pl[1] != nullid and f in self._map:
# if there is a merge going on and the file was either
# in state 'm' or dirty before being removed, restore that state.
entry = self._map[f]
if entry[0] == 'r' and entry[2] in (-1, -2):
source = self._copymap.get(f)
if entry[2] == -1:
self.merge(f)
elif entry[2] == -2:
self.normaldirty(f)
if source:
self.copy(source, f)
return
if entry[0] == 'm' or entry[0] == 'n' and entry[2] == -2:
return
Matt Mackall
dirstate: use True and false for _dirty
r4903 self._dirty = True
Maxim Dounin
Fix dir-changed-to-file updates on clean workdir....
r5516 self._changepath(f, 'n', True)
Matt Mackall
dirstate: speed up read and write...
r5327 self._map[f] = ('n', 0, -1, -1, 0)
Alexis S. L. Carvalho
merge: forcefully mark files that we get from the second parent as dirty...
r5210 if f in self._copymap:
del self._copymap[f]
def normaldirty(self, f):
'mark a file normal, but dirty'
self._dirty = True
Maxim Dounin
Fix dir-changed-to-file updates on clean workdir....
r5516 self._changepath(f, 'n', True)
Matt Mackall
dirstate: speed up read and write...
r5327 self._map[f] = ('n', 0, -2, -1, 0)
Matt Mackall
dirstate: break update into separate functions
r4904 if f in self._copymap:
del self._copymap[f]
def add(self, f):
'mark a file added'
self._dirty = True
Maxim Dounin
Fix file-changed-to-dir and dir-to-file commits (issue660)....
r5487 self._changepath(f, 'a')
Matt Mackall
dirstate: speed up read and write...
r5327 self._map[f] = ('a', 0, -1, -1, 0)
Matt Mackall
dirstate: break update into separate functions
r4904 if f in self._copymap:
del self._copymap[f]
Matt Mackall
dirstate: refactor checkinterfering
r4616
Matt Mackall
dirstate: break update into separate functions
r4904 def remove(self, f):
'mark a file removed'
self._dirty = True
Maxim Dounin
Fix file-changed-to-dir and dir-to-file commits (issue660)....
r5487 self._changepath(f, 'r')
Alexis S. L. Carvalho
dirstate.remove: during merges, remember the previous file state...
r6297 size = 0
if self._pl[1] != nullid and f in self._map:
entry = self._map[f]
if entry[0] == 'm':
size = -1
elif entry[0] == 'n' and entry[2] == -2:
size = -2
self._map[f] = ('r', 0, size, 0, 0)
if size == 0 and f in self._copymap:
Matt Mackall
dirstate: break update into separate functions
r4904 del self._copymap[f]
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
dirstate: break update into separate functions
r4904 def merge(self, f):
'mark a file merged'
Matt Mackall
dirstate: use True and false for _dirty
r4903 self._dirty = True
Matt Mackall
dirstate: make wjoin function private
r4905 s = os.lstat(self._join(f))
Maxim Dounin
Fix dir-changed-to-file updates on clean workdir....
r5516 self._changepath(f, 'm', True)
Matt Mackall
dirstate: speed up read and write...
r5327 self._map[f] = ('m', s.st_mode, s.st_size, s.st_mtime, 0)
Matt Mackall
dirstate: break update into separate functions
r4904 if f in self._copymap:
del self._copymap[f]
def forget(self, f):
'forget a file'
self._dirty = True
try:
Maxim Dounin
Fix file-changed-to-dir and dir-to-file commits (issue660)....
r5487 self._changepath(f, '?')
Matt Mackall
dirstate: break update into separate functions
r4904 del self._map[f]
except KeyError:
Thomas Arendsen Hein
Remove trailing ! from two error messages as this was confusing.
r6057 self._ui.warn(_("not in dirstate: %s\n") % f)
mpm@selenic.com
Break apart hg.py...
r1089
Paul Moore
Add a normalize() method to dirstate...
r6677 def _normalize(self, path):
normpath = os.path.normcase(os.path.normpath(path))
if normpath in self._foldmap:
return self._foldmap[normpath]
elif os.path.exists(path):
self._foldmap[normpath] = util.fspath(path, self._root)
return self._foldmap[normpath]
else:
return path
Alexis S. L. Carvalho
dirstate: fix rebuild; add a test...
r5065 def clear(self):
self._map = {}
Maxim Dounin
Fix file-changed-to-dir and dir-to-file commits (issue660)....
r5487 if "_dirs" in self.__dict__:
delattr(self, "_dirs");
Alexis S. L. Carvalho
dirstate: fix rebuild; add a test...
r5065 self._copymap = {}
self._pl = [nullid, nullid]
Alexis S. L. Carvalho
merge with crew-stable
r5123 self._dirty = True
Alexis S. L. Carvalho
dirstate: fix rebuild; add a test...
r5065
Benoit Boissinot
add 'debugrebuildstate' to rebuild the dirstate from a given revision...
r1755 def rebuild(self, parent, files):
Alexis S. L. Carvalho
dirstate: fix rebuild; add a test...
r5065 self.clear()
Matt Mackall
Start using manifestflags methods
r2832 for f in files:
Matt Mackall
add __len__ and __iter__ methods to repo and revlog
r6750 if 'x' in files.flags(f):
Matt Mackall
dirstate: speed up read and write...
r5327 self._map[f] = ('n', 0777, -1, 0, 0)
Benoit Boissinot
add 'debugrebuildstate' to rebuild the dirstate from a given revision...
r1755 else:
Matt Mackall
dirstate: speed up read and write...
r5327 self._map[f] = ('n', 0666, -1, 0, 0)
Matt Mackall
dirstate: hide internal vars...
r4614 self._pl = (parent, nullid)
Matt Mackall
dirstate: use True and false for _dirty
r4903 self._dirty = True
mpm@selenic.com
Break apart hg.py...
r1089
def write(self):
Matt Mackall
dirstate: simplify dirty handling
r4612 if not self._dirty:
Benoit Boissinot
only write the dirstate when something changed
r1794 return
Alexis S. L. Carvalho
dirstate: ignore stat data for files that were updated too recently...
r6326 st = self._opener("dirstate", "w", atomictemp=True)
Matt Mackall
dirstate: refactor granularity code, add a test...
r6327
try:
gran = int(self._ui.config('dirstate', 'granularity', 1))
except ValueError:
gran = 1
limit = sys.maxint
if gran > 0:
limit = util.fstat(st).st_mtime - gran
Bryan O'Sullivan
dirstate: speed up write by 50%.
r4374 cs = cStringIO.StringIO()
Matt Mackall
dirstate: speed up read and write...
r5327 copymap = self._copymap
pack = struct.pack
write = cs.write
write("".join(self._pl))
Matt Mackall
dirstate: hide internal vars...
r4614 for f, e in self._map.iteritems():
Matt Mackall
dirstate: speed up read and write...
r5327 if f in copymap:
f = "%s\0%s" % (f, copymap[f])
Alexis S. L. Carvalho
dirstate: ignore stat data for files that were updated too recently...
r6326 if e[3] > limit and e[0] == 'n':
e = (e[0], 0, -1, -1, 0)
Matt Mackall
dirstate: speed up read and write...
r5327 e = pack(_format, e[0], e[1], e[2], e[3], len(f))
write(e)
write(f)
Bryan O'Sullivan
dirstate: speed up write by 50%.
r4374 st.write(cs.getvalue())
Alexis S. L. Carvalho
Use atomictemp files to write the dirstate....
r4507 st.rename()
Matt Mackall
Merge with crew
r4965 self._dirty = self._dirtypl = False
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
dirstate: make filterfiles private
r4907 def _filter(self, files):
mpm@selenic.com
Break apart hg.py...
r1089 ret = {}
unknown = []
for x in files:
twaldmann@thinkmo.de
fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
r1541 if x == '.':
Matt Mackall
dirstate: hide internal vars...
r4614 return self._map.copy()
if x not in self._map:
mpm@selenic.com
Break apart hg.py...
r1089 unknown.append(x)
else:
Matt Mackall
dirstate: hide internal vars...
r4614 ret[x] = self._map[x]
mpm@selenic.com
Break apart hg.py...
r1089
if not unknown:
return ret
Matt Mackall
dirstate: hide internal vars...
r4614 b = self._map.keys()
mpm@selenic.com
Break apart hg.py...
r1089 b.sort()
blen = len(b)
for x in unknown:
Benoit Boissinot
simplify filterfiles when filtering based on a directory...
r2486 bs = bisect.bisect(b, "%s%s" % (x, '/'))
mpm@selenic.com
Break apart hg.py...
r1089 while bs < blen:
s = b[bs]
Brendan Cully
filterfiles: Search as long as the target is a prefix of current....
r2485 if len(s) > len(x) and s.startswith(x):
Matt Mackall
dirstate: hide internal vars...
r4614 ret[s] = self._map[s]
mpm@selenic.com
Break apart hg.py...
r1089 else:
break
bs += 1
return ret
Matt Mackall
revlog: pass mode to _supported directly
r5001 def _supported(self, f, mode, verbose=False):
if stat.S_ISREG(mode) or stat.S_ISLNK(mode):
Benoit Boissinot
fix handling of files of unsupported type in the walk code...
r1487 return True
if verbose:
kind = 'unknown'
Matt Mackall
revlog: pass mode to _supported directly
r5001 if stat.S_ISCHR(mode): kind = _('character device')
elif stat.S_ISBLK(mode): kind = _('block device')
elif stat.S_ISFIFO(mode): kind = _('fifo')
elif stat.S_ISSOCK(mode): kind = _('socket')
elif stat.S_ISDIR(mode): kind = _('directory')
Matt Mackall
dirstate: hide internal vars...
r4614 self._ui.warn(_('%s: unsupported file type (type is %s)\n')
Thomas Arendsen Hein
Cleanup of whitespace, indentation and line continuation.
r4633 % (self.pathto(f), kind))
Benoit Boissinot
fix handling of files of unsupported type in the walk code...
r1487 return False
Alexis S. L. Carvalho
dirstate: don't walk ignored directories...
r6032 def _dirignore(self, f):
Patrick Mezard
dirstate: do not ignore current directory '.' (issue 1078)
r6479 if f == '.':
return False
Alexis S. L. Carvalho
dirstate: don't walk ignored directories...
r6032 if self._ignore(f):
return True
for c in strutil.findall(f, '/'):
if self._ignore(f[:c]):
return True
return False
Matt Mackall
dirstate: fold statwalk and walk
r6755 def walk(self, match, unknown, ignored):
Matt Mackall
simplify dirstate walking...
r3529 '''
walk recursively through the directory tree, finding all files
matched by the match function
results are yielded in a tuple (src, filename, st), where src
is one of:
'f' the file was found in the directory tree
'm' the file was only in the dirstate and not in the tree
Matt Mackall
improve walk docstrings
r3532
Matt Mackall
simplify dirstate walking...
r3529 and st is the stat result if the file was found in the directory.
'''
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
walk: begin refactoring badmatch handling
r6578 def fwarn(f, msg):
self._ui.warn('%s: %s\n' % (self.pathto(ff), msg))
return False
Matt Mackall
walk: use match.bad in statwalk
r6589 badfn = fwarn
if hasattr(match, 'bad'):
badfn = match.bad
Matt Mackall
walk: begin refactoring badmatch handling
r6578
mpm@selenic.com
Break apart hg.py...
r1089 # walk all files by default
Matt Mackall
match: remove files arg from repo.status and friends
r6603 files = match.files()
mpm@selenic.com
Break apart hg.py...
r1089 if not files:
Alexis S. L. Carvalho
statwalk: don't put self.root in the files list...
r4172 files = ['.']
Matt Mackall
dirstate: hide internal vars...
r4614 dc = self._map.copy()
Matt Mackall
simplify dirstate walking...
r3529 else:
Matt Mackall
small refactoring of path normalization in dirstate.statwalk
r3536 files = util.unique(files)
Matt Mackall
dirstate: make filterfiles private
r4907 dc = self._filter(files)
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
simplify dirstate walking...
r3529 def imatch(file_):
Matt Mackall
dirstate: move ignore to its own file
r4609 if file_ not in dc and self._ignore(file_):
mason@suse.com
Optimize dirstate walking...
r1183 return False
Benoit Boissinot
fix warnings from pychecker (unused variables and shadowing)
r1749 return match(file_)
mpm@selenic.com
Fix Windows status problem from new dirstate walk code
r1224
Thomas Arendsen Hein
Extend/correct acc40572da5b regarding -qA and ignored files....
r6201 # TODO: don't walk unknown directories if unknown and ignored are False
Matt Mackall
dirstate: move ignore to its own file
r4609 ignore = self._ignore
Alexis S. L. Carvalho
dirstate: don't walk ignored directories...
r6032 dirignore = self._dirignore
Alexis S. L. Carvalho
dirstate.statwalk: explicitly test for ignored directories...
r4193 if ignored:
imatch = match
ignore = util.never
Alexis S. L. Carvalho
dirstate: don't walk ignored directories...
r6032 dirignore = util.never
Matt Mackall
Simplify ignore logic in dirstate.walk...
r3534
Matt Mackall
dirstate: hide internal vars...
r4614 # self._root may end with a path separator when self._root == '/'
common_prefix_len = len(self._root)
Shun-ichi GOTO
Add endswithsep() and use it instead of using os.sep and os.altsep directly....
r5843 if not util.endswithsep(self._root):
Benoit Boissinot
self.root == '/': prefix length computation out of the loop...
r2671 common_prefix_len += 1
Matt Mackall
dirstate: localize a bunch of methods for findfiles
r5000
normpath = util.normpath
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 listdir = osutil.listdir
Matt Mackall
dirstate: localize a bunch of methods for findfiles
r5000 lstat = os.lstat
bisect_left = bisect.bisect_left
isdir = os.path.isdir
pconvert = util.pconvert
join = os.path.join
s_isdir = stat.S_ISDIR
supported = self._supported
Matt Mackall
revlog: pass mode to _supported directly
r5001 _join = self._join
known = {'.hg': 1}
Matt Mackall
dirstate: localize a bunch of methods for findfiles
r5000
mason@suse.com
Optimize dirstate walking...
r1183 # recursion free walker, faster than os.walk.
def findfiles(s):
work = [s]
Matt Mackall
dirstate: speed up sorting in findfiles
r5002 wadd = work.append
found = []
add = found.append
Matt Mackall
walk: use match.dir in statwalk
r6588 if hasattr(match, 'dir'):
match.dir(normpath(s[common_prefix_len:]))
mason@suse.com
Optimize dirstate walking...
r1183 while work:
top = work.pop()
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 entries = listdir(top, stat=True)
mason@suse.com
Optimize dirstate walking...
r1183 # nd is the top of the repository dir tree
Matt Mackall
dirstate: localize a bunch of methods for findfiles
r5000 nd = normpath(top[common_prefix_len:])
Vadim Gelfer
support nested repositories....
r2061 if nd == '.':
nd = ''
else:
Vadim Gelfer
benoit asked for comment to make avoid of recursive repo clearer.
r2063 # do not recurse into a repo contained in this
# one. use bisect to find .hg directory so speed
# is good on big directory.
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 names = [e[0] for e in entries]
Matt Mackall
dirstate: localize a bunch of methods for findfiles
r5000 hg = bisect_left(names, '.hg')
Vadim Gelfer
support nested repositories....
r2061 if hg < len(names) and names[hg] == '.hg':
Matt Mackall
dirstate: localize a bunch of methods for findfiles
r5000 if isdir(join(top, '.hg')):
Vadim Gelfer
support nested repositories....
r2061 continue
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 for f, kind, st in entries:
Matt Mackall
revlog: pass mode to _supported directly
r5001 np = pconvert(join(nd, f))
Matt Mackall
dirstate: improve case-folding logic...
r6756 nn = self.normalize(np)
Matt Mackall
revlog: pass mode to _supported directly
r5001 if np in known:
mason@suse.com
Optimize dirstate walking...
r1183 continue
Matt Mackall
dirstate: improve case-folding logic...
r6756 known[nn] = 1
Matt Mackall
dirstate: localize a bunch of methods for findfiles
r5000 p = join(top, f)
mpm@selenic.com
Fix dangling symlink bug in dirstate walk code
r1228 # don't trip over symlinks
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 if kind == stat.S_IFDIR:
Alexis S. L. Carvalho
Pass normalized directory names to the ignore function...
r4254 if not ignore(np):
Matt Mackall
dirstate: speed up sorting in findfiles
r5002 wadd(p)
Matt Mackall
walk: use match.dir in statwalk
r6588 if hasattr(match, 'dir'):
match.dir(np)
Matt Mackall
revlog: pass mode to _supported directly
r5001 if np in dc and match(np):
Matt Mackall
dirstate: improve case-folding logic...
r6756 add((nn, 'm', st))
Matt Mackall
simplify dirstate walking...
r3529 elif imatch(np):
Matt Mackall
revlog: pass mode to _supported directly
r5001 if supported(np, st.st_mode):
Matt Mackall
dirstate: improve case-folding logic...
r6756 add((nn, 'f', st))
Benoit Boissinot
fix handling of files of unsupported type in the walk code...
r1487 elif np in dc:
Matt Mackall
dirstate: improve case-folding logic...
r6756 add((nn, 'm', st))
Matt Mackall
dirstate: speed up sorting in findfiles
r5002 found.sort()
return found
mason@suse.com
Optimize dirstate walking...
r1183
# step one, find all files that match our criteria
files.sort()
Matt Mackall
small refactoring of path normalization in dirstate.statwalk
r3536 for ff in files:
Matt Mackall
dirstate: localize a bunch of methods for findfiles
r5000 nf = normpath(ff)
Matt Mackall
dirstate: improve case-folding logic...
r6756 nn = self.normalize(nf)
Matt Mackall
revlog: pass mode to _supported directly
r5001 f = _join(ff)
mason@suse.com
Optimize dirstate walking...
r1183 try:
Matt Mackall
dirstate: localize a bunch of methods for findfiles
r5000 st = lstat(f)
mason@suse.com
Optimize dirstate walking...
r1183 except OSError, inst:
Benoit Boissinot
Re: [PATCH 2 of 3] remove walk warning about nonexistent files...
r1564 found = False
for fn in dc:
if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'):
found = True
break
if not found:
Matt Mackall
walk: begin refactoring badmatch handling
r6578 if inst.errno != errno.ENOENT:
fwarn(ff, inst.strerror)
elif badfn(ff, inst.strerror) and imatch(nf):
Matt Mackall
walk: remove more old badmatch logic
r6583 yield 'f', ff, None
mason@suse.com
Optimize dirstate walking...
r1183 continue
Matt Mackall
dirstate: localize a bunch of methods for findfiles
r5000 if s_isdir(st.st_mode):
Alexis S. L. Carvalho
dirstate: don't walk ignored directories...
r6032 if not dirignore(nf):
for f, src, st in findfiles(f):
yield src, f, st
Benoit Boissinot
add a check for filetype when walking
r1392 else:
Matt Mackall
dirstate: improve case-folding logic...
r6756 if nn in known:
Matt Mackall
revlog: pass mode to _supported directly
r5001 continue
Matt Mackall
dirstate: improve case-folding logic...
r6756 known[nn] = 1
Matt Mackall
revlog: pass mode to _supported directly
r5001 if match(nf):
if supported(ff, st.st_mode, verbose=True):
Paul Moore
Add a normalize() method to dirstate...
r6677 yield 'f', self.normalize(nf), st
Benoit Boissinot
fix handling of files of unsupported type in the walk code...
r1487 elif ff in dc:
Matt Mackall
small refactoring of path normalization in dirstate.statwalk
r3536 yield 'm', nf, st
mpm@selenic.com
Break apart hg.py...
r1089
mason@suse.com
Optimize dirstate walking...
r1183 # step two run through anything left in the dc hash and yield
# if we haven't already seen it
ks = dc.keys()
ks.sort()
for k in ks:
Matt Mackall
revlog: pass mode to _supported directly
r5001 if k in known:
continue
known[k] = 1
if imatch(k):
Benoit Boissinot
rewrote changes function in dirstate to use generic walk code...
r1471 yield 'm', k, None
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
repo.status: eliminate list_
r6753 def status(self, match, ignored, clean, unknown):
listignored, listclean, listunknown = ignored, clean, unknown
Thomas Arendsen Hein
New option -i/--ignored for 'hg status' to show ignored files....
r2022 lookup, modified, added, unknown, ignored = [], [], [], [], []
Vadim Gelfer
status: add -c (clean) and -A (all files) options...
r2661 removed, deleted, clean = [], [], []
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 _join = self._join
lstat = os.lstat
cmap = self._copymap
dmap = self._map
ladd = lookup.append
madd = modified.append
aadd = added.append
uadd = unknown.append
iadd = ignored.append
radd = removed.append
dadd = deleted.append
cadd = clean.append
Matt Mackall
dirstate: fold statwalk and walk
r6755 for src, fn, st in self.walk(match, listunknown, listignored):
Matt Mackall
dirstate: minor status cleanups
r6591 if fn not in dmap:
Matt Mackall
repo.status: eliminate list_
r6753 if (listignored or match.exact(fn)) and self._dirignore(fn):
if listignored:
Alexis S. L. Carvalho
dirstate.status: avoid putting ignored files in the unknown list...
r6033 iadd(fn)
Matt Mackall
repo.status: eliminate list_
r6753 elif listunknown:
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 uadd(fn)
Benoit Boissinot
rewrote changes function in dirstate to use generic walk code...
r1471 continue
Matt Mackall
dirstate: minor status cleanups
r6591
state, mode, size, time, foo = dmap[fn]
Benoit Boissinot
fix dirstate.change: it should walk ignored files
r1476 if src == 'm':
Benoit Boissinot
fix handling of files of unsupported type in the walk code...
r1487 nonexistent = True
if not st:
try:
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 st = lstat(_join(fn))
Benoit Boissinot
fix handling of files of unsupported type in the walk code...
r1487 except OSError, inst:
Maxim Dounin
Fix file-changed-to-dir and dir-to-file commits (issue660)....
r5487 if inst.errno not in (errno.ENOENT, errno.ENOTDIR):
Benoit Boissinot
fix handling of files of unsupported type in the walk code...
r1487 raise
st = None
# We need to re-check that it is a valid file
Matt Mackall
revlog: pass mode to _supported directly
r5001 if st and self._supported(fn, st.st_mode):
Benoit Boissinot
fix handling of files of unsupported type in the walk code...
r1487 nonexistent = False
Matt Mackall
status: rename type_ to state
r6590 if nonexistent and state in "nma":
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 dadd(fn)
Benoit Boissinot
fix dirstate.change: it should walk ignored files
r1476 continue
Benoit Boissinot
rewrote changes function in dirstate to use generic walk code...
r1471 # check the common case first
Matt Mackall
status: rename type_ to state
r6590 if state == 'n':
Benoit Boissinot
rewrote changes function in dirstate to use generic walk code...
r1471 if not st:
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 st = lstat(_join(fn))
Alexis S. L. Carvalho
dirstate: ignore mode changes if the fs does not supports the exec bit...
r6257 if (size >= 0 and
(size != st.st_size
or ((mode ^ st.st_mode) & 0100 and self._checkexec))
Alexis S. L. Carvalho
merge: forcefully mark files that we get from the second parent as dirty...
r5210 or size == -2
Alexis S. L. Carvalho
dirstate.status: if a file is marked as copied, consider it modified...
r4677 or fn in self._copymap):
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 madd(fn)
Alexis S. L. Carvalho
dirstate.py: when comparing mtimes, use only the integer part....
r2962 elif time != int(st.st_mtime):
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 ladd(fn)
Matt Mackall
repo.status: eliminate list_
r6753 elif listclean:
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 cadd(fn)
Matt Mackall
status: rename type_ to state
r6590 elif state == 'm':
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 madd(fn)
Matt Mackall
status: rename type_ to state
r6590 elif state == 'a':
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 aadd(fn)
Matt Mackall
status: rename type_ to state
r6590 elif state == 'r':
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 radd(fn)
mason@suse.com
Optimize dirstate walking...
r1183
Vadim Gelfer
status: add -c (clean) and -A (all files) options...
r2661 return (lookup, modified, added, removed, deleted, unknown, ignored,
clean)