Patchwork [3,of,4,v2] convert: introduce hg.revs to replace hg.startrev and --rev with a revset

login
register
mail settings
Submitter Mads Kiilerich
Date Oct. 10, 2013, 6:46 p.m.
Message ID <a6e6bce1fa496a922175.1381430776@mk-desktop>
Download mbox | patch
Permalink /patch/2746/
State Accepted
Commit e271970b98216098c1cb0c71ae1076d7ac0ad8ee
Headers show

Comments

Mads Kiilerich - Oct. 10, 2013, 6:46 p.m.
# HG changeset patch
# User Mads Kiilerich <madski@unity3d.com>
# Date 1374273788 -7200
#      Sat Jul 20 00:43:08 2013 +0200
# Node ID a6e6bce1fa496a922175449208d7d2b9a4c40f74
# Parent  3951cebb6743fee2b68a835d9097cb2d8784d230
convert: introduce hg.revs to replace hg.startrev and --rev with a revset

The existing knobs for controlling which revisions to convert were often
insufficient. Revsets is a shiny hammer that provides a better solution.

Revsets has been introduced in --rev handling in a lot of other places while
being more or less backwards compatible. Doing the same here would be a much
more elegant ... but that would unfortunately not work in this case.  "--rev 7"
used to mean revision 0 to 7 - it would be an unacceptable change if it
suddenly just meant revision 7.

Instead we introduce a new configuration setting. It will only work for
Mercurial repositories so adding a new commandline option for it would not be a
nice solution.

There is no way to use the fancy deprecation markup for configuration settings
so we just remove the documentation of hg.startrev.

Patch

diff --git a/hgext/convert/__init__.py b/hgext/convert/__init__.py
--- a/hgext/convert/__init__.py
+++ b/hgext/convert/__init__.py
@@ -155,8 +155,7 @@ 
         (forces target IDs to change). It takes a boolean argument and
         defaults to False.
 
-    :convert.hg.startrev: convert start revision and its descendants.
-        It takes a hg revision identifier and defaults to 0.
+    :convert.hg.revs: revset specifying the source revisions to convert.
 
     CVS Source
     ##########
diff --git a/hgext/convert/hg.py b/hgext/convert/hg.py
--- a/hgext/convert/hg.py
+++ b/hgext/convert/hg.py
@@ -21,7 +21,7 @@ 
 import os, time, cStringIO
 from mercurial.i18n import _
 from mercurial.node import bin, hex, nullid
-from mercurial import hg, util, context, bookmarks, error
+from mercurial import hg, util, context, bookmarks, error, scmutil
 
 from common import NoRepo, commit, converter_source, converter_sink
 
@@ -252,23 +252,37 @@ 
         self.convertfp = None
         # Restrict converted revisions to startrev descendants
         startnode = ui.config('convert', 'hg.startrev')
-        if startnode is not None:
-            try:
-                startnode = self.repo.lookup(startnode)
-            except error.RepoError:
-                raise util.Abort(_('%s is not a valid start revision')
-                                 % startnode)
-            startrev = self.repo.changelog.rev(startnode)
-            children = {startnode: 1}
-            for r in self.repo.changelog.descendants([startrev]):
-                children[self.repo.changelog.node(r)] = 1
-            self.keep = children.__contains__
+        hgrevs = ui.config('convert', 'hg.revs')
+        if hgrevs is None:
+            if startnode is not None:
+                try:
+                    startnode = self.repo.lookup(startnode)
+                except error.RepoError:
+                    raise util.Abort(_('%s is not a valid start revision')
+                                     % startnode)
+                startrev = self.repo.changelog.rev(startnode)
+                children = {startnode: 1}
+                for r in self.repo.changelog.descendants([startrev]):
+                    children[self.repo.changelog.node(r)] = 1
+                self.keep = children.__contains__
+            else:
+                self.keep = util.always
+            if rev:
+                self._heads = [self.repo[rev].node()]
+            else:
+                self._heads = self.repo.heads()
         else:
-            self.keep = util.always
-        if rev:
-            self._heads = [self.repo[rev].node()]
-        else:
-            self._heads = self.repo.heads()
+            if rev or startnode is not None:
+                raise util.Abort(_('hg.revs cannot be combined with '
+                                   'hg.startrev or --rev'))
+            nodes = set()
+            parents = set()
+            for r in scmutil.revrange(self.repo, [hgrevs]):
+                ctx = self.repo[r]
+                nodes.add(ctx.node())
+                parents.update(p.node() for p in ctx.parents())
+            self.keep = nodes.__contains__
+            self._heads = nodes - parents
 
     def changectx(self, rev):
         if self.lastrev != rev:
diff --git a/tests/test-convert-hg-startrev.t b/tests/test-convert-hg-startrev.t
--- a/tests/test-convert-hg-startrev.t
+++ b/tests/test-convert-hg-startrev.t
@@ -183,3 +183,23 @@ 
   b
   $ hg -q verify
   $ cd ..
+
+Convert from revset in convert.hg.revs
+
+  $ hg convert --config convert.hg.revs='3:4+0' source revsetrepo
+  initializing destination revsetrepo repository
+  scanning source...
+  sorting...
+  converting...
+  2 0: add a b f
+  1 3: change a
+  0 4: merge 2 and 3
+
+  $ glog revsetrepo
+  o  2 "4: merge 2 and 3" files: b c d e f
+  |
+  o  1 "3: change a" files: a
+  |
+  o  0 "0: add a b f" files: a b f
+  
+  $ cd ..
diff --git a/tests/test-convert.t b/tests/test-convert.t
--- a/tests/test-convert.t
+++ b/tests/test-convert.t
@@ -135,9 +135,8 @@ 
                     store original revision ID in changeset (forces target IDs
                     to change). It takes a boolean argument and defaults to
                     False.
-      convert.hg.startrev
-                    convert start revision and its descendants. It takes a hg
-                    revision identifier and defaults to 0.
+      convert.hg.revs
+                    revset specifying the source revisions to convert.
   
       CVS Source
       ##########