834 # changes out, but also for dropping ambiguous timestamp. |
834 # changes out, but also for dropping ambiguous timestamp. |
835 # delayed writing re-raise "ambiguous timestamp issue". |
835 # delayed writing re-raise "ambiguous timestamp issue". |
836 # See also the wiki page below for detail: |
836 # See also the wiki page below for detail: |
837 # https://www.mercurial-scm.org/wiki/DirstateTransactionPlan |
837 # https://www.mercurial-scm.org/wiki/DirstateTransactionPlan |
838 |
838 |
839 # emulate dropping timestamp in 'parsers.pack_dirstate' |
839 # record when mtime start to be ambiguous |
840 now = _getfsnow(self._opener) |
840 now = _getfsnow(self._opener) |
841 self._map.clearambiguoustimes(self._updatedfiles, now) |
|
842 |
841 |
843 # emulate that all 'dirstate.normal' results are written out |
842 # emulate that all 'dirstate.normal' results are written out |
844 self._lastnormaltime = 0 |
|
845 self._updatedfiles.clear() |
843 self._updatedfiles.clear() |
846 |
844 |
847 # delay writing in-memory changes out |
845 # delay writing in-memory changes out |
848 tr.addfilegenerator( |
846 tr.addfilegenerator( |
849 b'dirstate', |
847 b'dirstate', |
850 (self._filename,), |
848 (self._filename,), |
851 lambda f: self._writedirstate(tr, f), |
849 lambda f: self._writedirstate(tr, f, now=now), |
852 location=b'plain', |
850 location=b'plain', |
853 ) |
851 ) |
854 return |
852 return |
855 |
853 |
856 st = self._opener(filename, b"w", atomictemp=True, checkambig=True) |
854 st = self._opener(filename, b"w", atomictemp=True, checkambig=True) |
865 Category is a unique identifier to allow overwriting an old callback |
863 Category is a unique identifier to allow overwriting an old callback |
866 with a newer callback. |
864 with a newer callback. |
867 """ |
865 """ |
868 self._plchangecallbacks[category] = callback |
866 self._plchangecallbacks[category] = callback |
869 |
867 |
870 def _writedirstate(self, tr, st): |
868 def _writedirstate(self, tr, st, now=None): |
871 # notify callbacks about parents change |
869 # notify callbacks about parents change |
872 if self._origpl is not None and self._origpl != self._pl: |
870 if self._origpl is not None and self._origpl != self._pl: |
873 for c, callback in sorted( |
871 for c, callback in sorted( |
874 pycompat.iteritems(self._plchangecallbacks) |
872 pycompat.iteritems(self._plchangecallbacks) |
875 ): |
873 ): |
876 callback(self, self._origpl, self._pl) |
874 callback(self, self._origpl, self._pl) |
877 self._origpl = None |
875 self._origpl = None |
878 # use the modification time of the newly created temporary file as the |
876 |
879 # filesystem's notion of 'now' |
877 if now is None: |
880 now = util.fstat(st)[stat.ST_MTIME] & _rangemask |
878 # use the modification time of the newly created temporary file as the |
|
879 # filesystem's notion of 'now' |
|
880 now = util.fstat(st)[stat.ST_MTIME] & _rangemask |
881 |
881 |
882 # enough 'delaywrite' prevents 'pack_dirstate' from dropping |
882 # enough 'delaywrite' prevents 'pack_dirstate' from dropping |
883 # timestamp of each entries in dirstate, because of 'now > mtime' |
883 # timestamp of each entries in dirstate, because of 'now > mtime' |
884 delaywrite = self._ui.configint(b'debug', b'dirstate.delaywrite') |
884 delaywrite = self._ui.configint(b'debug', b'dirstate.delaywrite') |
885 if delaywrite > 0: |
885 if delaywrite > 0: |