mercurial/dirstate.py
changeset 26634 09bb1ee7e73e
parent 26633 020b12d591f3
child 26635 79d86ab65c9d
equal deleted inserted replaced
26633:020b12d591f3 26634:09bb1ee7e73e
    24 
    24 
    25 class rootcache(filecache):
    25 class rootcache(filecache):
    26     """filecache for files in the repository root"""
    26     """filecache for files in the repository root"""
    27     def join(self, obj, fname):
    27     def join(self, obj, fname):
    28         return obj._join(fname)
    28         return obj._join(fname)
       
    29 
       
    30 def _getfsnow(vfs):
       
    31     '''Get "now" timestamp on filesystem'''
       
    32     tmpfd, tmpname = vfs.mkstemp()
       
    33     try:
       
    34         return util.statmtimesec(os.fstat(tmpfd))
       
    35     finally:
       
    36         os.close(tmpfd)
       
    37         vfs.unlink(tmpname)
    29 
    38 
    30 class dirstate(object):
    39 class dirstate(object):
    31 
    40 
    32     def __init__(self, opener, ui, root, validate):
    41     def __init__(self, opener, ui, root, validate):
    33         '''Create a new dirstate object.
    42         '''Create a new dirstate object.
   609                 else:
   618                 else:
   610                     self._map[f] = dirstatetuple('n', 0o666, -1, 0)
   619                     self._map[f] = dirstatetuple('n', 0o666, -1, 0)
   611         self._pl = (parent, nullid)
   620         self._pl = (parent, nullid)
   612         self._dirty = True
   621         self._dirty = True
   613 
   622 
   614     def write(self):
   623     def write(self, repo=None):
   615         if not self._dirty:
   624         if not self._dirty:
   616             return
   625             return
   617 
   626 
   618         # enough 'delaywrite' prevents 'pack_dirstate' from dropping
   627         # enough 'delaywrite' prevents 'pack_dirstate' from dropping
   619         # timestamp of each entries in dirstate, because of 'now > mtime'
   628         # timestamp of each entries in dirstate, because of 'now > mtime'
   620         delaywrite = self._ui.configint('debug', 'dirstate.delaywrite', 0)
   629         delaywrite = self._ui.configint('debug', 'dirstate.delaywrite', 0)
   621         if delaywrite > 0:
   630         if delaywrite > 0:
   622             import time # to avoid useless import
   631             import time # to avoid useless import
   623             time.sleep(delaywrite)
   632             time.sleep(delaywrite)
   624 
   633 
   625         st = self._opener(self._filename, "w", atomictemp=True)
   634         filename = self._filename
       
   635         if not repo:
       
   636             tr = None
       
   637             if self._opener.lexists(self._pendingfilename):
       
   638                 # if pending file already exists, in-memory changes
       
   639                 # should be written into it, because it has priority
       
   640                 # to '.hg/dirstate' at reading under HG_PENDING mode
       
   641                 filename = self._pendingfilename
       
   642         else:
       
   643             tr = repo.currenttransaction()
       
   644 
       
   645         if tr:
       
   646             # 'dirstate.write()' is not only for writing in-memory
       
   647             # changes out, but also for dropping ambiguous timestamp.
       
   648             # delayed writing re-raise "ambiguous timestamp issue".
       
   649             # See also the wiki page below for detail:
       
   650             # https://www.mercurial-scm.org/wiki/DirstateTransactionPlan
       
   651 
       
   652             # emulate dropping timestamp in 'parsers.pack_dirstate'
       
   653             now = _getfsnow(repo.vfs)
       
   654             dmap = self._map
       
   655             for f, e in dmap.iteritems():
       
   656                 if e[0] == 'n' and e[3] == now:
       
   657                     dmap[f] = dirstatetuple(e[0], e[1], e[2], -1)
       
   658 
       
   659             # emulate that all 'dirstate.normal' results are written out
       
   660             self._lastnormaltime = 0
       
   661 
       
   662             # delay writing in-memory changes out
       
   663             tr.addfilegenerator('dirstate', (self._filename,),
       
   664                                 self._writedirstate, location='plain')
       
   665             return
       
   666 
       
   667         st = self._opener(filename, "w", atomictemp=True)
   626         self._writedirstate(st)
   668         self._writedirstate(st)
   627 
   669 
   628     def _writedirstate(self, st):
   670     def _writedirstate(self, st):
   629         # use the modification time of the newly created temporary file as the
   671         # use the modification time of the newly created temporary file as the
   630         # filesystem's notion of 'now'
   672         # filesystem's notion of 'now'