mercurial/manifest.py
changeset 26402 05871262acd5
parent 26401 e93e12e2ff9a
child 26871 1cbf144fd8a1
equal deleted inserted replaced
26401:e93e12e2ff9a 26402:05871262acd5
   440         dir, subpath = f.split('/', 1)
   440         dir, subpath = f.split('/', 1)
   441         return dir + '/', subpath
   441         return dir + '/', subpath
   442     else:
   442     else:
   443         return '', f
   443         return '', f
   444 
   444 
   445 _noop = lambda: None
   445 _noop = lambda s: None
   446 
   446 
   447 class treemanifest(object):
   447 class treemanifest(object):
   448     def __init__(self, dir='', text=''):
   448     def __init__(self, dir='', text=''):
   449         self._dir = dir
   449         self._dir = dir
   450         self._node = revlog.nullid
   450         self._node = revlog.nullid
   451         self._load = _noop
   451         self._loadfunc = _noop
       
   452         self._copyfunc = _noop
   452         self._dirty = False
   453         self._dirty = False
   453         self._dirs = {}
   454         self._dirs = {}
   454         # Using _lazymanifest here is a little slower than plain old dicts
   455         # Using _lazymanifest here is a little slower than plain old dicts
   455         self._files = {}
   456         self._files = {}
   456         self._flags = {}
   457         self._flags = {}
   477                 all(m._isempty() for m in self._dirs.values())))
   478                 all(m._isempty() for m in self._dirs.values())))
   478 
   479 
   479     def __repr__(self):
   480     def __repr__(self):
   480         return ('<treemanifest dir=%s, node=%s, loaded=%s, dirty=%s at 0x%x>' %
   481         return ('<treemanifest dir=%s, node=%s, loaded=%s, dirty=%s at 0x%x>' %
   481                 (self._dir, revlog.hex(self._node),
   482                 (self._dir, revlog.hex(self._node),
   482                  bool(self._load is _noop),
   483                  bool(self._loadfunc is _noop),
   483                  self._dirty, id(self)))
   484                  self._dirty, id(self)))
   484 
   485 
   485     def dir(self):
   486     def dir(self):
   486         '''The directory that this tree manifest represents, including a
   487         '''The directory that this tree manifest represents, including a
   487         trailing '/'. Empty string for the repo root directory.'''
   488         trailing '/'. Empty string for the repo root directory.'''
   596             self._dirs[dir].__setitem__(subpath, n)
   597             self._dirs[dir].__setitem__(subpath, n)
   597         else:
   598         else:
   598             self._files[f] = n[:21] # to match manifestdict's behavior
   599             self._files[f] = n[:21] # to match manifestdict's behavior
   599         self._dirty = True
   600         self._dirty = True
   600 
   601 
       
   602     def _load(self):
       
   603         if self._loadfunc is not _noop:
       
   604             lf, self._loadfunc = self._loadfunc, _noop
       
   605             lf(self)
       
   606         elif self._copyfunc is not _noop:
       
   607             cf, self._copyfunc = self._copyfunc, _noop
       
   608             cf(self)
       
   609 
   601     def setflag(self, f, flags):
   610     def setflag(self, f, flags):
   602         """Set the flags (symlink, executable) for path f."""
   611         """Set the flags (symlink, executable) for path f."""
   603         assert 'd' not in flags
   612         assert 'd' not in flags
   604         self._load()
   613         self._load()
   605         dir, subpath = _splittopdir(f)
   614         dir, subpath = _splittopdir(f)
   613 
   622 
   614     def copy(self):
   623     def copy(self):
   615         copy = treemanifest(self._dir)
   624         copy = treemanifest(self._dir)
   616         copy._node = self._node
   625         copy._node = self._node
   617         copy._dirty = self._dirty
   626         copy._dirty = self._dirty
   618         def _load_for_copy():
   627         if self._copyfunc is _noop:
   619             self._load()
   628             def _copyfunc(s):
   620             for d in self._dirs:
   629                 self._load()
   621                 copy._dirs[d] = self._dirs[d].copy()
   630                 for d in self._dirs:
   622             copy._files = dict.copy(self._files)
   631                     s._dirs[d] = self._dirs[d].copy()
   623             copy._flags = dict.copy(self._flags)
   632                 s._files = dict.copy(self._files)
   624             copy._load = _noop
   633                 s._flags = dict.copy(self._flags)
   625         copy._load = _load_for_copy
   634             if self._loadfunc is _noop:
   626         if self._load == _noop:
   635                 _copyfunc(copy)
   627             # Chaining _load if it's _noop is functionally correct, but the
   636             else:
   628             # chain may end up excessively long (stack overflow), and
   637                 copy._copyfunc = _copyfunc
   629             # will prevent garbage collection of 'self'.
   638         else:
   630             copy._load()
   639             copy._copyfunc = self._copyfunc
   631         return copy
   640         return copy
   632 
   641 
   633     def filesnotin(self, m2):
   642     def filesnotin(self, m2):
   634         '''Set of files in this manifest that are not in the other'''
   643         '''Set of files in this manifest that are not in the other'''
   635         files = set()
   644         files = set()
   832         dirs = [(d[:-1], self._dirs[d]._node, 'd') for d in self._dirs]
   841         dirs = [(d[:-1], self._dirs[d]._node, 'd') for d in self._dirs]
   833         files = [(f, self._files[f], flags(f)) for f in self._files]
   842         files = [(f, self._files[f], flags(f)) for f in self._files]
   834         return _text(sorted(dirs + files), usemanifestv2)
   843         return _text(sorted(dirs + files), usemanifestv2)
   835 
   844 
   836     def read(self, gettext, readsubtree):
   845     def read(self, gettext, readsubtree):
   837         def _load_for_read():
   846         def _load_for_read(s):
   838             # Mark as loaded already here, so __setitem__ and setflag() don't
   847             s.parse(gettext(), readsubtree)
   839             # cause infinite loops when they try to load.
   848             s._dirty = False
   840             self._load = _noop
   849         self._loadfunc = _load_for_read
   841             self.parse(gettext(), readsubtree)
       
   842             self._dirty = False
       
   843         self._load = _load_for_read
       
   844 
   850 
   845     def writesubtrees(self, m1, m2, writesubtree):
   851     def writesubtrees(self, m1, m2, writesubtree):
   846         self._load() # for consistency; should never have any effect here
   852         self._load() # for consistency; should never have any effect here
   847         emptytree = treemanifest()
   853         emptytree = treemanifest()
   848         for d, subm in self._dirs.iteritems():
   854         for d, subm in self._dirs.iteritems():