[PATCH 1 of 2 RFC] extdiff: use archiver to take snapshots of committed revisions
Mathias De Maré
mathias.demare at gmail.com
Mon Feb 9 01:18:16 CST 2015
On Mon, Feb 9, 2015 at 5:01 AM, Matt Harbison <mharbison72 at gmail.com> wrote:
> # HG changeset patch
> # User Matt Harbison <matt_harbison at yahoo.com>
> # Date 1342054131 14400
> # Wed Jul 11 20:48:51 2012 -0400
> # Node ID 6abceaa1a49f82cebd3a4f141f69558e2bb3cec4
> # Parent ff5caa8dfd993680d9602ca6ebb14da9de10d5f4
> extdiff: use archiver to take snapshots of committed revisions
>
> [This is the proof of concept that Mathias asked for. The fix for file
> archiving from the internal API maybe should be a separate commit.]
>
Thanks! :-)
How do you want to proceed with this? Do you want to continue with these
patches yourself, or is it something you don't have time to continue with?
>
> There should be no visible functional differences, other than the largefile
> standins are no longer included in the non working copy snapshots. That's
> probably not a big deal, and proper largefile support can still be added.
> This
> is the first step to make -S work. The full (deep) working copy snapshot
> needs
> to be handled prior to that. This could probably be improved in the
> future by
> excluding .hgsub and .hgsubstate from status, since that is really just
> private
> bookkeeping info.
>
> 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 = {}
> @@ -80,31 +81,44 @@
> 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)))
> +
> + # Use archive to build the snapshot for committed nodes. (It
> aborts if
> + # the list is empty.)
> + if files:
> + repo.ui.setconfig("ui", "archivemeta", False)
> +
> + archival.archive(repo, base, node, 'files',
> + matchfn=scmutil.matchfiles(repo, files))
> 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:
> +
> + # TODO: Use filesystem routines to duplicate the relevant parts
> of the
> + # working directory instead of this (archive doesn't work
> for
> + # wctx). This will allow any subrepo type and largefiles
> to work
>
It looks like util.copyfile should be able to do this.
> + wopener = scmutil.opener(base)
> + 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
>
I've been wondering about this: what exactly does this bogus modify mean?
Is this still something that could happen, or a leftover from the past?
Could we ignore it and just copy all the relevant files without worrying
about this?
> + 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)
>
The checking of the flags will no longer be necessary if we can use
something like copyfile.
> +
> fns_and_mtime.append((dest, repo.wjoin(fn),
> os.lstat(dest).st_mtime))
> return dirname, fns_and_mtime
> diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
> --- a/hgext/largefiles/overrides.py
> +++ b/hgext/largefiles/overrides.py
> @@ -851,7 +851,7 @@
> repo._lfcommithooks.pop()
>
> def overridearchive(orig, repo, dest, node, kind, decode=True,
> matchfn=None,
> - prefix=None, mtime=None, subrepos=None):
> + 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)
> diff --git a/mercurial/archival.py b/mercurial/archival.py
> --- a/mercurial/archival.py
> +++ b/mercurial/archival.py
> @@ -230,7 +230,7 @@
> }
>
> def archive(repo, dest, node, kind, decode=True, matchfn=None,
> - prefix=None, mtime=None, subrepos=False):
> + prefix='', mtime=None, subrepos=False):
> '''create archive of repo as it was at node.
>
> dest can be name of directory, name of archive file, or file
> 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
> @@ -419,4 +419,47 @@
> A a.dat
> A a.txt
>
> + $ cat <<EOF >> $HGRCPATH
> + > [extdiff]
> + > cmd.falabala = echo
> + > opts.falabala = diffing
> + > EOF
> +
> +Interaction with extdiff, largefiles and subrepos
> +
> + $ hg --config extensions.extdiff= extdiff
> + diff -Npru cloned.6e907bf12afc/.hglf/a.dat cloned/.hglf/a.dat
> + --- cloned.6e907bf12afc/.hglf/a.dat 1970-01-01 00:00:00 +0000
> + +++ cloned/.hglf/a.dat * (glob)
> + @@ -0,0 +1 @@
> + +
> + [1]
> +
> + $ hg --config extensions.extdiff= extdiff -r .^
> + diff -Npru cloned.1f79fbad5d0f/.hglf/a.dat cloned/.hglf/a.dat
> + --- cloned.1f79fbad5d0f/.hglf/a.dat 1970-01-01 00:00:00 +0000
> + +++ cloned/.hglf/a.dat * (glob)
> + @@ -0,0 +1 @@
> + +
> + diff -Npru cloned.1f79fbad5d0f/.hglf/foo/bar/large.dat
> cloned/.hglf/foo/bar/large.dat
> + --- cloned.1f79fbad5d0f/.hglf/foo/bar/large.dat 1970-01-01
> 00:00:00 +0000
> + +++ cloned/.hglf/foo/bar/large.dat * (glob)
> + @@ -0,0 +1 @@
> + +2f6933b5ee0f5fdd823d9717d8729f3c2523811b
> + diff -Npru cloned.1f79fbad5d0f/foo/bar/abc cloned/foo/bar/abc
> + --- cloned.1f79fbad5d0f/foo/bar/abc * (glob)
> + +++ cloned/foo/bar/abc * (glob)
> + @@ -0,0 +1 @@
> + +changed
> + [1]
> +
> + $ hg --config extensions.extdiff= extdiff -r 0 -r .^
> + diff -Npru cloned.7f491f53a367/.hgsubstate
> cloned.1f79fbad5d0f/.hgsubstate
> + --- cloned.7f491f53a367/.hgsubstate * (glob)
> + +++ cloned.1f79fbad5d0f/.hgsubstate * (glob)
> + @@ -1 +1 @@
> + -fc3b4ce2696f7741438c79207583768f2ce6b0dd sub1
> + +7a36fa02b66e61f27f3d4a822809f159479b8ab2 sub1
> + [1]
> +
> $ cd ..
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://selenic.com/pipermail/mercurial-devel/attachments/20150209/35ea775e/attachment.html>
More information about the Mercurial-devel
mailing list