##// END OF EJS Templates
verify: check the subrepository references in .hgsubstate...
verify: check the subrepository references in .hgsubstate While hopefully atypical, there are reasons that a subrepository revision can be lost that aren't covered by corruption of the .hgsubstate revlog. Such things can happen when a subrepo is amended, stripped or simply isn't pulled from upstream because the parent repo revision wasn't updated yet. There's no way to know if it is an error, but this will find potential problems sooner than when some random revision is updated. Until recently, convert made no attempt at rewriting the .hgsubstate file. The impetuous for this is to verify the conversion of some repositories, and this is orders of magnitude faster than a bash script from 0..tip that does an 'hg update -C $rev'. But it is equally useful to determine if everything has been pulled down before taking a thumb drive on the go. It feels somewhat wrong to leave this out of verifymod (mostly because the file is already read in there, and the final summary is printed before the subrepos are checked). But verifymod looks very low level, so importing subrepo stuff there seems more wrong.

File last commit:

r25585:868b7ee8 default
r25591:f1d46075 default
Show More
dirstate.py
1006 lines | 35.6 KiB | text/x-python | PythonLexer
Martin Geisler
put license and copyright info into comment blocks
r8226 # dirstate.py - working directory tracking for mercurial
#
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
mpm@selenic.com
Break apart hg.py...
r1089
Joel Rosdahl
Expand import * to allow Pyflakes to find problems
r6211 from node import nullid
Matt Mackall
Simplify i18n imports
r3891 from i18n import _
Durham Goode
ignore: use 'include:' rules instead of custom syntax...
r25216 import scmutil, util, osutil, parsers, encoding, pathutil
Pierre-Yves David
dirstate: use the 'nogc' decorator...
r23496 import os, stat, errno
Durham Goode
ignore: use 'include:' rules instead of custom syntax...
r25216 import match as matchmod
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
dirstate: use propertycache
r8261 propertycache = util.propertycache
Idan Kamara
dirstate: filecacheify _branch...
r16201 filecache = scmutil.filecache
Matt Mackall
dirstate: handle large dates and times with masking (issue2608)...
r17733 _rangemask = 0x7fffffff
Idan Kamara
dirstate: filecacheify _branch...
r16201
Siddharth Agarwal
parsers: inline fields of dirstate values in C version...
r21809 dirstatetuple = parsers.dirstatetuple
Siddharth Agarwal
dirstate: add dirstatetuple to create dirstate values...
r21808
Idan Kamara
dirstate: filecacheify _branch...
r16201 class repocache(filecache):
"""filecache for files in .hg/"""
def join(self, obj, fname):
return obj._opener.join(fname)
Matt Mackall
dirstate: simplify state()
r4610
Idan Kamara
dirstate: filecacheify _ignore (issue3278)...
r16202 class rootcache(filecache):
"""filecache for files in the repository root"""
def join(self, obj, fname):
return obj._join(fname)
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
Matt Mackall
dirstate: warn on invalid parents rather than aborting...
r13032 def __init__(self, opener, ui, root, validate):
Martin Geisler
dirstate: improve docstring formatting...
r10145 '''Create a new dirstate object.
opener is an open()-like callable that can be used to open the
dirstate file; root is the root of the directory tracked by
the dirstate.
'''
Matt Mackall
dirstate: hide internal vars...
r4614 self._opener = opener
Matt Mackall
dirstate: warn on invalid parents rather than aborting...
r13032 self._validate = validate
Matt Mackall
dirstate: hide internal vars...
r4614 self._root = root
Yuya Nishihara
dirstate: make sure rootdir ends with directory separator (issue4557)...
r24198 # ntpath.join(root, '') of Python 2.7.9 does not add sep if root is
# UNC path pointing to root share (issue4557)
FUJIWARA Katsunori
dirstate: use pathutil.normasprefix to ensure os.sep at the end of root...
r24833 self._rootdir = pathutil.normasprefix(root)
Matt Mackall
dirstate: use True and false for _dirty
r4903 self._dirty = False
Matt Mackall
Merge with crew
r4965 self._dirtypl = False
Martin Geisler
Use explicit integer division...
r15791 self._lastnormaltime = 0
Matt Mackall
dirstate: hide internal vars...
r4614 self._ui = ui
Idan Kamara
dirstate: add filecache support
r16200 self._filecache = {}
Durham Goode
dirstate: add begin/endparentchange to dirstate...
r22404 self._parentwriters = 0
FUJIWARA Katsunori
dirstate: use self._filename instead of immediate string `dirstate`...
r25226 self._filename = 'dirstate'
Durham Goode
dirstate: add begin/endparentchange to dirstate...
r22404
def beginparentchange(self):
'''Marks the beginning of a set of changes that involve changing
the dirstate parents. If there is an exception during this time,
the dirstate will not be written when the wlock is released. This
prevents writing an incoherent dirstate where the parent doesn't
match the contents.
'''
self._parentwriters += 1
def endparentchange(self):
'''Marks the end of a set of changes that involve changing the
dirstate parents. Once all parent changes have been marked done,
the wlock will be free to write the dirstate on release.
'''
if self._parentwriters > 0:
self._parentwriters -= 1
def pendingparentchange(self):
'''Returns true if the dirstate is in the middle of a set of changes
that modify the dirstate parent.
'''
return self._parentwriters > 0
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
dirstate: use propertycache
r8261 @propertycache
def _map(self):
Greg Ward
dirstate: add/improve method docstrings....
r9518 '''Return the dirstate contents as a map from filename to
(state, mode, size, time).'''
Matt Mackall
dirstate: use propertycache
r8261 self._read()
return self._map
@propertycache
def _copymap(self):
self._read()
return self._copymap
@propertycache
Siddharth Agarwal
dirstate: split the foldmap into separate ones for files and directories...
r24540 def _filefoldmap(self):
Siddharth Agarwal
dirstate: use parsers.make_file_foldmap when available...
r24610 try:
makefilefoldmap = parsers.make_file_foldmap
except AttributeError:
pass
else:
return makefilefoldmap(self._map, util.normcasespec,
util.normcasefallback)
Matt Mackall
dirstate: use propertycache
r8261 f = {}
Siddharth Agarwal
dirstate: cache util.normcase while constructing the foldmap...
r22782 normcase = util.normcase
FUJIWARA Katsunori
icasefs: ignore removed files at building "dirstate._foldmap" up on icasefs...
r19103 for name, s in self._map.iteritems():
if s[0] != 'r':
Siddharth Agarwal
dirstate: cache util.normcase while constructing the foldmap...
r22782 f[normcase(name)] = name
Siddharth Agarwal
dirstate: split the foldmap into separate ones for files and directories...
r24540 f['.'] = '.' # prevents useless util.fspath() invocation
return f
@propertycache
def _dirfoldmap(self):
f = {}
normcase = util.normcase
Matt Mackall
dirstate: normalize case of directory components...
r16302 for name in self._dirs:
Siddharth Agarwal
dirstate: cache util.normcase while constructing the foldmap...
r22782 f[normcase(name)] = name
Matt Mackall
dirstate: use propertycache
r8261 return f
Idan Kamara
dirstate: filecacheify _branch...
r16201 @repocache('branch')
Matt Mackall
dirstate: use propertycache
r8261 def _branch(self):
try:
Dan Villiom Podlaski Christiansen
prevent transient leaks of file handle by using new helper functions...
r14168 return self._opener.read("branch").strip() or "default"
Pierre-Yves David
dirstate: propagate IOError other than ENOENT when reading branch
r15799 except IOError, inst:
if inst.errno != errno.ENOENT:
raise
Matt Mackall
dirstate: use propertycache
r8261 return "default"
@propertycache
def _pl(self):
try:
FUJIWARA Katsunori
dirstate: use self._filename instead of immediate string `dirstate`...
r25226 fp = self._opener(self._filename)
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 st = fp.read(40)
fp.close()
Matt Mackall
dirstate: don't complain about 0-length files
r8716 l = len(st)
if l == 40:
Matt Mackall
dirstate: use propertycache
r8261 return st[:20], st[20:40]
Matt Mackall
dirstate: don't complain about 0-length files
r8716 elif l > 0 and l < 40:
Matt Mackall
dirstate: notice truncated parents read
r8640 raise util.Abort(_('working directory state appears damaged!'))
Matt Mackall
dirstate: use propertycache
r8261 except IOError, err:
Matt Mackall
many, many trivial check-code fixups
r10282 if err.errno != errno.ENOENT:
raise
Matt Mackall
dirstate: use propertycache
r8261 return [nullid, nullid]
@propertycache
def _dirs(self):
Drew Gottlieb
util: move dirs() and finddirs() from scmutil to util...
r24635 return util.dirs(self._map, 'r')
Matt Mackall
dirstate: use propertycache
r8261
FUJIWARA Katsunori
context: add 'dirs()' to changectx/workingctx for directory patterns...
r16143 def dirs(self):
return self._dirs
Idan Kamara
dirstate: filecacheify _ignore (issue3278)...
r16202 @rootcache('.hgignore')
Matt Mackall
dirstate: use propertycache
r8261 def _ignore(self):
Durham Goode
ignore: remove .hgignore from ignore list if nonexistent...
r25163 files = []
if os.path.exists(self._join('.hgignore')):
files.append(self._join('.hgignore'))
Matt Mackall
dirstate: use propertycache
r8261 for name, path in self._ui.configitems("ui"):
if name == 'ignore' or name.startswith('ignore.'):
Siddharth Agarwal
ignore: resolve ignore files relative to repo root (issue4473) (BC)...
r23629 # we need to use os.path.join here rather than self._join
# because path is arbitrary and user-specified
files.append(os.path.join(self._rootdir, util.expandpath(path)))
Durham Goode
ignore: use 'include:' rules instead of custom syntax...
r25216
if not files:
return util.never
pats = ['include:%s' % f for f in files]
return matchmod.match(self._root, '', [], pats, warn=self._ui.warn)
Matt Mackall
dirstate: use propertycache
r8261
@propertycache
def _slash(self):
return self._ui.configbool('ui', 'slash') and os.sep != '/'
@propertycache
def _checklink(self):
return util.checklink(self._root)
@propertycache
def _checkexec(self):
return util.checkexec(self._root)
@propertycache
def _checkcase(self):
return not util.checkcase(self._join('.hg'))
Matt Mackall
dirstate: make wjoin function private
r4905 def _join(self, f):
Benoit Boissinot
performance: normalize self._root, avoid calling os.path.join() in dirstate...
r6972 # much faster than os.path.join()
Benoit Boissinot
dirstate: explain why appending instead of os.path.join() is safe
r6973 # it's safe because f is always a relative path
Benoit Boissinot
performance: normalize self._root, avoid calling os.path.join() in dirstate...
r6972 return self._rootdir + f
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
windows: recompute flags when committing a merge (issue1802)...
r15337 def flagfunc(self, buildfallback):
if self._checklink and self._checkexec:
def f(x):
Bryan O'Sullivan
dirstate: only call lstat once per flags invocation...
r18869 try:
st = os.lstat(self._join(x))
if util.statislink(st):
return 'l'
if util.statisexec(st):
return 'x'
except OSError:
pass
Matt Mackall
windows: recompute flags when committing a merge (issue1802)...
r15337 return ''
return f
fallback = buildfallback()
Matt Mackall
simplify flag handling...
r6743 if self._checklink:
def f(x):
Benoit Boissinot
performance: normalize self._root, avoid calling os.path.join() in dirstate...
r6972 if os.path.islink(self._join(x)):
Matt Mackall
simplify flag handling...
r6743 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'
Adrian Buehlmann
rename util.is_exec to isexec
r14273 if util.isexec(self._join(x)):
Matt Mackall
simplify flag handling...
r6743 return 'x'
return ''
return f
Matt Mackall
windows: recompute flags when committing a merge (issue1802)...
r15337 else:
return fallback
Matt Mackall
simplify flag handling...
r6743
Pierre-Yves David
rebase: do not crash in panic when cwd disapear in the process (issue4121)...
r20335 @propertycache
def _cwd(self):
return os.getcwd()
mpm@selenic.com
Break apart hg.py...
r1089 def getcwd(self):
Pierre-Yves David
rebase: do not crash in panic when cwd disapear in the process (issue4121)...
r20335 cwd = self._cwd
Matt Mackall
many, many trivial check-code fixups
r10282 if cwd == self._root:
return ''
Matt Mackall
dirstate: hide internal vars...
r4614 # 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:
Matt Mackall
dirstate: don't overnormalize for ui.slash...
r19210 return util.pconvert(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):
Greg Ward
dirstate: add/improve method docstrings....
r9518 '''Return the current state of key (a filename) in the dirstate.
Martin Geisler
dirstate: improve docstring formatting...
r10145
Greg Ward
dirstate: add/improve method docstrings....
r9518 States are:
n normal
m needs merging
r marked for removal
a marked for addition
? not tracked
'''
Matt Mackall
dirstate: add __contains__ and make __getitem__ more useful...
r4906 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):
Matt Mackall
replace util.sort with sorted built-in...
r8209 for x in sorted(self._map):
Matt Mackall
dirstate: hide internal vars...
r4614 yield x
mpm@selenic.com
Break apart hg.py...
r1089
Bryan O'Sullivan
completion: add a debugpathcomplete command...
r18792 def iteritems(self):
return self._map.iteritems()
mpm@selenic.com
Break apart hg.py...
r1089 def parents(self):
Matt Mackall
dirstate: warn on invalid parents rather than aborting...
r13032 return [self._validate(p) for p in self._pl]
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
dirstate: add p1/p2 convenience methods
r13876 def p1(self):
return self._validate(self._pl[0])
def p2(self):
return self._validate(self._pl[1])
Matt Mackall
Move branch read/write to dirstate where it belongs
r4179 def branch(self):
Matt Mackall
branch: operate on branch names in local string space where possible...
r13047 return encoding.tolocal(self._branch)
Matt Mackall
Move branch read/write to dirstate where it belongs
r4179
mpm@selenic.com
Break apart hg.py...
r1089 def setparents(self, p1, p2=nullid):
Patrick Mezard
localrepo: add setparents() to adjust dirstate copies (issue3407)...
r16551 """Set dirstate parents to p1 and p2.
When moving from two parents to one, 'm' merged entries a
adjusted to normal and previous copy records discarded and
returned by the call.
See localrepo.setparents()
"""
Durham Goode
dirstate: add exception when calling setparent without begin/end (API)...
r22407 if self._parentwriters == 0:
Siddharth Agarwal
dirstate: copyedit exception for no beginparentchange call
r22459 raise ValueError("cannot set dirstate parent without "
"calling dirstate.beginparentchange")
Durham Goode
dirstate: add exception when calling setparent without begin/end (API)...
r22407
Matt Mackall
Merge with crew
r4965 self._dirty = self._dirtypl = True
Patrick Mezard
rebase: skip resolved but emptied revisions...
r16509 oldp2 = self._pl[1]
Matt Mackall
dirstate: hide internal vars...
r4614 self._pl = p1, p2
Patrick Mezard
localrepo: add setparents() to adjust dirstate copies (issue3407)...
r16551 copies = {}
Patrick Mezard
rebase: skip resolved but emptied revisions...
r16509 if oldp2 != nullid and p2 == nullid:
for f, s in self._map.iteritems():
Matt Mackall
dirstate: properly clean-up some more merge state on setparents
r22895 # Discard 'm' markers when moving away from a merge state
Patrick Mezard
rebase: skip resolved but emptied revisions...
r16509 if s[0] == 'm':
Patrick Mezard
localrepo: add setparents() to adjust dirstate copies (issue3407)...
r16551 if f in self._copymap:
copies[f] = self._copymap[f]
Patrick Mezard
rebase: skip resolved but emptied revisions...
r16509 self.normallookup(f)
Matt Mackall
dirstate: properly clean-up some more merge state on setparents
r22895 # Also fix up otherparent markers
elif s[0] == 'n' and s[2] == -2:
if f in self._copymap:
copies[f] = self._copymap[f]
self.add(f)
Patrick Mezard
localrepo: add setparents() to adjust dirstate copies (issue3407)...
r16551 return copies
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
Move branch read/write to dirstate where it belongs
r4179 def setbranch(self, branch):
Matt Mackall
branch: operate on branch names in local string space where possible...
r13047 self._branch = encoding.fromlocal(branch)
Idan Kamara
dirstate: write branch file atomically
r16472 f = self._opener('branch', 'w', atomictemp=True)
try:
f.write(self._branch + '\n')
f.close()
Idan Kamara
dirstate: refresh _branch cache entry after writing it
r18317
# make sure filecache has the correct stat info for _branch after
# replacing the underlying file
ce = self._filecache['_branch']
if ce:
ce.refresh()
Idan Kamara
dirstate: don't rename branch file if writing it failed
r18076 except: # re-raises
f.discard()
raise
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 = {}
Matt Mackall
dirstate: fold parse into read
r4607 try:
FUJIWARA Katsunori
dirstate: use open/read of vfs(opener) explicitly instead of read...
r25227 fp = self._opener.open(self._filename)
try:
st = fp.read()
finally:
fp.close()
Matt Mackall
dirstate: fold parse into read
r4607 except IOError, err:
Matt Mackall
many, many trivial check-code fixups
r10282 if err.errno != errno.ENOENT:
raise
Matt Mackall
dirstate: fold parse into read
r4607 return
if not st:
return
Siddharth Agarwal
dirstate: use a presized dict for the dirstate...
r25585 if util.safehasattr(parsers, 'dict_new_presized'):
# Make an estimate of the number of files in the dirstate based on
# its size. From a linear regression on a set of real-world repos,
# all over 10,000 files, the size of a dirstate entry is 85
# bytes. The cost of resizing is significantly higher than the cost
# of filling in a larger presized dict, so subtract 20% from the
# size.
#
# This heuristic is imperfect in many ways, so in a future dirstate
# format update it makes sense to just record the number of entries
# on write.
self._map = parsers.dict_new_presized(len(st) / 71)
Siddharth Agarwal
dirstate: disable gc while parsing the dirstate...
r18649 # Python's garbage collector triggers a GC each time a certain number
# of container objects (the number being defined by
# gc.get_threshold()) are allocated. parse_dirstate creates a tuple
# for each file in the dirstate. The C version then immediately marks
# them as not to be tracked by the collector. However, this has no
# effect on when GCs are triggered, only on what objects the GC looks
# into. This means that O(number of files) GCs are unavoidable.
# Depending on when in the process's lifetime the dirstate is parsed,
# this can get very expensive. As a workaround, disable GC while
# parsing the dirstate.
Pierre-Yves David
dirstate: use the 'nogc' decorator...
r23496 #
# (we cannot decorate the function directly since it is in a C module)
parse_dirstate = util.nogc(parsers.parse_dirstate)
p = parse_dirstate(self._map, self._copymap, st)
Alexis S. L. Carvalho
add dirstate._dirtypl variable...
r4952 if not self._dirtypl:
Matt Mackall
dirstate: C parsing extension
r7093 self._pl = p
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
localrepo and dirstate: rename reload to invalidate...
r4613 def invalidate(self):
Siddharth Agarwal
dirstate: split the foldmap into separate ones for files and directories...
r24540 for a in ("_map", "_copymap", "_filefoldmap", "_dirfoldmap", "_branch",
"_pl", "_dirs", "_ignore"):
Alexis S. L. Carvalho
dirstate.invalidate: avoid rebuilding _map...
r4953 if a in self.__dict__:
delattr(self, a)
Martin Geisler
Use explicit integer division...
r15791 self._lastnormaltime = 0
Matt Mackall
dirstate: use True and false for _dirty
r4903 self._dirty = False
Durham Goode
dirstate: add begin/endparentchange to dirstate...
r22404 self._parentwriters = 0
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):
Martin Geisler
dirstate: improve docstring formatting...
r10145 """Mark dest as a copy of source. Unmark dest if source is None."""
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
Patrick Mezard
mq: drop copy records when refreshing regular patches (issue1441)...
r7566 if source is not None:
self._copymap[dest] = source
elif dest in self._copymap:
del self._copymap[dest]
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: simplify/optimize path checking...
r6767 def _droppath(self, f):
if self[f] not in "?r" and "_dirs" in self.__dict__:
Bryan O'Sullivan
scmutil: use new dirs class in dirstate and context...
r18899 self._dirs.delpath(f)
Vadim Gelfer
fix issue 322....
r2953
Adrian Buehlmann
dirstate: eliminate redundant check parameter on _addpath()...
r17196 def _addpath(self, f, state, mode, size, mtime):
Maxim Dounin
Fix file-changed-to-dir and dir-to-file commits (issue660)....
r5487 oldstate = self[f]
Adrian Buehlmann
dirstate: eliminate redundant check parameter on _addpath()...
r17196 if state == 'a' or oldstate == 'r':
Adrian Buehlmann
move checkfilename from util to scmutil...
r13974 scmutil.checkfilename(f)
Matt Mackall
dirstate: simplify/optimize path checking...
r6767 if f in self._dirs:
raise util.Abort(_('directory %r already in dirstate') % f)
# shadows
Drew Gottlieb
util: move dirs() and finddirs() from scmutil to util...
r24635 for d in util.finddirs(f):
Matt Mackall
dirstate: simplify/optimize path checking...
r6767 if d in self._dirs:
break
if d in self._map and self[d] != 'r':
raise util.Abort(
_('file %r in dirstate clashes with %r') % (d, f))
if oldstate in "?r" and "_dirs" in self.__dict__:
Bryan O'Sullivan
scmutil: use new dirs class in dirstate and context...
r18899 self._dirs.addpath(f)
Joshua Redstone
dirstate: factor common update code into _addpath...
r17094 self._dirty = True
Siddharth Agarwal
dirstate: add dirstatetuple to create dirstate values...
r21808 self._map[f] = dirstatetuple(state, mode, size, mtime)
Maxim Dounin
Fix file-changed-to-dir and dir-to-file commits (issue660)....
r5487
Matt Mackall
dirstate: break update into separate functions
r4904 def normal(self, f):
Martin Geisler
dirstate: improve docstring formatting...
r10145 '''Mark a file normal and clean.'''
Matt Mackall
dirstate: make wjoin function private
r4905 s = os.lstat(self._join(f))
Adrian Buehlmann
dirstate: check mtime when adding to _lastnormal...
r13754 mtime = int(s.st_mtime)
Matt Mackall
dirstate: handle large dates and times with masking (issue2608)...
r17733 self._addpath(f, 'n', s.st_mode,
s.st_size & _rangemask, mtime & _rangemask)
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]
Adrian Buehlmann
dirstate: eliminate _lastnormal set...
r13763 if mtime > self._lastnormaltime:
# Remember the most recent modification timeslot for status(),
Adrian Buehlmann
dirstate: check mtime when adding to _lastnormal...
r13754 # to make sure we won't miss future size-preserving file content
# modifications that happen within the same timeslot.
Adrian Buehlmann
dirstate: eliminate _lastnormal set...
r13763 self._lastnormaltime = mtime
Greg Ward
dirstate: avoid a race with multiple commits in the same process...
r13704
Alexis S. L. Carvalho
merge: forcefully mark files that we get from the second parent as dirty...
r5210 def normallookup(self, f):
Martin Geisler
dirstate: improve docstring formatting...
r10145 '''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
Benoit Boissinot
dirstate: more explicit name, rename normaldirty() to otherparent()
r10968 # in state 'm' (-1) or coming from other parent (-2) before
# being removed, restore that state.
Alexis S. L. Carvalho
normallookup: during merges, restore the state saved by remove
r6298 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:
Benoit Boissinot
dirstate: more explicit name, rename normaldirty() to otherparent()
r10968 self.otherparent(f)
Alexis S. L. Carvalho
normallookup: during merges, restore the state saved by remove
r6298 if source:
self.copy(source, f)
return
if entry[0] == 'm' or entry[0] == 'n' and entry[2] == -2:
return
Joshua Redstone
dirstate: factor common update code into _addpath...
r17094 self._addpath(f, 'n', 0, -1, -1)
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]
Benoit Boissinot
dirstate: more explicit name, rename normaldirty() to otherparent()
r10968 def otherparent(self, f):
'''Mark as coming from the other parent, always dirty.'''
if self._pl[1] == nullid:
raise util.Abort(_("setting %r to other parent "
"only allowed in merges") % f)
Matt Mackall
dirstate: use 'm' state in otherparent to reduce ambiguity...
r22896 if f in self and self[f] == 'n':
# merge-like
self._addpath(f, 'm', 0, -2, -1)
else:
# add-like
self._addpath(f, 'n', 0, -2, -1)
Matt Mackall
dirstate: break update into separate functions
r4904 if f in self._copymap:
del self._copymap[f]
def add(self, f):
Martin Geisler
dirstate: improve docstring formatting...
r10145 '''Mark a file added.'''
Adrian Buehlmann
dirstate: eliminate redundant check parameter on _addpath()...
r17196 self._addpath(f, 'a', 0, -1, -1)
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):
Martin Geisler
dirstate: improve docstring formatting...
r10145 '''Mark a file removed.'''
Matt Mackall
dirstate: break update into separate functions
r4904 self._dirty = True
Matt Mackall
dirstate: simplify/optimize path checking...
r6767 self._droppath(f)
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:
Benoit Boissinot
dirstate: more explicit name, rename normaldirty() to otherparent()
r10968 # backup the previous state
Alexis S. L. Carvalho
dirstate.remove: during merges, remember the previous file state...
r6297 entry = self._map[f]
Benoit Boissinot
dirstate: more explicit name, rename normaldirty() to otherparent()
r10968 if entry[0] == 'm': # merge
Alexis S. L. Carvalho
dirstate.remove: during merges, remember the previous file state...
r6297 size = -1
Benoit Boissinot
dirstate: more explicit name, rename normaldirty() to otherparent()
r10968 elif entry[0] == 'n' and entry[2] == -2: # other parent
Alexis S. L. Carvalho
dirstate.remove: during merges, remember the previous file state...
r6297 size = -2
Siddharth Agarwal
dirstate: add dirstatetuple to create dirstate values...
r21808 self._map[f] = dirstatetuple('r', 0, size, 0)
Alexis S. L. Carvalho
dirstate.remove: during merges, remember the previous file state...
r6297 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):
Martin Geisler
dirstate: improve docstring formatting...
r10145 '''Mark a file merged.'''
Patrick Mezard
rebase: skip resolved but emptied revisions...
r16509 if self._pl[1] == nullid:
return self.normallookup(f)
Matt Mackall
dirstate: merge falls through to otherparent...
r22897 return self.otherparent(f)
Matt Mackall
dirstate: break update into separate functions
r4904
Matt Mackall
dirstate: rename forget to drop...
r14434 def drop(self, f):
'''Drop a file from the dirstate'''
Matt Mackall
dirstate: don't fail when dropping a not-tracked file (issue3080)...
r15399 if f in self._map:
self._dirty = True
self._droppath(f)
del self._map[f]
mpm@selenic.com
Break apart hg.py...
r1089
Siddharth Agarwal
dirstate: factor out code to discover normalized path...
r24538 def _discoverpath(self, path, normed, ignoremissing, exists, storemap):
if exists is None:
exists = os.path.lexists(os.path.join(self._root, path))
if not exists:
# Maybe a path component exists
if not ignoremissing and '/' in path:
d, f = path.rsplit('/', 1)
d = self._normalize(d, False, ignoremissing, None)
folded = d + "/" + f
else:
# No path components, preserve original case
folded = path
else:
# recursively normalize leading directory components
# against dirstate
if '/' in normed:
d, f = normed.rsplit('/', 1)
d = self._normalize(d, False, ignoremissing, True)
r = self._root + "/" + d
folded = d + "/" + util.fspath(f, r)
else:
folded = util.fspath(normed, self._root)
storemap[normed] = folded
return folded
Siddharth Agarwal
dirstate: introduce function to normalize just filenames...
r24539 def _normalizefile(self, path, isknown, ignoremissing=False, exists=None):
Matt Mackall
dirstate: fix case-folding identity for traditional Unix...
r15488 normed = util.normcase(path)
Siddharth Agarwal
dirstate: split the foldmap into separate ones for files and directories...
r24540 folded = self._filefoldmap.get(normed, None)
Matt Mackall
dirstate: introduce a public case normalizing method
r13717 if folded is None:
Patrick Mezard
dirstate: preserve path components case on renames (issue3402)...
r16542 if isknown:
Matt Mackall
dirstate: introduce a public case normalizing method
r13717 folded = path
Petr Kodl
issue 1286: dirstat regression on case folding systems...
r7068 else:
Siddharth Agarwal
dirstate: introduce function to normalize just filenames...
r24539 folded = self._discoverpath(path, normed, ignoremissing, exists,
Siddharth Agarwal
dirstate: split the foldmap into separate ones for files and directories...
r24540 self._filefoldmap)
Siddharth Agarwal
dirstate: introduce function to normalize just filenames...
r24539 return folded
Matt Mackall
dirstate: normalize case of directory components...
r16302
Patrick Mezard
dirstate: preserve path components case on renames (issue3402)...
r16542 def _normalize(self, path, isknown, ignoremissing=False, exists=None):
Matt Mackall
dirstate: fix case-folding identity for traditional Unix...
r15488 normed = util.normcase(path)
Siddharth Agarwal
dirstate._normalize: don't construct dirfoldmap if not necessary...
r24561 folded = self._filefoldmap.get(normed, None)
if folded is None:
folded = self._dirfoldmap.get(normed, None)
Matt Mackall
dirstate: introduce a public case normalizing method
r13717 if folded is None:
Patrick Mezard
dirstate: preserve path components case on renames (issue3402)...
r16542 if isknown:
Matt Mackall
dirstate: introduce a public case normalizing method
r13717 folded = path
Petr Kodl
issue 1286: dirstat regression on case folding systems...
r7068 else:
Siddharth Agarwal
dirstate: split the foldmap into separate ones for files and directories...
r24540 # store discovered result in dirfoldmap so that future
# normalizefile calls don't start matching directories
Siddharth Agarwal
dirstate: factor out code to discover normalized path...
r24538 folded = self._discoverpath(path, normed, ignoremissing, exists,
Siddharth Agarwal
dirstate: split the foldmap into separate ones for files and directories...
r24540 self._dirfoldmap)
Matt Mackall
dirstate: introduce a public case normalizing method
r13717 return folded
Patrick Mezard
dirstate: preserve path components case on renames (issue3402)...
r16542 def normalize(self, path, isknown=False, ignoremissing=False):
Matt Mackall
dirstate: introduce a public case normalizing method
r13717 '''
normalize the case of a pathname when on a casefolding filesystem
isknown specifies whether the filename came from walking the
Patrick Mezard
dirstate: preserve path components case on renames (issue3402)...
r16542 disk, to avoid extra filesystem access.
If ignoremissing is True, missing path are returned
unchanged. Otherwise, we try harder to normalize possibly
existing path components.
Matt Mackall
dirstate: introduce a public case normalizing method
r13717
The normalized case is determined based on the following precedence:
- version of name already stored in the dirstate
- version of name stored on disk
- version provided via command arguments
'''
if self._checkcase:
Patrick Mezard
dirstate: preserve path components case on renames (issue3402)...
r16542 return self._normalize(path, isknown, ignoremissing)
Matt Mackall
dirstate: introduce a public case normalizing method
r13717 return path
Paul Moore
Add a normalize() method to dirstate...
r6677
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__:
Benoit Boissinot
fix coding style (reported by pylint)
r10394 delattr(self, "_dirs")
Alexis S. L. Carvalho
dirstate: fix rebuild; add a test...
r5065 self._copymap = {}
self._pl = [nullid, nullid]
Martin Geisler
Use explicit integer division...
r15791 self._lastnormaltime = 0
Alexis S. L. Carvalho
merge with crew-stable
r5123 self._dirty = True
Alexis S. L. Carvalho
dirstate: fix rebuild; add a test...
r5065
Durham Goode
strip: make --keep option not set all dirstate times to 0...
r18760 def rebuild(self, parent, allfiles, changedfiles=None):
Pierre-Yves David
dirstate: avoid invalidating every entries when list is empty...
r25448 if changedfiles is None:
changedfiles = allfiles
Durham Goode
strip: make --keep option not set all dirstate times to 0...
r18760 oldmap = self._map
Alexis S. L. Carvalho
dirstate: fix rebuild; add a test...
r5065 self.clear()
Durham Goode
strip: make --keep option not set all dirstate times to 0...
r18760 for f in allfiles:
if f not in changedfiles:
self._map[f] = oldmap[f]
Benoit Boissinot
add 'debugrebuildstate' to rebuild the dirstate from a given revision...
r1755 else:
Durham Goode
strip: make --keep option not set all dirstate times to 0...
r18760 if 'x' in allfiles.flags(f):
Siddharth Agarwal
dirstate: add dirstatetuple to create dirstate values...
r21808 self._map[f] = dirstatetuple('n', 0777, -1, 0)
Durham Goode
strip: make --keep option not set all dirstate times to 0...
r18760 else:
Siddharth Agarwal
dirstate: add dirstatetuple to create dirstate values...
r21808 self._map[f] = dirstatetuple('n', 0666, -1, 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
FUJIWARA Katsunori
dirstate: delay writing out to ensure timestamp of each entries explicitly...
r21931
# enough 'delaywrite' prevents 'pack_dirstate' from dropping
# timestamp of each entries in dirstate, because of 'now > mtime'
delaywrite = self._ui.configint('debug', 'dirstate.delaywrite', 0)
Mads Kiilerich
dirstate: ignore negative debug.dirstate.delaywrite values - they crashed it...
r23866 if delaywrite > 0:
FUJIWARA Katsunori
dirstate: delay writing out to ensure timestamp of each entries explicitly...
r21931 import time # to avoid useless import
time.sleep(delaywrite)
FUJIWARA Katsunori
dirstate: use self._filename instead of immediate string `dirstate`...
r25226 st = self._opener(self._filename, "w", atomictemp=True)
Adrian Buehlmann
dirstate: kill dirstate.granularity config option...
r9509 # use the modification time of the newly created temporary file as the
# filesystem's notion of 'now'
Bryan O'Sullivan
parsers: add a C function to pack the dirstate...
r16955 now = util.fstat(st).st_mtime
Mads Kiilerich
dirstate: inline local finish function...
r21026 st.write(parsers.pack_dirstate(self._map, self._copymap, self._pl, now))
st.close()
self._lastnormaltime = 0
self._dirty = self._dirtypl = False
mpm@selenic.com
Break apart hg.py...
r1089
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
Drew Gottlieb
util: move dirs() and finddirs() from scmutil to util...
r24635 for p in util.finddirs(f):
Matt Mackall
dirstate: simplify/optimize path checking...
r6767 if self._ignore(p):
Alexis S. L. Carvalho
dirstate: don't walk ignored directories...
r6032 return True
return False
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173 def _walkexplicit(self, match, subrepos):
'''Get stat data about the files explicitly specified by match.
Matt Mackall
simplify dirstate walking...
r3529
Siddharth Agarwal
dirstate._walkexplicit: rename work to dirsfound...
r19174 Return a triple (results, dirsfound, dirsnotfound).
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173 - results is a mapping from filename to stat result. It also contains
listings mapping subrepos and .hg to None.
Siddharth Agarwal
dirstate._walkexplicit: rename work to dirsfound...
r19174 - dirsfound is a list of files found to be directories.
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173 - dirsnotfound is a list of files that the dirstate thinks are
directories and that were not found.'''
Matt Mackall
walk: begin refactoring badmatch handling
r6578
Matt Mackall
walk: use match.bad callback for filetype messages
r8681 def badtype(mode):
Simon Heimberg
dirstate: translate forgotten string
r8310 kind = _('unknown')
Matt Mackall
many, many trivial check-code fixups
r10282 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
walk: use match.bad callback for filetype messages
r8681 return _('unsupported file type (type is %s)') % kind
Matt Mackall
dirstate.walk: fold in _supported...
r6830
Siddharth Agarwal
dirstate.walk: cache match.explicitdir and traversedir locally
r19142 matchedir = match.explicitdir
Matt Mackall
walk: we always have a badfn
r8676 badfn = match.bad
Matt Mackall
dirstate.walk: more cleanups...
r6831 dmap = self._map
Matt Mackall
dirstate: localize a bunch of methods for findfiles
r5000 lstat = os.lstat
Matt Mackall
dirstate.walk: fold in _supported...
r6830 getkind = stat.S_IFMT
Matt Mackall
dirstate.walk: minor cleanups...
r6828 dirkind = stat.S_IFDIR
Matt Mackall
dirstate.walk: fold in _supported...
r6830 regkind = stat.S_IFREG
lnkkind = stat.S_IFLNK
Matt Mackall
dirstate.walk: more cleanups...
r6831 join = self._join
Siddharth Agarwal
dirstate._walkexplicit: rename work to dirsfound...
r19174 dirsfound = []
foundadd = dirsfound.append
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173 dirsnotfound = []
Siddharth Agarwal
dirstate._walkexplicit: inline dirsnotfound.append
r19175 notfoundadd = dirsnotfound.append
Matt Mackall
dirstate.walk: fold findfiles into main walk loop
r6820
Martin von Zweigbergk
match: add isexact() method to hide internals...
r24448 if not match.isexact() and self._checkcase:
Matt Mackall
dirstate: skip optimization on case-folding FS (issue2440)
r12907 normalize = self._normalize
else:
Siddharth Agarwal
dirstate: test normalize is truthy instead of using a no-op lambda...
r18032 normalize = None
Matt Mackall
dirstate: skip optimization on case-folding FS (issue2440)
r12907
Martin Geisler
dirstate: use one pass to filter out files in subrepos
r12211 files = sorted(match.files())
subrepos.sort()
i, j = 0, 0
while i < len(files) and j < len(subrepos):
subpath = subrepos[j] + "/"
Oleg Stepanov
subrepo: do not report known files inside repositories as unknown
r13233 if files[i] < subpath:
Martin Geisler
dirstate: use one pass to filter out files in subrepos
r12211 i += 1
continue
trbs
subrepo: fix pruning of subrepo filenames in dirstate (issue2619)
r13339 while i < len(files) and files[i].startswith(subpath):
Martin Geisler
dirstate: use one pass to filter out files in subrepos
r12211 del files[i]
j += 1
Matt Mackall
dirstate.walk: more cleanups...
r6831 if not files or '.' in files:
Siddharth Agarwal
dirstate._walkexplicit: indicate root as '.', not ''...
r24521 files = ['.']
Augie Fackler
dirstate: don't check state of subrepo directories
r10176 results = dict.fromkeys(subrepos)
results['.hg'] = None
Matt Mackall
dirstate: localize a bunch of methods for findfiles
r5000
Martin von Zweigbergk
dirstate: speed up repeated missing directory checks...
r23375 alldirs = None
Martin Geisler
dirstate: use one pass to filter out files in subrepos
r12211 for ff in files:
Siddharth Agarwal
dirstate._walkexplicit: don't bother normalizing '.'...
r24523 # constructing the foldmap is expensive, so don't do it for the
# common case where files is ['.']
if normalize and ff != '.':
Siddharth Agarwal
dirstate._walkexplicit: drop normpath calls...
r24522 nf = normalize(ff, False, True)
Siddharth Agarwal
dirstate: test normalize is truthy instead of using a no-op lambda...
r18032 else:
Siddharth Agarwal
dirstate._walkexplicit: drop normpath calls...
r24522 nf = ff
Matt Mackall
dirstate.walk: build a dict rather than yield...
r6829 if nf in results:
Matt Mackall
dirstate.walk: fold findfiles into main walk loop
r6820 continue
try:
Matt Mackall
dirstate.walk: more cleanups...
r6831 st = lstat(join(nf))
Matt Mackall
dirstate.walk: fold in _supported...
r6830 kind = getkind(st.st_mode)
if kind == dirkind:
Simon Heimberg
dirstate: set more states in step 1 of walk
r8588 if nf in dmap:
Mads Kiilerich
dirstate: improve documentation and readability of match and ignore in the walker
r21115 # file replaced by dir on disk but still in dirstate
Simon Heimberg
dirstate: set more states in step 1 of walk
r8588 results[nf] = None
Siddharth Agarwal
match: make explicitdir and traversedir None by default...
r19143 if matchedir:
matchedir(nf)
Matt Harbison
dirstate: don't require exact case when adding dirs on icasefs (issue4578)...
r24537 foundadd((nf, ff))
Matt Mackall
backout most of 4f8067c94729
r12401 elif kind == regkind or kind == lnkkind:
Matt Mackall
dirstate.walk: fold in _supported...
r6830 results[nf] = st
Matt Mackall
dirstate.walk: minor cleanups...
r6828 else:
Matt Mackall
walk: use match.bad callback for filetype messages
r8681 badfn(ff, badtype(kind))
Matt Mackall
dirstate.walk: fold in _supported...
r6830 if nf in dmap:
Matt Mackall
dirstate.walk: build a dict rather than yield...
r6829 results[nf] = None
Mads Kiilerich
dirstate: improve documentation and readability of match and ignore in the walker
r21115 except OSError, inst: # nf not found on disk - it is dirstate only
if nf in dmap: # does it exactly match a missing file?
Matt Mackall
walk: simplify check for missing file
r8675 results[nf] = None
Mads Kiilerich
dirstate: improve documentation and readability of match and ignore in the walker
r21115 else: # does it match a missing directory?
Martin von Zweigbergk
dirstate: speed up repeated missing directory checks...
r23375 if alldirs is None:
Drew Gottlieb
util: move dirs() and finddirs() from scmutil to util...
r24635 alldirs = util.dirs(dmap)
Martin von Zweigbergk
dirstate: speed up repeated missing directory checks...
r23375 if nf in alldirs:
if matchedir:
matchedir(nf)
notfoundadd(nf)
Matt Mackall
walk: simplify logic for badfn clause...
r8677 else:
Matt Mackall
match: ignore return of match.bad...
r8680 badfn(ff, inst.strerror)
Matt Mackall
dirstate.walk: fold findfiles into main walk loop
r6820
Siddharth Agarwal
dirstate._walkexplicit: rename work to dirsfound...
r19174 return results, dirsfound, dirsnotfound
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173
Siddharth Agarwal
dirstate.walk: add a flag to let extensions avoid full walks...
r19190 def walk(self, match, subrepos, unknown, ignored, full=True):
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173 '''
Walk recursively through the directory tree, finding all files
matched by match.
Siddharth Agarwal
dirstate.walk: add a flag to let extensions avoid full walks...
r19190 If full is False, maybe skip some known-clean files.
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173 Return a dict mapping filename to stat-like object (either
mercurial.osutil.stat instance or return value of os.stat()).
Siddharth Agarwal
dirstate.walk: add a flag to let extensions avoid full walks...
r19190
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173 '''
Siddharth Agarwal
dirstate.walk: add a flag to let extensions avoid full walks...
r19190 # full is a flag that extensions that hook into walk can use -- this
# implementation doesn't use it at all. This satisfies the contract
# because we only guarantee a "maybe".
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173
if ignored:
ignore = util.never
dirignore = util.never
Mads Kiilerich
dirstate: improve documentation and readability of match and ignore in the walker
r21115 elif unknown:
ignore = self._ignore
dirignore = self._dirignore
else:
# if not unknown and not ignored, drop dir recursion and step 2
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173 ignore = util.always
dirignore = util.always
matchfn = match.matchfn
matchalways = match.always()
matchtdir = match.traversedir
dmap = self._map
listdir = osutil.listdir
lstat = os.lstat
dirkind = stat.S_IFDIR
regkind = stat.S_IFREG
lnkkind = stat.S_IFLNK
join = self._join
exact = skipstep3 = False
Martin von Zweigbergk
match: add isexact() method to hide internals...
r24448 if match.isexact(): # match.exact
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173 exact = True
dirignore = util.always # skip step 2
Martin von Zweigbergk
dirstate: avoid match.files() in walk()
r25234 elif match.prefix(): # match.match, no patterns
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173 skipstep3 = True
if not exact and self._checkcase:
normalize = self._normalize
Siddharth Agarwal
dirstate.walk: use the file foldmap to normalize...
r24541 normalizefile = self._normalizefile
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173 skipstep3 = False
else:
Siddharth Agarwal
dirstate.walk: don't keep track of normalized files in parallel...
r24560 normalize = self._normalize
Siddharth Agarwal
dirstate.walk: use the file foldmap to normalize...
r24541 normalizefile = None
Siddharth Agarwal
dirstate.walk: refactor explicit walk into separate function...
r19173
# step 1: find all explicit files
results, work, dirsnotfound = self._walkexplicit(match, subrepos)
Siddharth Agarwal
dirstate.walk: pull skipstep3 out of the explicit walk code...
r19172 skipstep3 = skipstep3 and not (work or dirsnotfound)
Matt Harbison
dirstate: don't require exact case when adding dirs on icasefs (issue4578)...
r24537 work = [d for d in work if not dirignore(d[0])]
Siddharth Agarwal
dirstate.walk: move dirignore filter out of explicit walk code...
r19171
Matt Mackall
dirstate.walk: pull directory scanning into top-level loop
r6826 # step 2: visit subdirectories
Siddharth Agarwal
dirstate.walk: don't keep track of normalized files in parallel...
r24560 def traverse(work, alreadynormed):
Siddharth Agarwal
dirstate.walk: factor out directory traversal...
r24559 wadd = work.append
while work:
Siddharth Agarwal
dirstate.walk: don't keep track of normalized files in parallel...
r24560 nd = work.pop()
Siddharth Agarwal
dirstate.walk: factor out directory traversal...
r24559 skip = None
if nd == '.':
nd = ''
Siddharth Agarwal
dirstate: test normalize is truthy instead of using a no-op lambda...
r18032 else:
Siddharth Agarwal
dirstate.walk: factor out directory traversal...
r24559 skip = '.hg'
try:
entries = listdir(join(nd), stat=True, skip=skip)
except OSError, inst:
if inst.errno in (errno.EACCES, errno.ENOENT):
match.bad(self.pathto(nd), inst.strerror)
continue
raise
for f, kind, st in entries:
if normalizefile:
# even though f might be a directory, we're only
# interested in comparing it to files currently in the
# dmap -- therefore normalizefile is enough
nf = normalizefile(nd and (nd + "/" + f) or f, True,
True)
else:
nf = nd and (nd + "/" + f) or f
if nf not in results:
if kind == dirkind:
if not ignore(nf):
if matchtdir:
matchtdir(nf)
Siddharth Agarwal
dirstate.walk: don't keep track of normalized files in parallel...
r24560 wadd(nf)
Siddharth Agarwal
dirstate.walk: factor out directory traversal...
r24559 if nf in dmap and (matchalways or matchfn(nf)):
results[nf] = None
elif kind == regkind or kind == lnkkind:
if nf in dmap:
if matchalways or matchfn(nf):
results[nf] = st
Siddharth Agarwal
dirstate.walk: don't keep track of normalized files in parallel...
r24560 elif ((matchalways or matchfn(nf))
and not ignore(nf)):
# unknown file -- normalize if necessary
if not alreadynormed:
nf = normalize(nf, False, True)
Siddharth Agarwal
dirstate.walk: factor out directory traversal...
r24559 results[nf] = st
elif nf in dmap and (matchalways or matchfn(nf)):
Matt Mackall
dirstate.walk: build a dict rather than yield...
r6829 results[nf] = None
Siddharth Agarwal
dirstate.walk: factor out directory traversal...
r24559
Siddharth Agarwal
dirstate.walk: don't keep track of normalized files in parallel...
r24560 for nd, d in work:
# alreadynormed means that processwork doesn't have to do any
# expensive directory normalization
alreadynormed = not normalize or nd == d
traverse([d], alreadynormed)
mpm@selenic.com
Break apart hg.py...
r1089
Siddharth Agarwal
dirstate.walk: remove subrepo and .hg from results before step 3...
r18812 for s in subrepos:
del results[s]
del results['.hg']
Mads Kiilerich
dirstate: improve documentation and readability of match and ignore in the walker
r21115 # step 3: visit remaining files from dmap
Matt Mackall
match: fold plan cases down to two special cases...
r8684 if not skipstep3 and not exact:
Mads Kiilerich
dirstate: improve documentation and readability of match and ignore in the walker
r21115 # If a dmap file is not in results yet, it was either
# a) not matching matchfn b) ignored, c) missing, or d) under a
# symlink directory.
Siddharth Agarwal
dirstate.walk: fast path none-seen + match-always case for step 3...
r18815 if not results and matchalways:
visit = dmap.keys()
else:
visit = [f for f in dmap if f not in results and matchfn(f)]
visit.sort()
Durham Goode
dirstate: walk returns None for files that have a symlink in their path...
r18625 if unknown:
Mads Kiilerich
dirstate: improve documentation and readability of match and ignore in the walker
r21115 # unknown == True means we walked all dirs under the roots
# that wasn't ignored, and everything that matched was stat'ed
# and is already in results.
# The rest must thus be ignored or under a symlink.
Augie Fackler
pathutil: tease out a new library to break an import cycle from canonpath use
r20033 audit_path = pathutil.pathauditor(self._root)
Durham Goode
dirstate: walk returns None for files that have a symlink in their path...
r18625
for nf in iter(visit):
Martin von Zweigbergk
dirstate.walk: don't report same file stat multiple times...
r24621 # If a stat for the same file was already added with a
# different case, don't add one for this, since that would
# make it appear as if the file exists under both names
# on disk.
Matt Mackall
merge with stable
r24632 if (normalizefile and
normalizefile(nf, True, True) in results):
Martin von Zweigbergk
dirstate.walk: don't report same file stat multiple times...
r24621 results[nf] = None
Durham Goode
dirstate: walk returns None for files that have a symlink in their path...
r18625 # Report ignored items in the dmap as long as they are not
# under a symlink directory.
Martin von Zweigbergk
dirstate.walk: don't report same file stat multiple times...
r24621 elif audit_path.check(nf):
Durham Goode
dirstate: fix generator/list error when using python 2.7...
r18663 try:
results[nf] = lstat(join(nf))
Mads Kiilerich
dirstate: improve documentation and readability of match and ignore in the walker
r21115 # file was just ignored, no links, and exists
Durham Goode
dirstate: fix generator/list error when using python 2.7...
r18663 except OSError:
# file doesn't exist
results[nf] = None
Durham Goode
dirstate: walk returns None for files that have a symlink in their path...
r18625 else:
# It's either missing or under a symlink directory
Mads Kiilerich
dirstate: improve documentation and readability of match and ignore in the walker
r21115 # which we in this case report as missing
Durham Goode
dirstate: walk returns None for files that have a symlink in their path...
r18625 results[nf] = None
else:
# We may not have walked the full directory tree above,
Mads Kiilerich
dirstate: improve documentation and readability of match and ignore in the walker
r21115 # so stat and check everything we missed.
Durham Goode
dirstate: walk returns None for files that have a symlink in their path...
r18625 nf = iter(visit).next
for st in util.statfiles([join(i) for i in visit]):
results[nf()] = st
Matt Mackall
dirstate.walk: build a dict rather than yield...
r6829 return results
mpm@selenic.com
Break apart hg.py...
r1089
Augie Fackler
dirstate: don't check state of subrepo directories
r10176 def status(self, match, subrepos, ignored, clean, unknown):
Greg Ward
dirstate: add/improve method docstrings....
r9518 '''Determine the status of the working copy relative to the
Martin von Zweigbergk
status: update and move documentation of status types to status class...
r22915 dirstate and return a pair of (unsure, status), where status is of type
scmutil.status and:
Greg Ward
dirstate: add/improve method docstrings....
r9518
unsure:
files that might have been modified since the dirstate was
written, but need to be read to be sure (size is the same
but mtime differs)
Martin von Zweigbergk
status: update and move documentation of status types to status class...
r22915 status.modified:
Greg Ward
dirstate: add/improve method docstrings....
r9518 files that have definitely been modified since the dirstate
was written (different size or mode)
Martin von Zweigbergk
status: update and move documentation of status types to status class...
r22915 status.clean:
Greg Ward
dirstate: add/improve method docstrings....
r9518 files that have definitely not been modified since the
dirstate was written
'''
Matt Mackall
repo.status: eliminate list_
r6753 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 dmap = self._map
Greg Ward
dirstate: add/improve method docstrings....
r9518 ladd = lookup.append # aka "unsure"
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 madd = modified.append
aadd = added.append
uadd = unknown.append
iadd = ignored.append
radd = removed.append
dadd = deleted.append
cadd = clean.append
Siddharth Agarwal
dirstate: inline more properties and methods in status...
r18034 mexact = match.exact
dirignore = self._dirignore
checkexec = self._checkexec
copymap = self._copymap
lastnormaltime = self._lastnormaltime
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003
Siddharth Agarwal
dirstate.status: avoid full walks when possible
r19191 # We need to do full walks when either
# - we're listing all clean files, or
# - match.traversedir does something, because match.traversedir should
# be called for every dir in the working dir
full = listclean or match.traversedir is not None
for fn, st in self.walk(match, subrepos, listunknown, listignored,
full=full).iteritems():
Matt Mackall
dirstate: minor status cleanups
r6591 if fn not in dmap:
Siddharth Agarwal
dirstate: inline more properties and methods in status...
r18034 if (listignored or mexact(fn)) and dirignore(fn):
Matt Mackall
repo.status: eliminate list_
r6753 if listignored:
Alexis S. L. Carvalho
dirstate.status: avoid putting ignored files in the unknown list...
r6033 iadd(fn)
Siddharth Agarwal
dirstate.status: return explicit unknown files even when not asked...
r19910 else:
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
Siddharth Agarwal
dirstate.status: assign members one by one instead of unpacking the tuple...
r21810 # This is equivalent to 'state, mode, size, time = dmap[fn]' but not
# written like that for performance reasons. dmap[fn] is not a
# Python tuple in compiled builds. The CPython UNPACK_SEQUENCE
# opcode has fast paths when the value to be unpacked is a tuple or
# a list, but falls back to creating a full-fledged iterator in
# general. That is much slower than simply accessing and storing the
# tuple members one by one.
t = dmap[fn]
state = t[0]
mode = t[1]
size = t[2]
time = t[3]
Matt Mackall
dirstate: minor status cleanups
r6591
Matt Mackall
dirstate.walk: eliminate src from yield...
r6818 if not st and state in "nma":
dadd(fn)
elif state == 'n':
Adrian Buehlmann
dirstate: eliminate _lastnormal set...
r13763 mtime = int(st.st_mtime)
Alexis S. L. Carvalho
dirstate: ignore mode changes if the fs does not supports the exec bit...
r6257 if (size >= 0 and
Matt Mackall
dirstate: handle large dates and times with masking (issue2608)...
r17733 ((size != st.st_size and size != st.st_size & _rangemask)
Siddharth Agarwal
dirstate: inline more properties and methods in status...
r18034 or ((mode ^ st.st_mode) & 0100 and checkexec))
Benoit Boissinot
dirstate: more explicit name, rename normaldirty() to otherparent()
r10968 or size == -2 # other parent
Siddharth Agarwal
dirstate: inline more properties and methods in status...
r18034 or fn in copymap):
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 madd(fn)
Siddharth Agarwal
dirstate.status: don't ignore symlink placeholders in the normal set...
r19651 elif time != mtime and time != mtime & _rangemask:
Matt Mackall
dirstate: localize a bunch of methods in status fastpath
r5003 ladd(fn)
Siddharth Agarwal
dirstate: inline more properties and methods in status...
r18034 elif mtime == lastnormaltime:
Mads Kiilerich
dirstate: clarify comment about leaving normal files undef if changed 'now'...
r24181 # fn may have just been marked as normal and it may have
# changed in the same second without changing its size.
# This can happen if we quickly do multiple commits.
Adrian Buehlmann
dirstate: eliminate _lastnormal set...
r13763 # Force lookup, so we don't miss such a racy file change.
Greg Ward
dirstate: avoid a race with multiple commits in the same process...
r13704 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
Martin von Zweigbergk
status: create class for status lists...
r22913 return (lookup, scmutil.status(modified, added, removed, deleted,
unknown, ignored, clean))
Siddharth Agarwal
dirstate: add a method to efficiently filter by match...
r21984
def matches(self, match):
'''
return files in the dirstate (in whatever state) filtered by match
'''
dmap = self._map
if match.always():
return dmap.keys()
files = match.files()
Martin von Zweigbergk
match: add isexact() method to hide internals...
r24448 if match.isexact():
Siddharth Agarwal
dirstate: add a method to efficiently filter by match...
r21984 # fast path -- filter the other way around, since typically files is
# much smaller than dmap
return [f for f in files if f in dmap]
Martin von Zweigbergk
dirstate: use match.prefix() instead of 'not match.anypats()'...
r25275 if match.prefix() and all(fn in dmap for fn in files):
Siddharth Agarwal
dirstate: add a method to efficiently filter by match...
r21984 # fast path -- all the values are known to be files, so just return
# that
return list(files)
return [f for f in dmap if match(f)]