[PATCH 5 of 5] phase: attach phase to the transaction instead of the lock
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Thu Aug 7 17:52:03 CDT 2014
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1407445896 25200
# Thu Aug 07 14:11:36 2014 -0700
# Node ID cd17100e1102a2296e45c8837b4b774371c80f1b
# Parent ed5766a5d48982f9794683f594625ce663ca8f90
phase: attach phase to the transaction instead of the lock
The phase cache file is no longer written on lock release, it is now handled by
the transaction (as changeset and obsolescence markers are).
(Hooray)
As we stop relying on the lock to write phase, repo with no existing phase
information will need to wait for a phase move or a strip to happen in order to
get the first write in the `phaseroots` file. This explain the change in
test-inherit-mode.t.
This should not have any side effect but in very obscure case were people
interact with pre 2.1 and post 2.1 version of Mercurial on the same repo while
having MQ patches applied but the MQ extension disabled from time to time. A
case unlikely enough to not worth preserving the old behavior with awful hacks.
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1087,12 +1087,10 @@ class localrepository(object):
if l is not None and l.held:
l.lock()
return l
def unlock():
- if hasunfilteredcache(self, '_phasecache'):
- self._phasecache.write()
for k, ce in self._filecache.items():
if k == 'dirstate' or k not in self.__dict__:
continue
ce.refresh()
diff --git a/mercurial/phases.py b/mercurial/phases.py
--- a/mercurial/phases.py
+++ b/mercurial/phases.py
@@ -204,15 +204,17 @@ class phasecache(object):
for phase, roots in enumerate(self.phaseroots):
for h in roots:
fp.write('%i %s\n' % (phase, hex(h)))
self.dirty = False
- def _updateroots(self, phase, newroots):
+ def _updateroots(self, phase, newroots, tr):
self.phaseroots[phase] = newroots
self._phaserevs = None
self.dirty = True
+ tr.addfilegenerator('phase', ('phaseroots',), self._write)
+
def advanceboundary(self, repo, tr, targetphase, nodes):
# Be careful to preserve shallow-copied values: do not update
# phaseroots values, replace them.
repo = repo.unfiltered()
@@ -225,11 +227,11 @@ class phasecache(object):
break # no roots to move anymore
olds = self.phaseroots[phase]
roots = set(ctx.node() for ctx in repo.set(
'roots((%ln::) - (%ln::%ln))', olds, olds, nodes))
if olds != roots:
- self._updateroots(phase, roots)
+ self._updateroots(phase, roots, tr)
# some roots may need to be declared for lower phases
delroots.extend(olds - roots)
# declare deleted root in the target phase
if targetphase != 0:
self.retractboundary(repo, tr, targetphase, delroots)
@@ -248,11 +250,11 @@ class phasecache(object):
raise util.Abort(_('cannot change null revision phase'))
currentroots = currentroots.copy()
currentroots.update(newroots)
ctxs = repo.set('roots(%ln::)', currentroots)
currentroots.intersection_update(ctx.node() for ctx in ctxs)
- self._updateroots(targetphase, currentroots)
+ self._updateroots(targetphase, currentroots, tr)
repo.invalidatevolatilesets()
def filterunknown(self, repo):
"""remove unknown nodes from the phase boundary
diff --git a/tests/test-inherit-mode.t b/tests/test-inherit-mode.t
--- a/tests/test-inherit-mode.t
+++ b/tests/test-inherit-mode.t
@@ -118,11 +118,10 @@ group can still write everything
00770 ../push/.hg/store/data/
00770 ../push/.hg/store/data/dir/
00660 ../push/.hg/store/data/dir/bar.i
00660 ../push/.hg/store/data/foo.i
00660 ../push/.hg/store/fncache
- 00660 ../push/.hg/store/phaseroots
00660 ../push/.hg/store/undo
00660 ../push/.hg/store/undo.phaseroots
00660 ../push/.hg/undo.bookmarks
00660 ../push/.hg/undo.branch
00660 ../push/.hg/undo.desc
More information about the Mercurial-devel
mailing list