[PATCH 3 of 3] archive: support 'wdir()'

Matt Harbison mharbison72 at gmail.com
Sun Jun 14 23:28:59 CDT 2015


# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1434328768 14400
#      Sun Jun 14 20:39:28 2015 -0400
# Node ID 18d376a661ffabe8121ab5d57b245f4f347f8cd1
# Parent  f5f5e4ae488d9cae8111e9a212f647ed1430a019
archive: support 'wdir()'

This is a step toward replacing the extdiff internals with archive, in order to
support 'extdiff -S'.  Only Mercurial subrepos are supported for now.

If a file is missing from the filesystem, it is silently skipped.  Perhaps it
should warn, but it cannot abort when working with extdiff because deleting a
file is a legitimate diff.

diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -882,7 +882,8 @@
             prefix='', mtime=None, subrepos=None):
     # No need to lock because we are only reading history and
     # largefile caches, neither of which are modified.
-    lfcommands.cachelfiles(repo.ui, repo, node)
+    if node is not None:
+        lfcommands.cachelfiles(repo.ui, repo, node)
 
     if kind not in archival.archivers:
         raise util.Abort(_("unknown archive type '%s'") % kind)
@@ -914,11 +915,16 @@
         ff = ctx.flags(f)
         getdata = ctx[f].data
         if lfutil.isstandin(f):
-            path = lfutil.findfile(repo, getdata().strip())
-            if path is None:
-                raise util.Abort(
-                    _('largefile %s not found in repo store or system cache')
-                    % lfutil.splitstandin(f))
+            if node is not None:
+                path = lfutil.findfile(repo, getdata().strip())
+
+                if path is None:
+                    raise util.Abort(
+                       _('largefile %s not found in repo store or system cache')
+                       % lfutil.splitstandin(f))
+            else:
+                path = lfutil.splitstandin(f)
+
             f = lfutil.splitstandin(f)
 
             def getdatafn():
@@ -943,10 +949,10 @@
 
 def hgsubrepoarchive(orig, repo, archiver, prefix, match=None):
     repo._get(repo._state + ('hg',))
-    rev = repo._state[1]
-    ctx = repo._repo[rev]
 
-    lfcommands.cachelfiles(repo.ui, repo._repo, ctx.node())
+    ctx = repo._getctx()
+    if ctx.node() is not None:
+        lfcommands.cachelfiles(repo.ui, repo._repo, ctx.node())
 
     def write(name, mode, islink, getdata):
         # At this point, the standin has been replaced with the largefile name,
@@ -961,11 +967,16 @@
         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))
+            if ctx.node() is not None:
+                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))
+            else:
+                path = lfutil.splitstandin(f)
+
             f = lfutil.splitstandin(f)
 
             def getdatafn():
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -751,8 +751,8 @@
     def archive(self, archiver, prefix, match=None):
         self._get(self._state + ('hg',))
         total = abstractsubrepo.archive(self, archiver, prefix, match)
-        rev = self._state[1]
-        ctx = self._repo[rev]
+        ctx = self._getctx()
+
         for subpath in ctx.substate:
             s = subrepo(ctx, subpath)
             submatch = matchmod.narrowmatcher(subpath, match)
@@ -918,18 +918,13 @@
 
     @annotatesubrepoerror
     def files(self):
-        rev = self._state[1]
-        ctx = self._repo[rev]
-        return ctx.manifest().keys()
+        return self._getctx().manifest().keys()
 
     def filedata(self, name):
-        rev = self._state[1]
-        return self._repo[rev][name].data()
+        return self._getctx()[name].data()
 
     def fileflags(self, name):
-        rev = self._state[1]
-        ctx = self._repo[rev]
-        return ctx.flags(name)
+        return self._getctx().flags(name)
 
     @annotatesubrepoerror
     def printfiles(self, ui, m, fm, fmt, subrepos):
diff --git a/tests/test-subrepo-deep-nested-change.t b/tests/test-subrepo-deep-nested-change.t
--- a/tests/test-subrepo-deep-nested-change.t
+++ b/tests/test-subrepo-deep-nested-change.t
@@ -168,6 +168,49 @@
   A foo/bar/abc
   A sub1/foo
   R sub1/sub2/test.txt
+
+Archive wdir() with subrepos
+  $ hg rm main
+  $ hg archive -S -r 'wdir()' ../wdir
+  $ diff -r . ../wdir | grep -v '\.hg$'
+  Only in ../wdir: .hg_archival.txt
+
+  $ find ../wdir -type f | sort
+  ../wdir/.hg_archival.txt
+  ../wdir/.hgsub
+  ../wdir/.hgsubstate
+  ../wdir/foo/bar/abc
+  ../wdir/sub1/.hgsub
+  ../wdir/sub1/.hgsubstate
+  ../wdir/sub1/foo
+  ../wdir/sub1/sub1
+  ../wdir/sub1/sub2/folder/test.txt
+  ../wdir/sub1/sub2/sub2
+
+  $ cat ../wdir/.hg_archival.txt
+  repo: 7f491f53a367861f47ee64a80eb997d1f341b77a
+  node: 9bb10eebee29dc0f1201dcf5977b811a540255fd+
+  branch: default
+  latesttag: null
+  latesttagdistance: 4
+  changessincelatesttag: 3
+
+Attempting to archive 'wdir()' with a missing file is handled gracefully
+  $ rm sub1/sub1
+  $ rm -r ../wdir
+  $ hg archive -v -S -r 'wdir()' ../wdir
+  $ find ../wdir -type f | sort
+  ../wdir/.hg_archival.txt
+  ../wdir/.hgsub
+  ../wdir/.hgsubstate
+  ../wdir/foo/bar/abc
+  ../wdir/sub1/.hgsub
+  ../wdir/sub1/.hgsubstate
+  ../wdir/sub1/foo
+  ../wdir/sub1/sub2/folder/test.txt
+  ../wdir/sub1/sub2/sub2
+
+Continue relative path printing + subrepos
   $ hg update -Cq
   $ touch sub1/sub2/folder/bar
   $ hg addremove sub1/sub2
@@ -469,8 +512,69 @@
   ? sub1/sub2/untracked.txt
   ? sub1/sub2/x.txt
   $ hg add sub1/sub2
+
+  $ hg archive -S -r 'wdir()' ../wdir2
+  $ diff -r . ../wdir2 | grep -v '\.hg$'
+  Only in ../wdir2: .hg_archival.txt
+  Only in .: .hglf
+  Only in .: foo
+  Only in ./sub1/sub2: large.bin
+  Only in ./sub1/sub2: test.txt
+  Only in ./sub1/sub2: untracked.txt
+  Only in ./sub1/sub2: x.txt
+  $ find ../wdir2 -type f | sort
+  ../wdir2/.hg_archival.txt
+  ../wdir2/.hgsub
+  ../wdir2/.hgsubstate
+  ../wdir2/large.bin
+  ../wdir2/main
+  ../wdir2/sub1/.hgsub
+  ../wdir2/sub1/.hgsubstate
+  ../wdir2/sub1/sub1
+  ../wdir2/sub1/sub2/folder/test.txt
+  ../wdir2/sub1/sub2/large.dat
+  ../wdir2/sub1/sub2/sub2
+  $ hg status -S -mac -n | sort
+  .hgsub
+  .hgsubstate
+  large.bin
+  main
+  sub1/.hgsub
+  sub1/.hgsubstate
+  sub1/sub1
+  sub1/sub2/folder/test.txt
+  sub1/sub2/large.dat
+  sub1/sub2/sub2
+
   $ hg ci -Sqm 'forget testing'
 
+Test 'wdir()' modified file archiving with largefiles
+  $ echo 'mod' > main
+  $ echo 'mod' > large.bin
+  $ echo 'mod' > sub1/sub2/large.dat
+  $ hg archive -S -r 'wdir()' ../wdir3
+  $ diff -r . ../wdir3 | grep -v '\.hg$'
+  Only in ../wdir3: .hg_archival.txt
+  Only in .: .hglf
+  Only in .: foo
+  Only in ./sub1/sub2: large.bin
+  Only in ./sub1/sub2: test.txt
+  Only in ./sub1/sub2: untracked.txt
+  Only in ./sub1/sub2: x.txt
+  $ find ../wdir3 -type f | sort
+  ../wdir3/.hg_archival.txt
+  ../wdir3/.hgsub
+  ../wdir3/.hgsubstate
+  ../wdir3/large.bin
+  ../wdir3/main
+  ../wdir3/sub1/.hgsub
+  ../wdir3/sub1/.hgsubstate
+  ../wdir3/sub1/sub1
+  ../wdir3/sub1/sub2/folder/test.txt
+  ../wdir3/sub1/sub2/large.dat
+  ../wdir3/sub1/sub2/sub2
+  $ hg up -Cq
+
 Test issue4330: commit a directory where only normal files have changed
   $ touch foo/bar/large.dat
   $ hg add --large foo/bar/large.dat


More information about the Mercurial-devel mailing list