subrepo: propagate matcher to subrepos when archiving
authorMatt Harbison <matt_harbison@yahoo.com>
Sat, 16 Jun 2012 22:34:06 -0400
changeset 17108 1894dac619de
parent 17107 dcac72c9efb2
child 17109 7ba2b9435da9
subrepo: propagate matcher to subrepos when archiving Add a match object to subrepo.archive(). This will allow the -X and -I options to be honored inside subrepos when archiving. They formerly only affect the top level repo.
hgext/largefiles/overrides.py
mercurial/archival.py
mercurial/subrepo.py
tests/test-subrepo-deep-nested-change.t
tests/test-subrepo-git.t
tests/test-subrepo-svn.t
--- a/hgext/largefiles/overrides.py	Mon Jun 18 22:45:21 2012 -0400
+++ b/hgext/largefiles/overrides.py	Sat Jun 16 22:34:06 2012 -0400
@@ -807,17 +807,22 @@
     if subrepos:
         for subpath in ctx.substate:
             sub = ctx.sub(subpath)
-            sub.archive(repo.ui, archiver, prefix)
+            submatch = match_.narrowmatcher(subpath, matchfn)
+            sub.archive(repo.ui, archiver, prefix, submatch)
 
     archiver.done()
 
-def hgsubrepoarchive(orig, repo, ui, archiver, prefix):
+def hgsubrepoarchive(orig, repo, ui, archiver, prefix, match=None):
     rev = repo._state[1]
     ctx = repo._repo[rev]
 
     lfcommands.cachelfiles(ui, repo._repo, ctx.node())
 
     def write(name, mode, islink, getdata):
+        # At this point, the standin has been replaced with the largefile name,
+        # so the normal matcher works here without the lfutil variants.
+        if match and not match(f):
+            return
         data = getdata()
 
         archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
@@ -848,7 +853,9 @@
 
     for subpath in ctx.substate:
         sub = ctx.sub(subpath)
-        sub.archive(ui, archiver, os.path.join(prefix, repo._path) + '/')
+        submatch = match_.narrowmatcher(subpath, match)
+        sub.archive(ui, archiver, os.path.join(prefix, repo._path) + '/',
+                    submatch)
 
 # If a largefile is modified, the change is not reflected in its
 # standin until a commit. cmdutil.bailifchanged() raises an exception
--- a/mercurial/archival.py	Mon Jun 18 22:45:21 2012 -0400
+++ b/mercurial/archival.py	Sat Jun 16 22:34:06 2012 -0400
@@ -7,6 +7,7 @@
 
 from i18n import _
 from node import hex
+import match as matchmod
 import cmdutil
 import scmutil, util, encoding
 import cStringIO, os, tarfile, time, zipfile
@@ -284,6 +285,7 @@
     if subrepos:
         for subpath in ctx.substate:
             sub = ctx.sub(subpath)
-            sub.archive(repo.ui, archiver, prefix)
+            submatch = matchmod.narrowmatcher(subpath, matchfn)
+            sub.archive(repo.ui, archiver, prefix, submatch)
 
     archiver.done()
--- a/mercurial/subrepo.py	Mon Jun 18 22:45:21 2012 -0400
+++ b/mercurial/subrepo.py	Sat Jun 16 22:34:06 2012 -0400
@@ -8,7 +8,7 @@
 import errno, os, re, xml.dom.minidom, shutil, posixpath
 import stat, subprocess, tarfile
 from i18n import _
-import config, scmutil, util, node, error, cmdutil, bookmarks
+import config, scmutil, util, node, error, cmdutil, bookmarks, match as matchmod
 hg = None
 propertycache = util.propertycache
 
@@ -351,8 +351,11 @@
         """return file flags"""
         return ''
 
-    def archive(self, ui, archiver, prefix):
-        files = self.files()
+    def archive(self, ui, archiver, prefix, match=None):
+        if match is not None:
+            files = [f for f in self.files() if match(f)]
+        else:
+            files = self.files()
         total = len(files)
         relpath = subrelpath(self)
         ui.progress(_('archiving (%s)') % relpath, 0,
@@ -445,15 +448,16 @@
             self._repo.ui.warn(_('warning: error "%s" in subrepository "%s"\n')
                                % (inst, subrelpath(self)))
 
-    def archive(self, ui, archiver, prefix):
+    def archive(self, ui, archiver, prefix, match=None):
         self._get(self._state + ('hg',))
-        abstractsubrepo.archive(self, ui, archiver, prefix)
+        abstractsubrepo.archive(self, ui, archiver, prefix, match)
 
         rev = self._state[1]
         ctx = self._repo[rev]
         for subpath in ctx.substate:
             s = subrepo(ctx, subpath)
-            s.archive(ui, archiver, os.path.join(prefix, self._path))
+            submatch = matchmod.narrowmatcher(subpath, match)
+            s.archive(ui, archiver, os.path.join(prefix, self._path), submatch)
 
     def dirty(self, ignoreupdate=False):
         r = self._state[1]
@@ -1205,7 +1209,7 @@
             else:
                 os.remove(path)
 
-    def archive(self, ui, archiver, prefix):
+    def archive(self, ui, archiver, prefix, match=None):
         source, revision = self._state
         if not revision:
             return
@@ -1221,6 +1225,8 @@
         for i, info in enumerate(tar):
             if info.isdir():
                 continue
+            if match and not match(info.name):
+                continue
             if info.issym():
                 data = info.linkname
             else:
--- a/tests/test-subrepo-deep-nested-change.t	Mon Jun 18 22:45:21 2012 -0400
+++ b/tests/test-subrepo-deep-nested-change.t	Sat Jun 16 22:34:06 2012 -0400
@@ -99,12 +99,64 @@
    source   ../sub2
    revision 53dd3430bcaf5ab4a7c48262bcad6d441f510487
 
+Check that deep archiving works
+ 
+  $ cd cloned
+  $ echo 'test' > sub1/sub2/test.txt
+  $ hg --config extensions.largefiles=! add sub1/sub2/test.txt
+  $ mkdir sub1/sub2/folder
+  $ echo 'subfolder' > sub1/sub2/folder/test.txt
+  $ hg --config extensions.largefiles=! add sub1/sub2/folder/test.txt
+  $ hg ci -Sm "add test.txt"
+  committing subrepository sub1
+  committing subrepository sub1/sub2
+  $ hg --config extensions.largefiles=! archive -S ../archive_all
+  $ find ../archive_all | sort
+  ../archive_all
+  ../archive_all/.hg_archival.txt
+  ../archive_all/.hgsub
+  ../archive_all/.hgsubstate
+  ../archive_all/main
+  ../archive_all/sub1
+  ../archive_all/sub1/.hgsub
+  ../archive_all/sub1/.hgsubstate
+  ../archive_all/sub1/sub1
+  ../archive_all/sub1/sub2
+  ../archive_all/sub1/sub2/folder
+  ../archive_all/sub1/sub2/folder/test.txt
+  ../archive_all/sub1/sub2/sub2
+  ../archive_all/sub1/sub2/test.txt
+
+Check that archive -X works in deep subrepos
+
+  $ hg --config extensions.largefiles=! archive -S -X '**test*' ../archive_exclude
+  $ find ../archive_exclude | sort
+  ../archive_exclude
+  ../archive_exclude/.hg_archival.txt
+  ../archive_exclude/.hgsub
+  ../archive_exclude/.hgsubstate
+  ../archive_exclude/main
+  ../archive_exclude/sub1
+  ../archive_exclude/sub1/.hgsub
+  ../archive_exclude/sub1/.hgsubstate
+  ../archive_exclude/sub1/sub1
+  ../archive_exclude/sub1/sub2
+  ../archive_exclude/sub1/sub2/sub2
+
+  $ hg --config extensions.largefiles=! archive -S -I '**test*' ../archive_include
+  $ find ../archive_include | sort
+  ../archive_include
+  ../archive_include/sub1
+  ../archive_include/sub1/sub2
+  ../archive_include/sub1/sub2/folder
+  ../archive_include/sub1/sub2/folder/test.txt
+  ../archive_include/sub1/sub2/test.txt
+
 Check that deep archive works with largefiles (which overrides hgsubrepo impl)
 This also tests the repo.ui regression in 43fb170a23bd, and that lf subrepo
 subrepos are archived properly.
 Note that add --large through a subrepo currently adds the file as a normal file
 
-  $ cd cloned
   $ echo "large" > sub1/sub2/large.bin
   $ hg --config extensions.largefiles= add --large -R sub1/sub2 sub1/sub2/large.bin
   $ echo "large" > large.bin
@@ -126,7 +178,88 @@
   ../archive_lf/sub1/.hgsubstate
   ../archive_lf/sub1/sub1
   ../archive_lf/sub1/sub2
+  ../archive_lf/sub1/sub2/folder
+  ../archive_lf/sub1/sub2/folder/test.txt
+  ../archive_lf/sub1/sub2/large.bin
+  ../archive_lf/sub1/sub2/sub2
+  ../archive_lf/sub1/sub2/test.txt
+  $ rm -rf ../archive_lf
+
+Exclude large files from main and sub-sub repo
+
+  $ hg --config extensions.largefiles= archive -S -X '**.bin' ../archive_lf
+  $ find ../archive_lf | sort
+  ../archive_lf
+  ../archive_lf/.hg_archival.txt
+  ../archive_lf/.hgsub
+  ../archive_lf/.hgsubstate
+  ../archive_lf/main
+  ../archive_lf/sub1
+  ../archive_lf/sub1/.hgsub
+  ../archive_lf/sub1/.hgsubstate
+  ../archive_lf/sub1/sub1
+  ../archive_lf/sub1/sub2
+  ../archive_lf/sub1/sub2/folder
+  ../archive_lf/sub1/sub2/folder/test.txt
+  ../archive_lf/sub1/sub2/sub2
+  ../archive_lf/sub1/sub2/test.txt
+  $ rm -rf ../archive_lf
+
+Exclude normal files from main and sub-sub repo
+
+  $ hg --config extensions.largefiles= archive -S -X '**.txt' ../archive_lf
+  $ find ../archive_lf | sort
+  ../archive_lf
+  ../archive_lf/.hgsub
+  ../archive_lf/.hgsubstate
+  ../archive_lf/large.bin
+  ../archive_lf/main
+  ../archive_lf/sub1
+  ../archive_lf/sub1/.hgsub
+  ../archive_lf/sub1/.hgsubstate
+  ../archive_lf/sub1/sub1
+  ../archive_lf/sub1/sub2
   ../archive_lf/sub1/sub2/large.bin
   ../archive_lf/sub1/sub2/sub2
+  $ rm -rf ../archive_lf
+
+Include normal files from within a largefiles subrepo
+
+  $ hg --config extensions.largefiles= archive -S -I '**.txt' ../archive_lf
+  $ find ../archive_lf | sort
+  ../archive_lf
+  ../archive_lf/.hg_archival.txt
+  ../archive_lf/sub1
+  ../archive_lf/sub1/sub2
+  ../archive_lf/sub1/sub2/folder
+  ../archive_lf/sub1/sub2/folder/test.txt
+  ../archive_lf/sub1/sub2/test.txt
+  $ rm -rf ../archive_lf
+
+Include large files from within a largefiles subrepo
+
+  $ hg --config extensions.largefiles= archive -S -I '**.bin' ../archive_lf
+  $ find ../archive_lf | sort
+  ../archive_lf
+  ../archive_lf/large.bin
+  ../archive_lf/sub1
+  ../archive_lf/sub1/sub2
+  ../archive_lf/sub1/sub2/large.bin
+  $ rm -rf ../archive_lf
+
+Find an exact largefile match in a largefiles subrepo
+
+  $ hg --config extensions.largefiles= archive -S -I 'sub1/sub2/large.bin' ../archive_lf
+  $ find ../archive_lf | sort
+  ../archive_lf
+  ../archive_lf/sub1
+  ../archive_lf/sub1/sub2
+  ../archive_lf/sub1/sub2/large.bin
+  $ rm -rf ../archive_lf
+
+Find an exact match to a standin (should archive nothing)
+  $ hg --config extensions.largefiles= archive -S -I 'sub/sub2/.hglf/large.bin' ../archive_lf
+  $ find ../archive_lf | sort
+  find: `../archive_lf': No such file or directory
 
   $ cd ..
--- a/tests/test-subrepo-git.t	Mon Jun 18 22:45:21 2012 -0400
+++ b/tests/test-subrepo-git.t	Sat Jun 16 22:34:06 2012 -0400
@@ -270,6 +270,16 @@
   gg
   ggg
 
+  $ hg -R ../tc archive --subrepo -r 5 -X ../tc/**f ../archive_x 2>/dev/null
+  $ find ../archive_x | sort
+  ../archive_x
+  ../archive_x/.hg_archival.txt
+  ../archive_x/.hgsub
+  ../archive_x/.hgsubstate
+  ../archive_x/a
+  ../archive_x/s
+  ../archive_x/s/g
+
 create nested repo
 
   $ cd ..
--- a/tests/test-subrepo-svn.t	Mon Jun 18 22:45:21 2012 -0400
+++ b/tests/test-subrepo-svn.t	Sat Jun 16 22:34:06 2012 -0400
@@ -550,6 +550,28 @@
   archiving (recreated): 0/1 files (0.00%)
   archiving (recreated): 1/1 files (100.00%)
 
+  $ hg archive -S ../archive-exclude --debug -X **old
+  archiving: 0/2 files (0.00%)
+  archiving: .hgsub 1/2 files (50.00%)
+  archiving: .hgsubstate 2/2 files (100.00%)
+  archiving (obstruct): 0/1 files (0.00%)
+  archiving (obstruct): 1/1 files (100.00%)
+  archiving (s): 0/2 files (0.00%)
+  archiving (s): 1/2 files (50.00%)
+  archiving (s): 2/2 files (100.00%)
+  archiving (recreated): 0 files
+  $ find ../archive-exclude | sort
+  ../archive-exclude
+  ../archive-exclude/.hg_archival.txt
+  ../archive-exclude/.hgsub
+  ../archive-exclude/.hgsubstate
+  ../archive-exclude/obstruct
+  ../archive-exclude/obstruct/other
+  ../archive-exclude/s
+  ../archive-exclude/s/alpha
+  ../archive-exclude/s/dir
+  ../archive-exclude/s/dir/epsilon.py
+
 Test forgetting files, not implemented in svn subrepo, used to
 traceback