[PATCH] mq: introduce the qunmanage command

Dirkjan Ochtman dirkjan at ochtman.nl
Wed May 28 04:26:44 CDT 2008


# HG changeset patch
# User Dirkjan Ochtman <dirkjan at ochtman.nl>
# Date 1211966794 -7200
# Node ID 1e626c9876da7bbb501177dc47ceea7af5ea68df
# Parent  2b7e8a964109148ce5ca5696df69cb12fe331e9a
mq: introduce the qunmanage command

diff -r 2b7e8a964109 -r 1e626c9876da hgext/mq.py
--- a/hgext/mq.py	Wed May 28 10:57:22 2008 +0200
+++ b/hgext/mq.py	Wed May 28 11:26:34 2008 +0200
@@ -535,6 +535,41 @@
                 break
         return (err, n)
 
+    def _clean_series(self, patches):
+        indices = [self.find_series(p) for p in patches]
+        indices.sort()
+        for i in indices[-1::-1]:
+            del self.full_series[i]
+        self.parse_series()
+        self.series_dirty = 1
+
+    def unmanage(self, repo, revs):
+        revs.sort()
+        firstrev = repo.changelog.rev(revlog.bin(self.applied[0].rev))
+        appliedbase = 0
+        patches = []
+        for rev in revs:
+            if rev < firstrev:
+                raise util.Abort(_('revision %d is not managed') % rev)
+            base = revlog.bin(self.applied[appliedbase].rev)
+            node = repo.changelog.node(rev)
+            if node != base:
+                raise util.Abort(_('cannot delete revision %d above '
+                                   'applied patches') % rev)
+            patches.append(self.applied[appliedbase].name)
+            appliedbase += 1
+
+        r = self.qrepo()
+        if r:
+            r.remove(patches, True)
+        else:
+            for p in patches:
+                os.unlink(self.join(p))
+
+        del self.applied[:appliedbase]
+        self.applied_dirty = 1
+        self._clean_series(patches)
+
     def delete(self, repo, patches, opts):
         if not patches and not opts.get('rev'):
             raise util.Abort(_('qdelete requires at least one revision or '
@@ -580,12 +615,7 @@
         if appliedbase:
             del self.applied[:appliedbase]
             self.applied_dirty = 1
-        indices = [self.find_series(p) for p in realpatches]
-        indices.sort()
-        for i in indices[-1::-1]:
-            del self.full_series[i]
-        self.parse_series()
-        self.series_dirty = 1
+        self._clean_series(realpatches)
 
     def check_toppatch(self, repo):
         if len(self.applied) > 0:
@@ -1497,9 +1527,8 @@
     the --rev parameter. At least one patch or revision is required.
 
     With --rev, mq will stop managing the named revisions (converting
-    them to regular mercurial changesets). The patches must be applied
-    and at the base of the stack. This option is useful when the patches
-    have been applied upstream.
+    them to regular mercurial changesets). The qunmanage command should be
+    used as an alternative for qdel -r, as the latter option is deprecated.
 
     With --keep, the patch files are preserved in the patch directory."""
     q = repo.mq
@@ -2167,6 +2196,35 @@
         finally:
             q.save_dirty()
 
+def unmanage(ui, repo, *revrange, **opts):
+    """move applied patches into repository history
+
+    Stops managing the specified revisions (corresponding to applied
+    patches) in mq and converts them to regular changesets.
+
+    Accepts an optional revision range. If no arguments are given, all
+    applied mq revisions are removed from mq control. The given revisions
+    must be at the base of the stack of applied patches.
+
+    This can be especially useful if your changes have been applied to an
+    upstream repository, or if you are about to push your changes to upstream.
+    """
+    if not opts['applied'] and not revrange:
+        ui.status(_('no revisions specified\n'))
+        return 0
+    elif opts['applied']:
+        revrange = ('qbase:qtip',) + revrange
+
+    q = repo.mq
+    if not q.applied:
+        ui.status(_('no patches applied\n'))
+        return 0
+
+    revs = cmdutil.revrange(repo, revrange)
+    q.unmanage(repo, revs)
+    q.save_dirty()
+    return 0
+
 def reposetup(ui, repo):
     class mqrepo(repo.__class__):
         def abort_if_wdir_patched(self, errmsg, force=False):
@@ -2377,4 +2435,8 @@
          _('hg strip [-f] [-b] [-n] REV')),
     "qtop": (top, [] + seriesopts, _('hg qtop [-s]')),
     "qunapplied": (unapplied, [] + seriesopts, _('hg qunapplied [-s] [PATCH]')),
+    "qunmanage":
+        (unmanage,
+         [('a', 'applied', None, _('unmanage all applied changesets'))],
+         _('hg qunmanage [-a] [REV...]')),
 }
diff -r 2b7e8a964109 -r 1e626c9876da tests/test-mq-qdelete
--- a/tests/test-mq-qdelete	Wed May 28 10:57:22 2008 +0200
+++ b/tests/test-mq-qdelete	Wed May 28 11:26:34 2008 +0200
@@ -35,3 +35,28 @@
 hg qdel -r qbase:e
 hg qapplied
 hg log --template '{rev} {desc}\n'
+
+cd ..
+hg init b
+cd b
+
+echo 'base' > base
+hg ci -Ambase
+
+hg qunmanage
+hg qunmanage -a
+
+hg qnew a
+hg qnew b
+hg qnew c
+
+hg qunmanage 0
+hg qunmanage b
+hg qunmanage qbase:b
+hg qapplied
+hg log --template '{rev} {desc}\n'
+
+hg qunmanage -a c
+hg qapplied
+hg log --template '{rev} {desc}\n'
+ls .hg/patches
diff -r 2b7e8a964109 -r 1e626c9876da tests/test-mq-qdelete.out
--- a/tests/test-mq-qdelete.out	Wed May 28 10:57:22 2008 +0200
+++ b/tests/test-mq-qdelete.out	Wed May 28 11:26:34 2008 +0200
@@ -22,3 +22,18 @@
 2 [mq]: d
 1 [mq]: a
 0 base
+adding base
+abort: no patches applied
+abort: revision 0 is not managed
+abort: cannot delete revision 2 above applied patches
+c
+3 [mq]: c
+2 [mq]: b
+1 [mq]: a
+0 base
+3 [mq]: c
+2 [mq]: b
+1 [mq]: a
+0 base
+series
+status
diff -r 2b7e8a964109 -r 1e626c9876da tests/test-mq.out
--- a/tests/test-mq.out	Wed May 28 10:57:22 2008 +0200
+++ b/tests/test-mq.out	Wed May 28 11:26:34 2008 +0200
@@ -48,6 +48,7 @@
  qseries      print the entire series file
  qtop         print the name of the current patch
  qunapplied   print the patches not yet applied
+ qunmanage    release applied patches from mq control
  strip        strip a revision and all later revs on the same branch
 
 use "hg -v help mq" to show aliases and global options


More information about the Mercurial-devel mailing list