mercurial/dirstate.py
changeset 48793 6e559391f96e
parent 48790 5ba24e886cec
child 48875 6000f5b25c9b
equal deleted inserted replaced
48792:8bbb1abb9d19 48793:6e559391f96e
    99         root,
    99         root,
   100         validate,
   100         validate,
   101         sparsematchfn,
   101         sparsematchfn,
   102         nodeconstants,
   102         nodeconstants,
   103         use_dirstate_v2,
   103         use_dirstate_v2,
   104         use_tracked_key=False,
   104         use_tracked_hint=False,
   105     ):
   105     ):
   106         """Create a new dirstate object.
   106         """Create a new dirstate object.
   107 
   107 
   108         opener is an open()-like callable that can be used to open the
   108         opener is an open()-like callable that can be used to open the
   109         dirstate file; root is the root of the directory tracked by
   109         dirstate file; root is the root of the directory tracked by
   110         the dirstate.
   110         the dirstate.
   111         """
   111         """
   112         self._use_dirstate_v2 = use_dirstate_v2
   112         self._use_dirstate_v2 = use_dirstate_v2
   113         self._use_tracked_key = use_tracked_key
   113         self._use_tracked_hint = use_tracked_hint
   114         self._nodeconstants = nodeconstants
   114         self._nodeconstants = nodeconstants
   115         self._opener = opener
   115         self._opener = opener
   116         self._validate = validate
   116         self._validate = validate
   117         self._root = root
   117         self._root = root
   118         self._sparsematchfn = sparsematchfn
   118         self._sparsematchfn = sparsematchfn
   125         self._dirty_tracked_set = False
   125         self._dirty_tracked_set = False
   126         self._ui = ui
   126         self._ui = ui
   127         self._filecache = {}
   127         self._filecache = {}
   128         self._parentwriters = 0
   128         self._parentwriters = 0
   129         self._filename = b'dirstate'
   129         self._filename = b'dirstate'
   130         self._filename_tk = b'dirstate-tracked-key'
   130         self._filename_th = b'dirstate-tracked-hint'
   131         self._pendingfilename = b'%s.pending' % self._filename
   131         self._pendingfilename = b'%s.pending' % self._filename
   132         self._plchangecallbacks = {}
   132         self._plchangecallbacks = {}
   133         self._origpl = None
   133         self._origpl = None
   134         self._mapcls = dirstatemap.dirstatemap
   134         self._mapcls = dirstatemap.dirstatemap
   135         # Access and cache cwd early, so we don't access it for the first time
   135         # Access and cache cwd early, so we don't access it for the first time
   719 
   719 
   720     def write(self, tr):
   720     def write(self, tr):
   721         if not self._dirty:
   721         if not self._dirty:
   722             return
   722             return
   723 
   723 
   724         write_key = self._use_tracked_key and self._dirty_tracked_set
   724         write_key = self._use_tracked_hint and self._dirty_tracked_set
   725         if tr:
   725         if tr:
   726             # delay writing in-memory changes out
   726             # delay writing in-memory changes out
   727             if write_key:
       
   728                 tr.addfilegenerator(
       
   729                     b'dirstate-0-key-pre',
       
   730                     (self._filename_tk,),
       
   731                     lambda f: self._write_tracked_key(tr, f),
       
   732                     location=b'plain',
       
   733                     post_finalize=True,
       
   734                 )
       
   735             tr.addfilegenerator(
   727             tr.addfilegenerator(
   736                 b'dirstate-1-main',
   728                 b'dirstate-1-main',
   737                 (self._filename,),
   729                 (self._filename,),
   738                 lambda f: self._writedirstate(tr, f),
   730                 lambda f: self._writedirstate(tr, f),
   739                 location=b'plain',
   731                 location=b'plain',
   740                 post_finalize=True,
   732                 post_finalize=True,
   741             )
   733             )
   742             if write_key:
   734             if write_key:
   743                 tr.addfilegenerator(
   735                 tr.addfilegenerator(
   744                     b'dirstate-2-key-post',
   736                     b'dirstate-2-key-post',
   745                     (self._filename_tk,),
   737                     (self._filename_th,),
   746                     lambda f: self._write_tracked_key(tr, f),
   738                     lambda f: self._write_tracked_hint(tr, f),
   747                     location=b'plain',
   739                     location=b'plain',
   748                     post_finalize=True,
   740                     post_finalize=True,
   749                 )
   741                 )
   750             return
   742             return
   751 
   743 
   752         file = lambda f: self._opener(f, b"w", atomictemp=True, checkambig=True)
   744         file = lambda f: self._opener(f, b"w", atomictemp=True, checkambig=True)
   753         if write_key:
       
   754             # we change the key-file before changing the dirstate to make sure
       
   755             # reading invalidate there cache before we start writing
       
   756             with file(self._filename_tk) as f:
       
   757                 self._write_tracked_key(tr, f)
       
   758         with file(self._filename) as f:
   745         with file(self._filename) as f:
   759             self._writedirstate(tr, f)
   746             self._writedirstate(tr, f)
   760         if write_key:
   747         if write_key:
   761             # we update the key-file after writing to make sure reader have a
   748             # we update the key-file after writing to make sure reader have a
   762             # key that match the newly written content
   749             # key that match the newly written content
   763             with file(self._filename_tk) as f:
   750             with file(self._filename_th) as f:
   764                 self._write_tracked_key(tr, f)
   751                 self._write_tracked_hint(tr, f)
   765 
   752 
   766     def delete_tracked_key(self):
   753     def delete_tracked_hint(self):
   767         """remove the tracked_key file
   754         """remove the tracked_hint file
   768 
   755 
   769         To be used by format downgrades operation"""
   756         To be used by format downgrades operation"""
   770         self._opener.unlink(self._filename_tk)
   757         self._opener.unlink(self._filename_th)
   771         self._use_tracked_key = False
   758         self._use_tracked_hint = False
   772 
   759 
   773     def addparentchangecallback(self, category, callback):
   760     def addparentchangecallback(self, category, callback):
   774         """add a callback to be called when the wd parents are changed
   761         """add a callback to be called when the wd parents are changed
   775 
   762 
   776         Callback will be called with the following arguments:
   763         Callback will be called with the following arguments:
   791             self._origpl = None
   778             self._origpl = None
   792         self._map.write(tr, st)
   779         self._map.write(tr, st)
   793         self._dirty = False
   780         self._dirty = False
   794         self._dirty_tracked_set = False
   781         self._dirty_tracked_set = False
   795 
   782 
   796     def _write_tracked_key(self, tr, f):
   783     def _write_tracked_hint(self, tr, f):
   797         key = node.hex(uuid.uuid4().bytes)
   784         key = node.hex(uuid.uuid4().bytes)
   798         f.write(b"1\n%s\n" % key)  # 1 is the format version
   785         f.write(b"1\n%s\n" % key)  # 1 is the format version
   799 
   786 
   800     def _dirignore(self, f):
   787     def _dirignore(self, f):
   801         if self._ignore(f):
   788         if self._ignore(f):