changeset 25601:3ec8351fa6ed

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.
author Matt Harbison <matt_harbison@yahoo.com>
date Tue, 16 Jun 2015 23:06:57 -0400
parents 70ac1868b707
children 85fb416f2fa7
files hgext/largefiles/overrides.py mercurial/archival.py mercurial/subrepo.py tests/test-subrepo-deep-nested-change.t
diffstat 4 files changed, 124 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/largefiles/overrides.py	Tue Jun 16 23:03:36 2015 -0400
+++ b/hgext/largefiles/overrides.py	Tue Jun 16 23:06:57 2015 -0400
@@ -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():
@@ -935,7 +941,7 @@
 
     if subrepos:
         for subpath in sorted(ctx.substate):
-            sub = ctx.sub(subpath)
+            sub = ctx.workingsub(subpath)
             submatch = match_.narrowmatcher(subpath, matchfn)
             sub.archive(archiver, prefix, submatch)
 
@@ -946,7 +952,8 @@
     rev = repo._state[1]
     ctx = repo._repo[rev]
 
-    lfcommands.cachelfiles(repo.ui, repo._repo, ctx.node())
+    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 +968,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():
@@ -982,7 +994,7 @@
         write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
 
     for subpath in sorted(ctx.substate):
-        sub = ctx.sub(subpath)
+        sub = ctx.workingsub(subpath)
         submatch = match_.narrowmatcher(subpath, match)
         sub.archive(archiver, prefix + repo._path + '/', submatch)
 
--- a/mercurial/archival.py	Tue Jun 16 23:03:36 2015 -0400
+++ b/mercurial/archival.py	Tue Jun 16 23:06:57 2015 -0400
@@ -315,7 +315,7 @@
 
     if subrepos:
         for subpath in sorted(ctx.substate):
-            sub = ctx.sub(subpath)
+            sub = ctx.workingsub(subpath)
             submatch = matchmod.narrowmatcher(subpath, matchfn)
             total += sub.archive(archiver, prefix, submatch)
 
--- a/mercurial/subrepo.py	Tue Jun 16 23:03:36 2015 -0400
+++ b/mercurial/subrepo.py	Tue Jun 16 23:06:57 2015 -0400
@@ -762,7 +762,7 @@
         rev = self._state[1]
         ctx = self._repo[rev]
         for subpath in ctx.substate:
-            s = subrepo(ctx, subpath)
+            s = subrepo(ctx, subpath, True)
             submatch = matchmod.narrowmatcher(subpath, match)
             total += s.archive(archiver, prefix + self._path + '/', submatch)
         return total
--- a/tests/test-subrepo-deep-nested-change.t	Tue Jun 16 23:03:36 2015 -0400
+++ b/tests/test-subrepo-deep-nested-change.t	Tue Jun 16 23:06:57 2015 -0400
@@ -168,6 +168,41 @@
   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
+
+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 +504,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