[PATCH 2 of 6] mq-safety: don't apply safety on non-outgoing changeset
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Fri Jan 20 14:30:54 CST 2012
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1327081529 -3600
# Branch stable
# Node ID ad5fac0e43e4167a302b9d687a3ac3e1c5811f51
# Parent 475afd5eb09b0a68dc0d563c83596dcc9a3a2dfe
mq-safety: don't apply safety on non-outgoing changeset
When mq changeset are secret, they don't appear in outgoing and won't be
pushed. So it's not necessary to abort the push.
The checkpush call is protected by lock to prevent race on phase.
diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -3161,15 +3161,22 @@
def checkpush(self, force, revs):
if self.mq.applied and not force:
- haspatches = True
+ outapplied = [e.node for e in self.mq.applied]
if revs:
- # Assume applied patches have no non-patch descendants
- # and are not on remote already. If they appear in the
- # set of resolved 'revs', bail out.
- applied = set(e.node for e in self.mq.applied)
- haspatches = bool([n for n in revs if n in applied])
- if haspatches:
- raise util.Abort(_('source has mq patches applied'))
+ # Assume applied patches have no non-patch descendants and
+ # are not on remote already. Filtering any changeset not
+ # pushed.
+ heads = set(revs)
+ for node in reversed(outapplied):
+ if node in heads:
+ break
+ else:
+ outapplied.pop()
+ # looking for pushed and shared changeset
+ for node in outapplied:
+ if repo[node].phase() < phases.secret:
+ raise util.Abort(_('source has mq patches applied'))
+ # no non-secret patches pushed
super(mqrepo, self).checkpush(force, revs)
def _findtags(self):
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1597,14 +1597,14 @@
# unbundle assumes local user cannot lock remote repo (new ssh
# servers, http servers).
- self.checkpush(force, revs)
- lock = None
- unbundle = remote.capable('unbundle')
- if not unbundle:
- lock = remote.lock()
+ # get local lock as we might write phase data
+ locallock = self.lock()
try:
- # get local lock as we might write phase data
- locallock = self.lock()
+ self.checkpush(force, revs)
+ lock = None
+ unbundle = remote.capable('unbundle')
+ if not unbundle:
+ lock = remote.lock()
try:
# discovery
fci = discovery.findcommonincoming
@@ -1687,10 +1687,10 @@
self.ui.warn(_('updating %s to public failed!\n')
% newremotehead)
finally:
- locallock.release()
+ if lock is not None:
+ lock.release()
finally:
- if lock is not None:
- lock.release()
+ locallock.release()
self.ui.debug("checking for updated bookmarks\n")
rb = remote.listkeys('bookmarks')
diff --git a/tests/test-mq-safety.t b/tests/test-mq-safety.t
--- a/tests/test-mq-safety.t
+++ b/tests/test-mq-safety.t
@@ -144,7 +144,18 @@
Pushing applied patch with --rev without --force
- $ hg push -r default ../forcepush2
+All secret
+
+ $ hg push -r . ../forcepush2
+ pushing to ../forcepush2
+ searching for changes
+ no changes to push but 1 secret changesets
+
+some draft
+
+ $ hg phase --draft 'mq()'
+
+ $ hg push -r . ../forcepush2
pushing to ../forcepush2
abort: source has mq patches applied
[255]
@@ -168,11 +179,12 @@
Pushing applied patch with --force
+ $ hg phase --force --secret 'mq()'
$ hg push --force -r default ../forcepush2
pushing to ../forcepush2
searching for changes
no changes to push but 1 secret changesets
- $ hg phase -d 'mq()'
+ $ hg phase --draft 'mq()'
$ hg push --force -r default ../forcepush2
pushing to ../forcepush2
searching for changes
diff --git a/tests/test-mq.t b/tests/test-mq.t
--- a/tests/test-mq.t
+++ b/tests/test-mq.t
@@ -393,8 +393,9 @@
abort: cannot commit over an applied mq patch
[255]
-push should fail
+push should fail if draft
+ $ hg phase --draft 'mq()'
$ hg push ../../k
pushing to ../../k
abort: source has mq patches applied
More information about the Mercurial-devel
mailing list