diff hgext/mq.py @ 13033:026053f691a4

mq: add an '-e/--exact' option to qpush This patch adds an '--exact/-e' option to qpush that will try to push the patches in the correct location in the DAG. Specifying this option does the following: * If --move is specified, abort. It makes no sense to move a patch to the front of the queue and try to apply it to its parent, because its parent is one of the patches we just moved it in front of! * If patches are already applied, abort. We don't want patch changesets scattered throughout the DAG. * If local changes are present, abort unless --force is used, as usual. * Find the first patch we're going to push (if we're pushing multiple patches with a target or --all). * If that patch doesn't have a parent, abort, obviously. * If the parent doesn't exist in the repo, abort. Something is wrong. * Update to the parent, then continue pushing the patches as normal.
author Steve Losh <steve@stevelosh.com>
date Wed, 17 Nov 2010 21:18:44 -0500
parents 3da456d0c885
children 77aa74fe0e0b
line wrap: on
line diff
--- a/hgext/mq.py	Mon Nov 22 12:43:31 2010 -0600
+++ b/hgext/mq.py	Wed Nov 17 21:18:44 2010 -0500
@@ -1006,7 +1006,7 @@
         raise util.Abort(_("patch %s not in series") % patch)
 
     def push(self, repo, patch=None, force=False, list=False,
-             mergeq=None, all=False, move=False):
+             mergeq=None, all=False, move=False, exact=False):
         diffopts = self.diffopts()
         wlock = repo.wlock()
         try:
@@ -1015,7 +1015,7 @@
                 heads += ls
             if not heads:
                 heads = [nullid]
-            if repo.dirstate.parents()[0] not in heads:
+            if repo.dirstate.parents()[0] not in heads and not exact:
                 self.ui.status(_("(working directory not at a head)\n"))
 
             if not self.series:
@@ -1062,6 +1062,18 @@
             if not force:
                 self.check_localchanges(repo)
 
+            if exact:
+                if move:
+                    raise util.Abort(_("cannot use --exact and --move together"))
+                if self.applied:
+                    raise util.Abort(_("cannot push --exact with applied patches"))
+                root = self.series[start]
+                target = patchheader(self.join(root), self.plainmode).parent
+                if not target:
+                    raise util.Abort(_("%s does not have a parent recorded" % root))
+                if not repo[target] == repo['.']:
+                    hg.update(repo, target)
+
             if move:
                 if not patch:
                     raise  util.Abort(_("please specify the patch to move"))
@@ -2338,7 +2350,8 @@
         mergeq = queue(ui, repo.join(""), newpath)
         ui.warn(_("merging with queue at: %s\n") % mergeq.path)
     ret = q.push(repo, patch, force=opts.get('force'), list=opts.get('list'),
-                 mergeq=mergeq, all=opts.get('all'), move=opts.get('move'))
+                 mergeq=mergeq, all=opts.get('all'), move=opts.get('move'),
+                 exact=opts.get('exact'))
     return ret
 
 def pop(ui, repo, patch=None, **opts):
@@ -3114,6 +3127,7 @@
     "^qpush":
         (push,
          [('f', 'force', None, _('apply on top of local changes')),
+          ('e', 'exact', None, _('apply the target patch to its recorded parent')),
           ('l', 'list', None, _('list patch name in commit text')),
           ('a', 'all', None, _('apply all patches')),
           ('m', 'merge', None, _('merge from another queue (DEPRECATED)')),