largefiles: make archive -S store largefiles instead of standins
authorMatt Harbison <matt_harbison@yahoo.com>
Thu, 03 May 2012 21:32:57 -0400
changeset 16578 43fb170a23bd
parent 16576 eab32ab5cd65
child 16579 1041a845f02d
largefiles: make archive -S store largefiles instead of standins This is essentially a copy of largefile's override of archive() in the archival class, adapted for overriding hgsubrepo's archive(). That means decoding isn't taken into consideration, nor is .hg_archival.txt generated (the same goes for regular subrepos). Unlike subrepos, but consistent with largefile's handling of the top repo, ui.progress() is *not* called. This should probably be refactored at some point, but at least this generates the archives properly for now. Previously, the standins were ignored and the largefiles were archived only for the top level repo. Long term, it would probably be most desirable to figure out how to tweak archival's archive() if necessary such that largefiles doesn't need to override it completely just to special case the translating of standins to the real files. Largefiles will already return a context with the true largefiles instead of the standins if lfilesrepo's lfstatus is True- perhaps this can be leveraged?
hgext/largefiles/overrides.py
hgext/largefiles/uisetup.py
tests/test-largefiles.t
--- a/hgext/largefiles/overrides.py	Thu May 03 16:12:52 2012 -0500
+++ b/hgext/largefiles/overrides.py	Thu May 03 21:32:57 2012 -0400
@@ -781,6 +781,47 @@
 
     archiver.done()
 
+def hgsubrepoarchive(orig, repo, ui, archiver, prefix):
+    rev = repo._state[1]
+    ctx = repo._repo[rev]
+
+    lfcommands.cachelfiles(ui, repo._repo, ctx.node())
+
+    def write(name, mode, islink, getdata):
+        if lfutil.isstandin(name):
+            return
+        data = getdata()
+
+        archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
+
+    for f in ctx:
+        ff = ctx.flags(f)
+        getdata = ctx[f].data
+        if lfutil.isstandin(f):
+            path = lfutil.findfile(repo._repo, getdata().strip())
+            if path is None:
+                raise util.Abort(
+                    _('largefile %s not found in repo store or system cache')
+                    % lfutil.splitstandin(f))
+            f = lfutil.splitstandin(f)
+
+            def getdatafn():
+                fd = None
+                try:
+                    fd = open(os.path.join(prefix, path), 'rb')
+                    return fd.read()
+                finally:
+                    if fd:
+                        fd.close()
+
+            getdata = getdatafn
+
+        write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
+
+    for subpath in ctx.substate:
+        sub = ctx.sub(subpath)
+        sub.archive(repo.ui, archiver, prefix)
+
 # If a largefile is modified, the change is not reflected in its
 # standin until a commit. cmdutil.bailifchanged() raises an exception
 # if the repo has uncommitted changes. Wrap it to also check if
--- a/hgext/largefiles/uisetup.py	Thu May 03 16:12:52 2012 -0500
+++ b/hgext/largefiles/uisetup.py	Thu May 03 21:32:57 2012 -0400
@@ -100,6 +100,7 @@
     extensions.wrapfunction(hg, 'merge', overrides.hgmerge)
 
     extensions.wrapfunction(archival, 'archive', overrides.overridearchive)
+    extensions.wrapfunction(hgsubrepo, 'archive', overrides.hgsubrepoarchive)
     extensions.wrapfunction(cmdutil, 'bailifchanged',
                             overrides.overridebailifchanged)
 
--- a/tests/test-largefiles.t	Thu May 03 16:12:52 2012 -0500
+++ b/tests/test-largefiles.t	Thu May 03 21:32:57 2012 -0400
@@ -1096,4 +1096,34 @@
   abort: uncommitted changes in subrepo subrepo
   (use --subrepos for recursive commit)
   [255]
+
+# Add a normal file to the subrepo, then test archiving
+  $ echo 'normal file' > subrepo/normal.txt
+  $ hg -R subrepo add subrepo/normal.txt
+# Lock in subrepo, otherwise the change isn't archived
+  $ hg ci -S -m "add normal file to top level"
+  committing subrepository subrepo
+  Invoking status precommit hook
+  M large.txt
+  A normal.txt
+  Invoking status precommit hook
+  M .hgsubstate
+  $ hg archive -S lf_subrepo_archive
+  $ find lf_subrepo_archive -print
+  lf_subrepo_archive
+  lf_subrepo_archive/.hg_archival.txt
+  lf_subrepo_archive/.hgsubstate
+  lf_subrepo_archive/subrepo
+  lf_subrepo_archive/subrepo/large.txt
+  lf_subrepo_archive/subrepo/normal.txt
+  lf_subrepo_archive/a
+  lf_subrepo_archive/a/b
+  lf_subrepo_archive/a/b/c
+  lf_subrepo_archive/a/b/c/d
+  lf_subrepo_archive/a/b/c/d/e.normal.txt
+  lf_subrepo_archive/a/b/c/d/e.large.txt
+  lf_subrepo_archive/a/b/c/x
+  lf_subrepo_archive/a/b/c/x/y.normal.txt
+  lf_subrepo_archive/.hgsub
+
   $ cd ..