[PATCH 6 of 8] convert: add support for --includerevs, --excluderevs

Yury Sulsky yury.sulsky at gmail.com
Mon Nov 28 00:26:02 CST 2011


# HG changeset patch
# User Yury Sulsky <yury.sulsky at gmail.com>
# Date 1322460125 18000
# Node ID 94ee4735ac3e64348ce1aa5de8265fd24dc93ccf
# Parent  2325d1fa02ac96bc8d4a31eab98ee736edc0f501
convert: add support for --includerevs, --excluderevs

diff -r 2325d1fa02ac -r 94ee4735ac3e hgext/convert/__init__.py
--- a/hgext/convert/__init__.py	Mon Nov 28 00:57:20 2011 -0500
+++ b/hgext/convert/__init__.py	Mon Nov 28 01:02:05 2011 -0500
@@ -135,6 +135,13 @@
     branch names. This can be used to (for instance) move code in one
     repository from "default" to a named branch.
 
+    The includerevs and excluderevs options allow you to choose which
+    revisions you would like to appear in the converted repository.
+    The arguments to these commands are files with a revision from the
+    source repository on each line. Note that these directives are
+    only advisory, and in certain situations (i.e. merge nodes and
+    branch endings) the revisions will be converted regardless.
+
     Mercurial Source
     ''''''''''''''''
 
@@ -306,6 +313,10 @@
            _('splice synthesized history into place'), _('FILE')),
           ('', 'branchmap', '',
            _('change branch names while converting'), _('FILE')),
+          ('', 'includerevs', '',
+           _('convert only these revisions'), _('FILE')),
+          ('', 'excluderevs', '',
+           _('exclude these revisions from the conversion'), _('FILE')),
           ('', 'branchsort', None, _('try to sort changesets by branches')),
           ('', 'datesort', None, _('try to sort changesets by date')),
           ('', 'sourcesort', None, _('preserve source changesets order'))],
diff -r 2325d1fa02ac -r 94ee4735ac3e hgext/convert/convcmd.py
--- a/hgext/convert/convcmd.py	Mon Nov 28 00:57:20 2011 -0500
+++ b/hgext/convert/convcmd.py	Mon Nov 28 01:02:05 2011 -0500
@@ -430,10 +430,15 @@
     if sortmode == 'sourcesort' and not srcc.hasnativeorder():
         raise util.Abort(_('--sourcesort is not supported by this data source'))
 
-    fmap = opts.get('filemap')
-    if fmap:
-        srcc = filtermap.filtermap_source(ui, srcc, fmap)
-        destc.setfilemapmode(True)
+    inrevs  = opts.get('includerevs')
+    outrevs = opts.get('excluderevs')
+    filemap = opts.get('filemap')
+    if filemap or inrevs or outrevs:
+        srcc = filtermap.filtermap_source(ui, srcc,
+                                          inrevs  = inrevs,
+                                          outrevs = outrevs,
+                                          filemap = filemap)
+        destc.setfilemapmode(filemap is not None)
 
     if not revmapfile:
         try:
diff -r 2325d1fa02ac -r 94ee4735ac3e hgext/convert/filtermap.py
--- a/hgext/convert/filtermap.py	Mon Nov 28 00:57:20 2011 -0500
+++ b/hgext/convert/filtermap.py	Mon Nov 28 01:02:05 2011 -0500
@@ -299,15 +299,48 @@
 #   or more interesting revisions.
 
 class filtermap_source(filtermap_base):
-    def __init__(self, ui, base, filemap):
+    def __init__(self, ui, base, inrevs = None, outrevs = None, filemap = None):
         # If we only filter by files, there's no need to track
         # changes. Revisions are only removed if they don't touch
         # files that we care about.
-        trackchanges = False
+        trackchanges = inrevs is not None or outrevs is not None
         super(filtermap_source, self).__init__(ui, base, trackchanges)
-        self.filemapper = filemapper(ui, filemap)
-
-    def wanted(self, rev, i):
+        if inrevs:
+            self.inrevs = self._parserevset(inrevs)
+        else:
+            self.inrevs = None
+
+        if outrevs:
+            self.outrevs = self._parserevset(outrevs)
+        else:
+            self.outrevs = None
+
+        if filemap is not None:
+            self.filemapper = filemapper(ui, filemap)
+        else:
+            self.filemapper = None
+
+    def _parserevset(self, fname):
+        def parse(line):
+            line = line.strip()
+            ret = self.base.lookuprev(line)
+            if ret is None:
+                self.ui.warn(_("Can't find revision %s." % line))
+            return ret
+        fp = open(fname, 'r')
+        try:
+            return set([parse(line) for line in fp])
+        finally:
+            fp.close()
+
+    def _wantrev(self, rev):
+        if self.inrevs  is not None and rev not in self.inrevs:
+            return False
+        if self.outrevs is not None and rev     in self.outrevs:
+            return False
+        return True
+
+    def _wantfiles(self, rev, i):
         try:
             files = self.base.getchangedfiles(rev, i)
         except NotImplementedError:
@@ -317,7 +350,13 @@
                 return True
         return False
 
+    def wanted(self, rev, i):
+        return self._wantrev(rev) and self._wantfiles(rev, i)
+
     def _filemapchanges(self, changes):
+        if self.filemapper is None:
+            return changes
+
         # Get the real changes and do the filtering/mapping. To be
         # able to get the files later on in getfile, we hide the
         # original filename in the rev part of the return value.
diff -r 2325d1fa02ac -r 94ee4735ac3e tests/test-convert-pickrevs.t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-convert-pickrevs.t	Mon Nov 28 01:02:05 2011 -0500
@@ -0,0 +1,214 @@
+
+  $ HGMERGE=true; export HGMERGE
+  $ echo '[extensions]' >> $HGRCPATH
+  $ echo 'graphlog =' >> $HGRCPATH
+  $ echo 'convert =' >> $HGRCPATH
+  $ glog()
+  > {
+  >     hg glog --template '{rev} "{desc}" files: {files}\n' "$@"
+  > }
+  $ hg init source
+  $ cd source
+  $ echo foo > foo
+  $ echo baz > baz
+  $ mkdir -p dir/subdir
+  $ echo dir/file >> dir/file
+  $ echo dir/file2 >> dir/file2
+  $ echo dir/file3 >> dir/file3 # to be corrupted in rev 0
+  $ echo dir/subdir/file3 >> dir/subdir/file3
+  $ echo dir/subdir/file4 >> dir/subdir/file4
+  $ hg ci -d '0 0' -qAm '0: add foo baz dir/'
+  $ echo bar > bar
+  $ echo quux > quux
+  $ echo dir/file4 >> dir/file4 # to be corrupted in rev 1
+  $ hg copy foo copied
+  $ hg ci -d '1 0' -qAm '1: add bar quux; copy foo to copied'
+  $ echo >> foo
+  $ hg ci -d '2 0' -m '2: change foo'
+  $ hg up -qC 1
+  $ echo >> bar
+  $ echo >> quux
+  $ hg ci -d '3 0' -m '3: change bar quux'
+  created new head
+  $ hg up -qC 2
+  $ hg merge -qr 3
+  $ echo >> bar
+  $ echo >> baz
+  $ hg ci -d '4 0' -m '4: first merge; change bar baz'
+  $ echo >> bar
+  $ echo 1 >> baz
+  $ echo >> quux
+  $ hg ci -d '5 0' -m '5: change bar baz quux'
+  $ hg up -qC 4
+  $ echo >> foo
+  $ echo 2 >> baz
+  $ hg ci -d '6 0' -m '6: change foo baz'
+  created new head
+  $ hg up -qC 5
+  $ hg merge -qr 6
+  $ echo >> bar
+  $ hg ci -d '7 0' -m '7: second merge; change bar'
+  $ echo >> foo
+  $ hg ci -m '8: change foo'
+  $ glog
+  @  8 "8: change foo" files: foo
+  |
+  o    7 "7: second merge; change bar" files: bar baz
+  |\
+  | o  6 "6: change foo baz" files: baz foo
+  | |
+  o |  5 "5: change bar baz quux" files: bar baz quux
+  |/
+  o    4 "4: first merge; change bar baz" files: bar baz
+  |\
+  | o  3 "3: change bar quux" files: bar quux
+  | |
+  o |  2 "2: change foo" files: foo
+  |/
+  o  1 "1: add bar quux; copy foo to copied" files: bar copied dir/file4 quux
+  |
+  o  0 "0: add foo baz dir/" files: baz dir/file dir/file2 dir/file3 dir/subdir/file3 dir/subdir/file4 foo
+  
+
+Test --includerev
+  $ cd ..
+  $ cat >>include.revs <<EOF
+  > 1
+  > 3
+  > 8
+  > EOF
+  $ hg convert --includerevs include.revs source dest1
+  initializing destination dest1 repository
+  scanning source...
+  sorting...
+  converting...
+  8 0: add foo baz dir/
+  7 1: add bar quux; copy foo to copied
+  6 2: change foo
+  5 3: change bar quux
+  4 4: first merge; change bar baz
+  3 5: change bar baz quux
+  2 6: change foo baz
+  1 7: second merge; change bar
+  0 8: change foo
+  $ hg glog -R dest1 --debug
+  o  changeset:   2:816c66a73d1cca6fee3bf3d1df8faf6b2f4f0028
+  |  tag:         tip
+  |  parent:      1:3d65aa94426b6d9d7cd36b96b56e14e3eaca073c
+  |  parent:      -1:0000000000000000000000000000000000000000
+  |  manifest:    2:09d3e43aece7285a480c3cf774b5f99d418dc219
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  files:       bar baz foo quux
+  |  extra:       branch=default
+  |  description:
+  |  8: change foo
+  |
+  |
+  o  changeset:   1:3d65aa94426b6d9d7cd36b96b56e14e3eaca073c
+  |  parent:      0:505780bbef8a0939a7ebb81b3972241566f73e81
+  |  parent:      -1:0000000000000000000000000000000000000000
+  |  manifest:    1:8236b8c9004f51898dbd80e712fc6ec17d828508
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:03 1970 +0000
+  |  files:       bar quux
+  |  extra:       branch=default
+  |  description:
+  |  3: change bar quux
+  |
+  |
+  o  changeset:   0:505780bbef8a0939a7ebb81b3972241566f73e81
+     parent:      -1:0000000000000000000000000000000000000000
+     parent:      -1:0000000000000000000000000000000000000000
+     manifest:    0:32cf238e6cc88a093c3d1d6e0f1ccab71423e3a1
+     user:        test
+     date:        Thu Jan 01 00:00:01 1970 +0000
+     files+:      bar baz copied dir/file dir/file2 dir/file3 dir/file4 dir/subdir/file3 dir/subdir/file4 foo quux
+     extra:       branch=default
+     description:
+     1: add bar quux; copy foo to copied
+  
+  
+Make sure that all of the files are there, even though some (e.g. baz) were 
+added in skipped revisions.
+
+  $ hg up -R dest1; ls dest1
+  11 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  bar
+  baz
+  copied
+  dir
+  foo
+  quux
+
+Test --excluderev
+
+  $ cat >>exclude.revs <<EOF
+  > 0
+  > 2
+  > 4
+  > 5
+  > 6
+  > 7
+  > EOF
+  $ hg convert --excluderevs exclude.revs source dest2
+  initializing destination dest2 repository
+  scanning source...
+  sorting...
+  converting...
+  8 0: add foo baz dir/
+  7 1: add bar quux; copy foo to copied
+  6 2: change foo
+  5 3: change bar quux
+  4 4: first merge; change bar baz
+  3 5: change bar baz quux
+  2 6: change foo baz
+  1 7: second merge; change bar
+  0 8: change foo
+  $ hg glog -R dest1 --debug
+  @  changeset:   2:816c66a73d1cca6fee3bf3d1df8faf6b2f4f0028
+  |  tag:         tip
+  |  parent:      1:3d65aa94426b6d9d7cd36b96b56e14e3eaca073c
+  |  parent:      -1:0000000000000000000000000000000000000000
+  |  manifest:    2:09d3e43aece7285a480c3cf774b5f99d418dc219
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  files:       bar baz foo quux
+  |  extra:       branch=default
+  |  description:
+  |  8: change foo
+  |
+  |
+  o  changeset:   1:3d65aa94426b6d9d7cd36b96b56e14e3eaca073c
+  |  parent:      0:505780bbef8a0939a7ebb81b3972241566f73e81
+  |  parent:      -1:0000000000000000000000000000000000000000
+  |  manifest:    1:8236b8c9004f51898dbd80e712fc6ec17d828508
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:03 1970 +0000
+  |  files:       bar quux
+  |  extra:       branch=default
+  |  description:
+  |  3: change bar quux
+  |
+  |
+  o  changeset:   0:505780bbef8a0939a7ebb81b3972241566f73e81
+     parent:      -1:0000000000000000000000000000000000000000
+     parent:      -1:0000000000000000000000000000000000000000
+     manifest:    0:32cf238e6cc88a093c3d1d6e0f1ccab71423e3a1
+     user:        test
+     date:        Thu Jan 01 00:00:01 1970 +0000
+     files+:      bar baz copied dir/file dir/file2 dir/file3 dir/file4 dir/subdir/file3 dir/subdir/file4 foo quux
+     extra:       branch=default
+     description:
+     1: add bar quux; copy foo to copied
+  
+  
+  $ hg up -R dest2; ls dest2
+  11 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  bar
+  baz
+  copied
+  dir
+  foo
+  quux
+
diff -r 2325d1fa02ac -r 94ee4735ac3e tests/test-convert.t
--- a/tests/test-convert.t	Mon Nov 28 00:57:20 2011 -0500
+++ b/tests/test-convert.t	Mon Nov 28 01:02:05 2011 -0500
@@ -121,6 +121,13 @@
       can be used to (for instance) move code in one repository from "default"
       to a named branch.
   
+      The includerevs and excluderevs options allow you to choose which
+      revisions you would like to appear in the converted repository. The
+      arguments to these commands are files with a revision from the source
+      repository on each line. Note that these directives are only advisory, and
+      in certain situations (i.e. merge nodes and branch endings) the revisions
+      will be converted regardless.
+  
       Mercurial Source
       ''''''''''''''''
   
@@ -257,6 +264,8 @@
       --filemap FILE     remap file names using contents of file
       --splicemap FILE   splice synthesized history into place
       --branchmap FILE   change branch names while converting
+      --includerevs FILE convert only these revisions
+      --excluderevs FILE exclude these revisions from the conversion
       --branchsort       try to sort changesets by branches
       --datesort         try to sort changesets by date
       --sourcesort       preserve source changesets order


More information about the Mercurial-devel mailing list