Mercurial > hg
view tests/test-import-bypass.t @ 35098:66c5a8cf2868
lfs: import the Facebook git-lfs client extension
The purpose of this is the same as the built-in largefiles extension- to handle
huge files outside of the normal storage system, generally to keep the amount of
data cloned to a lower amount. There are several benefits of implementing the
git-lfs protocol, instead of using the largefiles extension:
- Bitbucket and Github support (and probably wider support in 3rd party
hosting sites in general). [1][2]
- The number of hg internals monkey patched are several orders of magnitude
lower, so it will be easier to reason about and maintain. Future commands
will likely just work, without requiring various wrappers.
- The "standin" files are only written to the filelog, not the disk. That
should avoid weird edge cases where the largefile and standin files get out
of sync. [3] It also avoids the occasional printing of the "hidden" standin
file in various messages.
- Filesets like size() will work, even if the file isn't present. (It always
says 41 bytes for largefiles, whether present or not.)
The only place that I see where largefiles comes out on top is that it works
with `hg serve` for simple sharing, without external infrastructure. Getting
lfs-test-server working was a hassle, and took awhile to figure out. Maybe we
can do something to make it work in the future.
Long term, I expect that this will be highly preferred over largefiles. But if
we are to recommend this to largefile users, there are some UI issues to
bikeshed. Until they are resolved, I've marked this experimental, and am not
putting a pointer to this in the largefiles help. The (non exhaustive) list of
issues I've seen so far are:
- It isn't sufficient to just enable the largefiles extension- you have to
explicitly add a file with --large before it will pay attention to the
configured sizes and patterns on future adds. The justification being that
once you use it, you're stuck with it. I've seen people confused by this,
and haven't liked it myself. But it's also saved me a few times. Should we
do something like have a specific enabling config setting that must be set
in the local repo config, so that enabling this extension in the user or
system hgrc doesn't silently start storing lfs files?
- The largefiles extension adds a repo requirement when the first largefile is
committed, so that the extension must always be enabled in the future. This
extension is not doing that, and since I only enabled it locally to avoid
infecting other repos, I got a cryptic error about missing flag processors
when I cloned. Is there no repo requirement due to shallow/narrow clone
considerations (or other future advanced things)?
- In the (small amount of) reading I've done about the git implementation, it
seems that the files and sizes are stored in a tracked .gitattributes file.
I think a tracked file for this would be extremely useful for consistency
across developers, but this kind of touches on the tracked hgrc file
proposal a few months back.
- The git client can specify file patterns, not just sizes.
- The largefiles extension has a cache directory in the local repo, but also a
system wide one. We should probably implement a system wide cache too, so
that multiple clones don't have to refetch the files from the server.
- Jun mentioned other missing features, like SSH authentication, gc, etc.
The code corresponds to c0492b73c7ef in hg-experimental. [4] The only tweaks
are to load the extension in the tests with 'lfs=' instead of
'lfs=$TESTDIR/../hgext3rd/lfs', change the import in the *.py test to hgext
(from hgext3rd), add the 'testedwith' declaration, and mark it experimental for
now. The infinite-push, p4fastimport, and remotefilelog tests were left behind.
The devel-warnings for unregistered config options are not corrected yet, nor
are the import check warnings.
[1] https://www.mercurial-scm.org/pipermail/mercurial/2017-November/050699.html
[2] https://bitbucket.org/site/master/issues/3843/largefiles-support-bb-3903
[3] https://bz.mercurial-scm.org/show_bug.cgi?id=5738
[4] https://bitbucket.org/facebook/hg-experimental
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Tue, 14 Nov 2017 00:06:23 -0500 |
parents | eb586ed5d8ce |
children | d667302b6ee1 |
line wrap: on
line source
$ echo "[extensions]" >> $HGRCPATH $ echo "purge=" >> $HGRCPATH $ shortlog() { > hg log -G --template '{rev}:{node|short} {author} {date|hgdate} - {branch} - {desc|firstline}\n' > } Test --bypass with other options $ hg init repo-options $ cd repo-options $ echo a > a $ hg ci -Am adda adding a $ echo a >> a $ hg branch foo marked working directory as branch foo (branches are permanent and global, did you want a bookmark?) $ hg ci -Am changea $ hg export . > ../test.diff $ hg up null 0 files updated, 0 files merged, 1 files removed, 0 files unresolved Test importing an existing revision (this also tests that "hg import" disallows combination of '--exact' and '--edit') $ hg import --bypass --exact --edit ../test.diff abort: cannot use --exact with --edit [255] $ hg import --bypass --exact ../test.diff applying ../test.diff $ shortlog o 1:4e322f7ce8e3 test 0 0 - foo - changea | o 0:07f494440405 test 0 0 - default - adda Test failure without --exact $ hg import --bypass ../test.diff applying ../test.diff unable to find 'a' for patching (use '--prefix' to apply patch relative to the current directory) abort: patch failed to apply [255] $ hg st $ shortlog o 1:4e322f7ce8e3 test 0 0 - foo - changea | o 0:07f494440405 test 0 0 - default - adda Test --user, --date and --message $ hg up 0 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg import --bypass --u test2 -d '1 0' -m patch2 ../test.diff applying ../test.diff $ cat .hg/last-message.txt patch2 (no-eol) $ shortlog o 2:2e127d1da504 test2 1 0 - default - patch2 | | o 1:4e322f7ce8e3 test 0 0 - foo - changea |/ @ 0:07f494440405 test 0 0 - default - adda $ hg rollback repository tip rolled back to revision 1 (undo import) Test --import-branch (this also tests that editor is not invoked for '--bypass', if the patch contains the commit message, regardless of '--edit') $ HGEDITOR=cat hg import --bypass --import-branch --edit ../test.diff applying ../test.diff $ shortlog o 1:4e322f7ce8e3 test 0 0 - foo - changea | @ 0:07f494440405 test 0 0 - default - adda $ hg rollback repository tip rolled back to revision 1 (undo import) Test --strip $ hg import --bypass --strip 0 - <<EOF > # HG changeset patch > # User test > # Date 0 0 > # Branch foo > # Node ID 4e322f7ce8e3e4203950eac9ece27bf7e45ffa6c > # Parent 07f4944404050f47db2e5c5071e0e84e7a27bba9 > changea > > diff -r 07f494440405 -r 4e322f7ce8e3 a > --- a Thu Jan 01 00:00:00 1970 +0000 > +++ a Thu Jan 01 00:00:00 1970 +0000 > @@ -1,1 +1,2 @@ > a > +a > EOF applying patch from stdin $ hg rollback repository tip rolled back to revision 1 (undo import) Test --strip with --bypass $ mkdir -p dir/dir2 $ echo bb > dir/dir2/b $ echo cc > dir/dir2/c $ echo d > dir/d $ hg ci -Am 'addabcd' adding dir/d adding dir/dir2/b adding dir/dir2/c $ shortlog @ 2:d805bc8236b6 test 0 0 - default - addabcd | | o 1:4e322f7ce8e3 test 0 0 - foo - changea |/ o 0:07f494440405 test 0 0 - default - adda $ hg import --bypass --strip 2 --prefix dir/ - <<EOF > # HG changeset patch > # User test > # Date 0 0 > # Branch foo > changeabcd > > diff --git a/foo/a b/foo/a > new file mode 100644 > --- /dev/null > +++ b/foo/a > @@ -0,0 +1 @@ > +a > diff --git a/foo/dir2/b b/foo/dir2/b2 > rename from foo/dir2/b > rename to foo/dir2/b2 > diff --git a/foo/dir2/c b/foo/dir2/c > --- a/foo/dir2/c > +++ b/foo/dir2/c > @@ -0,0 +1 @@ > +cc > diff --git a/foo/d b/foo/d > deleted file mode 100644 > --- a/foo/d > +++ /dev/null > @@ -1,1 +0,0 @@ > -d > EOF applying patch from stdin $ shortlog o 3:5bd46886ca3e test 0 0 - default - changeabcd | @ 2:d805bc8236b6 test 0 0 - default - addabcd | | o 1:4e322f7ce8e3 test 0 0 - foo - changea |/ o 0:07f494440405 test 0 0 - default - adda $ hg diff --change 3 --git diff --git a/dir/a b/dir/a new file mode 100644 --- /dev/null +++ b/dir/a @@ -0,0 +1,1 @@ +a diff --git a/dir/d b/dir/d deleted file mode 100644 --- a/dir/d +++ /dev/null @@ -1,1 +0,0 @@ -d diff --git a/dir/dir2/b b/dir/dir2/b2 rename from dir/dir2/b rename to dir/dir2/b2 diff --git a/dir/dir2/c b/dir/dir2/c --- a/dir/dir2/c +++ b/dir/dir2/c @@ -1,1 +1,2 @@ cc +cc $ hg -q --config extensions.strip= strip . Test unsupported combinations $ hg import --bypass --no-commit ../test.diff abort: cannot use --no-commit with --bypass [255] $ hg import --bypass --similarity 50 ../test.diff abort: cannot use --similarity with --bypass [255] $ hg import --exact --prefix dir/ ../test.diff abort: cannot use --exact with --prefix [255] Test commit editor (this also tests that editor is invoked, if the patch doesn't contain the commit message, regardless of '--edit') $ cat > ../test.diff <<EOF > diff -r 07f494440405 -r 4e322f7ce8e3 a > --- a/a Thu Jan 01 00:00:00 1970 +0000 > +++ b/a Thu Jan 01 00:00:00 1970 +0000 > @@ -1,1 +1,2 @@ > -a > +b > +c > EOF $ HGEDITOR=cat hg import --bypass ../test.diff applying ../test.diff HG: Enter commit message. Lines beginning with 'HG:' are removed. HG: Leave message empty to abort commit. HG: -- HG: user: test HG: branch 'default' HG: changed a abort: empty commit message [255] Test patch.eol is handled (this also tests that editor is not invoked for '--bypass', if the commit message is explicitly specified, regardless of '--edit') $ $PYTHON -c 'file("a", "wb").write("a\r\n")' $ hg ci -m makeacrlf $ HGEDITOR=cat hg import -m 'should fail because of eol' --edit --bypass ../test.diff applying ../test.diff patching file a Hunk #1 FAILED at 0 abort: patch failed to apply [255] $ hg --config patch.eol=auto import -d '0 0' -m 'test patch.eol' --bypass ../test.diff applying ../test.diff $ shortlog o 3:c606edafba99 test 0 0 - default - test patch.eol | @ 2:872023de769d test 0 0 - default - makeacrlf | | o 1:4e322f7ce8e3 test 0 0 - foo - changea |/ o 0:07f494440405 test 0 0 - default - adda Test applying multiple patches $ hg up -qC 0 $ echo e > e $ hg ci -Am adde adding e created new head $ hg export . > ../patch1.diff $ hg up -qC 1 $ echo f > f $ hg ci -Am addf adding f $ hg export . > ../patch2.diff $ cd .. $ hg clone -r1 repo-options repo-multi1 adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 1 files new changesets 07f494440405:4e322f7ce8e3 updating to branch foo 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd repo-multi1 $ hg up 0 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg import --bypass ../patch1.diff ../patch2.diff applying ../patch1.diff applying ../patch2.diff $ shortlog o 3:bc8ca3f8a7c4 test 0 0 - default - addf | o 2:16581080145e test 0 0 - default - adde | | o 1:4e322f7ce8e3 test 0 0 - foo - changea |/ @ 0:07f494440405 test 0 0 - default - adda Test applying multiple patches with --exact $ cd .. $ hg clone -r1 repo-options repo-multi2 adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 1 files new changesets 07f494440405:4e322f7ce8e3 updating to branch foo 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd repo-multi2 $ hg import --bypass --exact ../patch1.diff ../patch2.diff applying ../patch1.diff applying ../patch2.diff $ shortlog o 3:d60cb8989666 test 0 0 - foo - addf | | o 2:16581080145e test 0 0 - default - adde | | @ | 1:4e322f7ce8e3 test 0 0 - foo - changea |/ o 0:07f494440405 test 0 0 - default - adda $ cd .. Test avoiding editor invocation at applying the patch with --exact even if commit message is empty $ cd repo-options $ echo a >> a $ hg commit -m ' ' $ hg tip -T "{node}\n" 1b77bc7d1db9f0e7f1716d515b630516ab386c89 $ hg export -o ../empty-log.diff . $ hg update -q -C ".^1" $ hg --config extensions.strip= strip -q tip $ HGEDITOR=cat hg import --exact --bypass ../empty-log.diff applying ../empty-log.diff $ hg tip -T "{node}\n" 1b77bc7d1db9f0e7f1716d515b630516ab386c89 $ cd .. #if symlink execbit Test complicated patch with --exact $ hg init repo-exact $ cd repo-exact $ echo a > a $ echo c > c $ echo d > d $ echo e > e $ echo f > f $ chmod +x f $ ln -s c linkc $ hg ci -Am t adding a adding c adding d adding e adding f adding linkc $ hg cp a aa1 $ echo b >> a $ echo b > b $ hg add b $ hg cp a aa2 $ echo aa >> aa2 $ chmod +x e $ chmod -x f $ ln -s a linka $ hg rm d $ hg rm linkc $ hg mv c cc $ hg ci -m patch $ hg export --git . > ../test.diff $ hg up -C null 0 files updated, 0 files merged, 7 files removed, 0 files unresolved $ hg purge $ hg st $ hg import --bypass --exact ../test.diff applying ../test.diff The patch should have matched the exported revision and generated no additional data. If not, diff both heads to debug it. $ shortlog o 1:2978fd5c8aa4 test 0 0 - default - patch | o 0:a0e19e636a43 test 0 0 - default - t #endif $ cd ..