[PATCH 2 of 3] extdiff: use archiver to take snapshots of committed revisions

Matt Harbison mharbison72 at gmail.com
Wed Jul 15 23:11:10 CDT 2015


# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1342054131 14400
#      Wed Jul 11 20:48:51 2012 -0400
# Node ID 4b5fc72daaf25e1ab66d340688b9bcdb986a2903
# Parent  b1178603bb23e8ccfbbdc9832b3f144fc090f754
extdiff: use archiver to take snapshots of committed revisions

This is the last step before supporting extdiff -S.  It maintains the existing
behavior of diffing the largefile standins instead of the largefiles themselves.
Note however that the standins are not updated immediately upon modification, so
uncommitted largefile changes are ignored, as they previously were, even with
the diff command.

diff --git a/hgext/extdiff.py b/hgext/extdiff.py
--- a/hgext/extdiff.py
+++ b/hgext/extdiff.py
@@ -63,6 +63,7 @@
 from mercurial.i18n import _
 from mercurial.node import short, nullid
 from mercurial import cmdutil, scmutil, util, commands, encoding, filemerge
+from mercurial import archival
 import os, shlex, shutil, tempfile, re
 
 cmdtable = {}
@@ -84,33 +85,34 @@
         dirname = '%s.%s' % (dirname, short(node))
     base = os.path.join(tmproot, dirname)
     os.mkdir(base)
+    fns_and_mtime = []
+
     if node is not None:
         ui.note(_('making snapshot of %d files from rev %s\n') %
                 (len(files), short(node)))
     else:
         ui.note(_('making snapshot of %d files from working directory\n') %
             (len(files)))
-    wopener = scmutil.opener(base)
-    fns_and_mtime = []
-    ctx = repo[node]
-    for fn in sorted(files):
-        wfn = util.pconvert(fn)
-        if wfn not in ctx:
-            # File doesn't exist; could be a bogus modify
-            continue
-        ui.note('  %s\n' % wfn)
-        dest = os.path.join(base, wfn)
-        fctx = ctx[wfn]
-        data = repo.wwritedata(wfn, fctx.data())
-        if 'l' in fctx.flags():
-            wopener.symlink(data, wfn)
-        else:
-            wopener.write(wfn, data)
-            if 'x' in fctx.flags():
-                util.setflags(dest, False, True)
-        if node is None:
-            fns_and_mtime.append((dest, repo.wjoin(fn),
-                                  os.lstat(dest).st_mtime))
+
+    if files:
+        repo.ui.setconfig("ui", "archivemeta", False)
+
+        archival.archive(repo, base, node, 'files',
+                         matchfn=scmutil.matchfiles(repo, files))
+
+        ctx = repo[node]
+        for fn in sorted(files):
+            wfn = util.pconvert(fn)
+            if wfn not in ctx:
+                # File doesn't exist; could be a bogus modify
+                continue
+            ui.note('  %s\n' % wfn)
+
+            if node is None:
+                dest = os.path.join(base, wfn)
+
+                fns_and_mtime.append((dest, repo.wjoin(fn),
+                                      os.lstat(dest).st_mtime))
     return dirname, fns_and_mtime
 
 def dodiff(ui, repo, cmdline, pats, opts):
diff --git a/tests/test-largefiles-update.t b/tests/test-largefiles-update.t
--- a/tests/test-largefiles-update.t
+++ b/tests/test-largefiles-update.t
@@ -20,6 +20,20 @@
   $ echo 'large1 in #1' > large1
   $ echo 'normal1 in #1' > normal1
   $ hg commit -m '#1'
+  $ hg extdiff -r '.^' --config extensions.extdiff=
+  diff -Npru repo.0d9d9b8dc9a3/.hglf/large1 repo/.hglf/large1
+  --- repo.0d9d9b8dc9a3/.hglf/large1	* (glob)
+  +++ repo/.hglf/large1	* (glob)
+  @@ -1 +1 @@
+  -4669e532d5b2c093a78eca010077e708a071bb64
+  +58e24f733a964da346e2407a2bee99d9001184f5
+  diff -Npru repo.0d9d9b8dc9a3/normal1 repo/normal1
+  --- repo.0d9d9b8dc9a3/normal1	* (glob)
+  +++ repo/normal1	* (glob)
+  @@ -1 +1 @@
+  -normal1
+  +normal1 in #1
+  [1]
   $ hg update -q -C 0
   $ echo 'large2 in #2' > large2
   $ hg commit -m '#2'


More information about the Mercurial-devel mailing list