# HG changeset patch # User Pierre-Yves David # Date 1327081529 -3600 # Node ID ec8a9e06cf0563824828479d39f5b9de1e73a7df # Parent bd84fc0b5f64e31c7e79eda59d2ede1fd135ba9d 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 -r bd84fc0b5f64 -r ec8a9e06cf05 hgext/mq.py --- a/hgext/mq.py Fri Jan 20 00:27:11 2012 +0100 +++ b/hgext/mq.py Fri Jan 20 18:45:29 2012 +0100 @@ -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 -r bd84fc0b5f64 -r ec8a9e06cf05 mercurial/localrepo.py --- a/mercurial/localrepo.py Fri Jan 20 00:27:11 2012 +0100 +++ b/mercurial/localrepo.py Fri Jan 20 18:45:29 2012 +0100 @@ -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 -r bd84fc0b5f64 -r ec8a9e06cf05 tests/test-mq-safety.t --- a/tests/test-mq-safety.t Fri Jan 20 00:27:11 2012 +0100 +++ b/tests/test-mq-safety.t Fri Jan 20 18:45:29 2012 +0100 @@ -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 -r bd84fc0b5f64 -r ec8a9e06cf05 tests/test-mq.t --- a/tests/test-mq.t Fri Jan 20 00:27:11 2012 +0100 +++ b/tests/test-mq.t Fri Jan 20 18:45:29 2012 +0100 @@ -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