Show More
@@ -24,6 +24,10 b' Configs::' | |||
|
24 | 24 | |
|
25 | 25 | # how many times to retry before giving up on transferring an object |
|
26 | 26 | retry = 5 |
|
27 | ||
|
28 | # the local directory to store lfs files for sharing across local clones. | |
|
29 | # If not set, the cache is located in an OS specific cache location. | |
|
30 | usercache = /path/to/global/cache | |
|
27 | 31 | """ |
|
28 | 32 | |
|
29 | 33 | from __future__ import absolute_import |
@@ -62,6 +66,9 b' configitem = registrar.configitem(config' | |||
|
62 | 66 | configitem('lfs', 'url', |
|
63 | 67 | default=configitem.dynamicdefault, |
|
64 | 68 | ) |
|
69 | configitem('lfs', 'usercache', | |
|
70 | default=None, | |
|
71 | ) | |
|
65 | 72 | configitem('lfs', 'threshold', |
|
66 | 73 | default=None, |
|
67 | 74 | ) |
@@ -20,6 +20,8 b' from mercurial import (' | |||
|
20 | 20 | vfs as vfsmod, |
|
21 | 21 | ) |
|
22 | 22 | |
|
23 | from ..largefiles import lfutil | |
|
24 | ||
|
23 | 25 | # 64 bytes for SHA256 |
|
24 | 26 | _lfsre = re.compile(r'\A[a-f0-9]{64}\Z') |
|
25 | 27 | |
@@ -68,20 +70,29 b' class local(object):' | |||
|
68 | 70 | def __init__(self, repo): |
|
69 | 71 | fullpath = repo.svfs.join('lfs/objects') |
|
70 | 72 | self.vfs = lfsvfs(fullpath) |
|
73 | usercache = lfutil._usercachedir(repo.ui, 'lfs') | |
|
74 | self.cachevfs = lfsvfs(usercache) | |
|
71 | 75 | |
|
72 | 76 | def write(self, oid, data): |
|
73 | 77 | """Write blob to local blobstore.""" |
|
74 | 78 | with self.vfs(oid, 'wb', atomictemp=True) as fp: |
|
75 | 79 | fp.write(data) |
|
76 | 80 | |
|
81 | # XXX: should we verify the content of the cache, and hardlink back to | |
|
82 | # the local store on success, but truncate, write and link on failure? | |
|
83 | if not self.cachevfs.exists(oid): | |
|
84 | lfutil.link(self.vfs.join(oid), self.cachevfs.join(oid)) | |
|
85 | ||
|
77 | 86 | def read(self, oid): |
|
78 | 87 | """Read blob from local blobstore.""" |
|
88 | if not self.vfs.exists(oid): | |
|
89 | lfutil.link(self.cachevfs.join(oid), self.vfs.join(oid)) | |
|
79 | 90 | return self.vfs.read(oid) |
|
80 | 91 | |
|
81 | 92 | def has(self, oid): |
|
82 | 93 | """Returns True if the local blobstore contains the requested blob, |
|
83 | 94 | False otherwise.""" |
|
84 | return self.vfs.exists(oid) | |
|
95 | return self.cachevfs.exists(oid) or self.vfs.exists(oid) | |
|
85 | 96 | |
|
86 | 97 | class _gitlfsremote(object): |
|
87 | 98 |
@@ -1102,6 +1102,9 b' class Test(unittest.TestCase):' | |||
|
1102 | 1102 | hgrc.write(b'[largefiles]\n') |
|
1103 | 1103 | hgrc.write(b'usercache = %s\n' % |
|
1104 | 1104 | (os.path.join(self._testtmp, b'.cache/largefiles'))) |
|
1105 | hgrc.write(b'[lfs]\n') | |
|
1106 | hgrc.write(b'usercache = %s\n' % | |
|
1107 | (os.path.join(self._testtmp, b'.cache/lfs'))) | |
|
1105 | 1108 | hgrc.write(b'[web]\n') |
|
1106 | 1109 | hgrc.write(b'address = localhost\n') |
|
1107 | 1110 | hgrc.write(b'ipv6 = %s\n' % str(self._useipv6).encode('ascii')) |
@@ -5,6 +5,7 b' Create a repository:' | |||
|
5 | 5 | devel.default-date=0 0 |
|
6 | 6 | extensions.fsmonitor= (fsmonitor !) |
|
7 | 7 | largefiles.usercache=$TESTTMP/.cache/largefiles (glob) |
|
8 | lfs.usercache=$TESTTMP/.cache/lfs (glob) | |
|
8 | 9 | ui.slash=True |
|
9 | 10 | ui.interactive=False |
|
10 | 11 | ui.mergemarkers=detailed |
@@ -207,6 +207,7 b' check that local configs for the cached ' | |||
|
207 | 207 | devel.default-date=0 0 |
|
208 | 208 | extensions.fsmonitor= (fsmonitor !) |
|
209 | 209 | largefiles.usercache=$TESTTMP/.cache/largefiles |
|
210 | lfs.usercache=$TESTTMP/.cache/lfs | |
|
210 | 211 | ui.slash=True |
|
211 | 212 | ui.interactive=False |
|
212 | 213 | ui.mergemarkers=detailed |
@@ -53,6 +53,8 b'' | |||
|
53 | 53 | adding file changes |
|
54 | 54 | added 1 changesets with 1 changes to 1 files |
|
55 | 55 | |
|
56 | Clear the cache to force a download | |
|
57 | $ rm -rf `hg config lfs.usercache` | |
|
56 | 58 | $ cd ../repo2 |
|
57 | 59 | $ hg update tip -v |
|
58 | 60 | resolving manifests |
@@ -79,6 +81,8 b' When the server has some blobs already' | |||
|
79 | 81 | adding file changes |
|
80 | 82 | added 1 changesets with 3 changes to 3 files |
|
81 | 83 | |
|
84 | Clear the cache to force a download | |
|
85 | $ rm -rf `hg config lfs.usercache` | |
|
82 | 86 | $ hg --repo ../repo1 update tip -v |
|
83 | 87 | resolving manifests |
|
84 | 88 | getting b |
@@ -95,6 +99,7 b' Check error message when the remote miss' | |||
|
95 | 99 | $ echo FFFFF >> b |
|
96 | 100 | $ hg commit -m b b |
|
97 | 101 | $ rm -rf .hg/store/lfs |
|
102 | $ rm -rf `hg config lfs.usercache` | |
|
98 | 103 | $ hg update -C '.^' |
|
99 | 104 | abort: LFS server claims required objects do not exist: |
|
100 | 105 | 8e6ea5f6c066b44a0efa43bcce86aea73f17e6e23f0663df0251e7524e140a13! |
@@ -118,6 +123,7 b' Check error message when object does not' | |||
|
118 | 123 | size 6 |
|
119 | 124 | x-is-binary 0 |
|
120 | 125 | $ cd .. |
|
126 | $ rm -rf `hg config lfs.usercache` | |
|
121 | 127 |
$ |
|
122 | 128 | updating to branch default |
|
123 | 129 | abort: LFS server error. Remote object for file data/a.i not found:(.*)! (re) |
@@ -566,9 +566,9 b'' | |||
|
566 | 566 | repo: repo9 |
|
567 | 567 | repo: repo10 |
|
568 | 568 | |
|
569 |
|
|
|
570 | unpushed files from repo12's source instead of the remote store, where they | |
|
571 | don't exist. | |
|
569 | repo12 doesn't have any cached lfs files and its source never pushed its | |
|
570 | files. Therefore, the files don't exist in the remote store. Use the files in | |
|
571 | the user cache. | |
|
572 | 572 | |
|
573 | 573 | $ find $TESTTMP/repo12/.hg/store/lfs/objects -type f |
|
574 | 574 |
find |
@@ -576,24 +576,28 b" don't exist." | |||
|
576 | 576 | |
|
577 | 577 | $ hg --config extensions.share= share repo12 repo13 |
|
578 | 578 | updating working directory |
|
579 | abort: $TESTTMP/dummy-remote/09/66faba9a01f6c78082aa45899a4fef732002d0b26404e90093adf1e876ab8d: $ENOTDIR$ (glob) | |
|
580 | [255] | |
|
579 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
580 | $ hg -R repo13 -q verify | |
|
581 | ||
|
581 | 582 | $ hg clone repo12 repo14 |
|
582 | 583 | updating to branch default |
|
583 | abort: $TESTTMP/dummy-remote/09/66faba9a01f6c78082aa45899a4fef732002d0b26404e90093adf1e876ab8d: $ENOTDIR$ (glob) | |
|
584 | [255] | |
|
584 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
585 | $ hg -R repo14 -q verify | |
|
585 | 586 | |
|
586 |
|
|
|
587 |
|
|
|
588 |
|
|
|
587 | If the source repo doesn't have the blob (maybe it was pulled or cloned with | |
|
588 | --noupdate), the blob is still accessible via the global cache to send to the | |
|
589 | remote store. | |
|
589 | 590 | |
|
590 | 591 | $ rm -rf $TESTTMP/repo14/.hg/store/lfs |
|
591 | 592 | $ hg init repo15 |
|
592 | 593 | $ hg -R repo14 push repo15 |
|
593 | 594 | pushing to repo15 |
|
594 | 595 | searching for changes |
|
595 | abort: $TESTTMP/repo14/.hg/store/lfs/objects/1c/896a0adcf9262119f4a98216aaa5ca00a58b9a0ce848914a02f9cd876f65a3: $ENOTDIR$ (glob) | |
|
596 | [255] | |
|
596 | adding changesets | |
|
597 | adding manifests | |
|
598 | adding file changes | |
|
599 | added 3 changesets with 2 changes to 1 files | |
|
600 | $ hg -R repo14 -q verify | |
|
597 | 601 | |
|
598 | 602 | lfs -> normal -> lfs round trip conversions are possible. The threshold for the |
|
599 | 603 | lfs destination is specified here because it was originally listed in the local |
General Comments 0
You need to be logged in to leave comments.
Login now