Patchwork [2,of,2] convert: don't drop commits that are empty in the source when using --filemap

login
register
mail settings
Submitter Matt Harbison
Date Jan. 10, 2019, 11:01 p.m.
Message ID <1f267b001e4588edd387.1547161292@mharbison-pc.attotech.com>
Download mbox | patch
Permalink /patch/37640/
State Accepted
Headers show

Comments

Matt Harbison - Jan. 10, 2019, 11:01 p.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1547067725 18000
#      Wed Jan 09 16:02:05 2019 -0500
# Branch stable
# Node ID 1f267b001e4588edd3873a9039be7679f08c7560
# Parent  60e7f0c9b572f995b0d196f6b946001f148d576f
convert: don't drop commits that are empty in the source when using --filemap

I ran into this when using `hg lfconvert --to-normal` (which uses the filemap
class internally), and saw that commits with nothing but a branch change were
dropped.  We could put in an option that only lfconvert uses internally.  But
silently dropping anything other than a commit where all changes were excluded
seems unintended.  For example, there's a message in mercurial_sink.putcommit()
if it drops an empty commit.  (And the reason that isn't kicking in here is
because lfconvert isn't passing --filemap, so the self.filemapmode conditional
there is always False.)

The naive change of `return not files` broke test-convert-filemap.t, so this is
a little more elaborate than needed for converting from largefiles.

Patch

diff --git a/hgext/convert/filemap.py b/hgext/convert/filemap.py
--- a/hgext/convert/filemap.py
+++ b/hgext/convert/filemap.py
@@ -305,7 +305,18 @@  class filemap_source(common.converter_so
         for f in files:
             if self.filemapper(f):
                 return True
-        return False
+
+        # The include directive is documented to include nothing else (though
+        # valid branch closes are included).
+        if self.filemapper.include:
+            return False
+
+        # Allow empty commits in the source revision through.  The getchanges()
+        # method doesn't even bother calling this if it determines that the
+        # close marker is significant (i.e. all of the branch ancestors weren't
+        # eliminated).  Therefore if there *is* a close marker, getchanges()
+        # doesn't consider it significant, and this revision should be dropped.
+        return not files and 'close' not in self.commits[rev].extra
 
     def mark_not_wanted(self, rev, p):
         # Mark rev as not interesting and update data structures.
diff --git a/tests/test-convert-filemap.t b/tests/test-convert-filemap.t
--- a/tests/test-convert-filemap.t
+++ b/tests/test-convert-filemap.t
@@ -435,6 +435,32 @@  exercise incremental conversion at the s
   |
   o  0 "addb" files: b
   
+Include directives dropped empty commits, but other directives don't
+
+  $ cat > branchpruning/exclude_filemap <<EOF
+  > exclude a
+  > EOF
+  $ hg convert --filemap branchpruning/exclude_filemap branchpruning branchpruning-hg-exclude
+  initializing destination branchpruning-hg-exclude repository
+  scanning source...
+  sorting...
+  converting...
+  5 adda
+  4 closefoo
+  3 emptybranch
+  2 closeempty
+  1 addb
+  0 closedefault
+
+  $ glog -R branchpruning-hg-exclude
+  _  3 "closedefault" files:
+  |
+  o  2 "addb" files: b
+  
+  _  1 "closeempty" files:
+  |
+  o  0 "emptybranch" files:
+  
 
 Test rebuilding of map with unknown revisions in shamap - it used to crash
 
diff --git a/tests/test-lfconvert.t b/tests/test-lfconvert.t
--- a/tests/test-lfconvert.t
+++ b/tests/test-lfconvert.t
@@ -356,20 +356,27 @@  Avoid a traceback if a largefile isn't a
 Ensure the largefile can be cached in the source if necessary
   $ hg clone -U largefiles-repo issue3519
   $ rm -f "${USERCACHE}"/*
+  $ hg -R issue3519 branch -q mybranch
+  $ hg -R issue3519 ci -m 'change branch name only'
   $ hg lfconvert --to-normal issue3519 normalized3519
   initializing destination normalized3519
   4 additional largefiles cached
   scanning source...
   sorting...
   converting...
-  7 add large, normal1
-  6 add sub/*
-  5 rename sub/ to stuff/
-  4 add normal3, modify sub/*
-  3 remove large, normal3
-  2 merge
-  1 add anotherlarge (should be a largefile)
-  0 Added tag mytag for changeset abacddda7028
+  8 add large, normal1
+  7 add sub/*
+  6 rename sub/ to stuff/
+  5 add normal3, modify sub/*
+  4 remove large, normal3
+  3 merge
+  2 add anotherlarge (should be a largefile)
+  1 Added tag mytag for changeset abacddda7028
+  0 change branch name only
+
+Ensure empty commits aren't lost in the conversion
+  $ hg -R normalized3519 log -r tip -T '{desc}\n'
+  change branch name only
 
 Ensure the abort message is useful if a largefile is entirely unavailable
   $ rm -rf normalized3519