##// END OF EJS Templates
lfs: add the '{oid}' template keyword to '{lfs_files}'...
Matt Harbison -
r35676:a1222a8c default
parent child Browse files
Show More
@@ -1,245 +1,246 b''
1 # lfs - hash-preserving large file support using Git-LFS protocol
1 # lfs - hash-preserving large file support using Git-LFS protocol
2 #
2 #
3 # Copyright 2017 Facebook, Inc.
3 # Copyright 2017 Facebook, Inc.
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 """lfs - large file support (EXPERIMENTAL)
8 """lfs - large file support (EXPERIMENTAL)
9
9
10 Configs::
10 Configs::
11
11
12 [lfs]
12 [lfs]
13 # Remote endpoint. Multiple protocols are supported:
13 # Remote endpoint. Multiple protocols are supported:
14 # - http(s)://user:pass@example.com/path
14 # - http(s)://user:pass@example.com/path
15 # git-lfs endpoint
15 # git-lfs endpoint
16 # - file:///tmp/path
16 # - file:///tmp/path
17 # local filesystem, usually for testing
17 # local filesystem, usually for testing
18 # if unset, lfs will prompt setting this when it must use this value.
18 # if unset, lfs will prompt setting this when it must use this value.
19 # (default: unset)
19 # (default: unset)
20 url = https://example.com/lfs
20 url = https://example.com/lfs
21
21
22 # Which files to track in LFS. Path tests are "**.extname" for file
22 # Which files to track in LFS. Path tests are "**.extname" for file
23 # extensions, and "path:under/some/directory" for path prefix. Both
23 # extensions, and "path:under/some/directory" for path prefix. Both
24 # are relative to the repository root, and the latter must be quoted.
24 # are relative to the repository root, and the latter must be quoted.
25 # File size can be tested with the "size()" fileset, and tests can be
25 # File size can be tested with the "size()" fileset, and tests can be
26 # joined with fileset operators. (See "hg help filesets.operators".)
26 # joined with fileset operators. (See "hg help filesets.operators".)
27 #
27 #
28 # Some examples:
28 # Some examples:
29 # - all() # everything
29 # - all() # everything
30 # - none() # nothing
30 # - none() # nothing
31 # - size(">20MB") # larger than 20MB
31 # - size(">20MB") # larger than 20MB
32 # - !**.txt # anything not a *.txt file
32 # - !**.txt # anything not a *.txt file
33 # - **.zip | **.tar.gz | **.7z # some types of compressed files
33 # - **.zip | **.tar.gz | **.7z # some types of compressed files
34 # - "path:bin" # files under "bin" in the project root
34 # - "path:bin" # files under "bin" in the project root
35 # - (**.php & size(">2MB")) | (**.js & size(">5MB")) | **.tar.gz
35 # - (**.php & size(">2MB")) | (**.js & size(">5MB")) | **.tar.gz
36 # | ("path:bin" & !"path:/bin/README") | size(">1GB")
36 # | ("path:bin" & !"path:/bin/README") | size(">1GB")
37 # (default: none())
37 # (default: none())
38 track = size(">10M")
38 track = size(">10M")
39
39
40 # how many times to retry before giving up on transferring an object
40 # how many times to retry before giving up on transferring an object
41 retry = 5
41 retry = 5
42
42
43 # the local directory to store lfs files for sharing across local clones.
43 # the local directory to store lfs files for sharing across local clones.
44 # If not set, the cache is located in an OS specific cache location.
44 # If not set, the cache is located in an OS specific cache location.
45 usercache = /path/to/global/cache
45 usercache = /path/to/global/cache
46 """
46 """
47
47
48 from __future__ import absolute_import
48 from __future__ import absolute_import
49
49
50 from mercurial.i18n import _
50 from mercurial.i18n import _
51
51
52 from mercurial import (
52 from mercurial import (
53 bundle2,
53 bundle2,
54 changegroup,
54 changegroup,
55 context,
55 context,
56 exchange,
56 exchange,
57 extensions,
57 extensions,
58 filelog,
58 filelog,
59 fileset,
59 fileset,
60 hg,
60 hg,
61 localrepo,
61 localrepo,
62 minifileset,
62 minifileset,
63 node,
63 node,
64 pycompat,
64 pycompat,
65 registrar,
65 registrar,
66 revlog,
66 revlog,
67 scmutil,
67 scmutil,
68 templatekw,
68 templatekw,
69 upgrade,
69 upgrade,
70 vfs as vfsmod,
70 vfs as vfsmod,
71 wireproto,
71 wireproto,
72 )
72 )
73
73
74 from . import (
74 from . import (
75 blobstore,
75 blobstore,
76 wrapper,
76 wrapper,
77 )
77 )
78
78
79 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
79 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
80 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
80 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
81 # be specifying the version(s) of Mercurial they are tested with, or
81 # be specifying the version(s) of Mercurial they are tested with, or
82 # leave the attribute unspecified.
82 # leave the attribute unspecified.
83 testedwith = 'ships-with-hg-core'
83 testedwith = 'ships-with-hg-core'
84
84
85 configtable = {}
85 configtable = {}
86 configitem = registrar.configitem(configtable)
86 configitem = registrar.configitem(configtable)
87
87
88 configitem('experimental', 'lfs.user-agent',
88 configitem('experimental', 'lfs.user-agent',
89 default=None,
89 default=None,
90 )
90 )
91
91
92 configitem('lfs', 'url',
92 configitem('lfs', 'url',
93 default=None,
93 default=None,
94 )
94 )
95 configitem('lfs', 'usercache',
95 configitem('lfs', 'usercache',
96 default=None,
96 default=None,
97 )
97 )
98 # Deprecated
98 # Deprecated
99 configitem('lfs', 'threshold',
99 configitem('lfs', 'threshold',
100 default=None,
100 default=None,
101 )
101 )
102 configitem('lfs', 'track',
102 configitem('lfs', 'track',
103 default='none()',
103 default='none()',
104 )
104 )
105 configitem('lfs', 'retry',
105 configitem('lfs', 'retry',
106 default=5,
106 default=5,
107 )
107 )
108
108
109 cmdtable = {}
109 cmdtable = {}
110 command = registrar.command(cmdtable)
110 command = registrar.command(cmdtable)
111
111
112 templatekeyword = registrar.templatekeyword()
112 templatekeyword = registrar.templatekeyword()
113
113
114 def featuresetup(ui, supported):
114 def featuresetup(ui, supported):
115 # don't die on seeing a repo with the lfs requirement
115 # don't die on seeing a repo with the lfs requirement
116 supported |= {'lfs'}
116 supported |= {'lfs'}
117
117
118 def uisetup(ui):
118 def uisetup(ui):
119 localrepo.localrepository.featuresetupfuncs.add(featuresetup)
119 localrepo.localrepository.featuresetupfuncs.add(featuresetup)
120
120
121 def reposetup(ui, repo):
121 def reposetup(ui, repo):
122 # Nothing to do with a remote repo
122 # Nothing to do with a remote repo
123 if not repo.local():
123 if not repo.local():
124 return
124 return
125
125
126 trackspec = repo.ui.config('lfs', 'track')
126 trackspec = repo.ui.config('lfs', 'track')
127
127
128 # deprecated config: lfs.threshold
128 # deprecated config: lfs.threshold
129 threshold = repo.ui.configbytes('lfs', 'threshold')
129 threshold = repo.ui.configbytes('lfs', 'threshold')
130 if threshold:
130 if threshold:
131 fileset.parse(trackspec) # make sure syntax errors are confined
131 fileset.parse(trackspec) # make sure syntax errors are confined
132 trackspec = "(%s) | size('>%d')" % (trackspec, threshold)
132 trackspec = "(%s) | size('>%d')" % (trackspec, threshold)
133
133
134 repo.svfs.options['lfstrack'] = minifileset.compile(trackspec)
134 repo.svfs.options['lfstrack'] = minifileset.compile(trackspec)
135 repo.svfs.lfslocalblobstore = blobstore.local(repo)
135 repo.svfs.lfslocalblobstore = blobstore.local(repo)
136 repo.svfs.lfsremoteblobstore = blobstore.remote(repo)
136 repo.svfs.lfsremoteblobstore = blobstore.remote(repo)
137
137
138 # Push hook
138 # Push hook
139 repo.prepushoutgoinghooks.add('lfs', wrapper.prepush)
139 repo.prepushoutgoinghooks.add('lfs', wrapper.prepush)
140
140
141 if 'lfs' not in repo.requirements:
141 if 'lfs' not in repo.requirements:
142 def checkrequireslfs(ui, repo, **kwargs):
142 def checkrequireslfs(ui, repo, **kwargs):
143 if 'lfs' not in repo.requirements:
143 if 'lfs' not in repo.requirements:
144 last = kwargs.get('node_last')
144 last = kwargs.get('node_last')
145 _bin = node.bin
145 _bin = node.bin
146 if last:
146 if last:
147 s = repo.set('%n:%n', _bin(kwargs['node']), _bin(last))
147 s = repo.set('%n:%n', _bin(kwargs['node']), _bin(last))
148 else:
148 else:
149 s = repo.set('%n', _bin(kwargs['node']))
149 s = repo.set('%n', _bin(kwargs['node']))
150 for ctx in s:
150 for ctx in s:
151 # TODO: is there a way to just walk the files in the commit?
151 # TODO: is there a way to just walk the files in the commit?
152 if any(ctx[f].islfs() for f in ctx.files() if f in ctx):
152 if any(ctx[f].islfs() for f in ctx.files() if f in ctx):
153 repo.requirements.add('lfs')
153 repo.requirements.add('lfs')
154 repo._writerequirements()
154 repo._writerequirements()
155 break
155 break
156
156
157 ui.setconfig('hooks', 'commit.lfs', checkrequireslfs, 'lfs')
157 ui.setconfig('hooks', 'commit.lfs', checkrequireslfs, 'lfs')
158 ui.setconfig('hooks', 'pretxnchangegroup.lfs', checkrequireslfs, 'lfs')
158 ui.setconfig('hooks', 'pretxnchangegroup.lfs', checkrequireslfs, 'lfs')
159
159
160 def wrapfilelog(filelog):
160 def wrapfilelog(filelog):
161 wrapfunction = extensions.wrapfunction
161 wrapfunction = extensions.wrapfunction
162
162
163 wrapfunction(filelog, 'addrevision', wrapper.filelogaddrevision)
163 wrapfunction(filelog, 'addrevision', wrapper.filelogaddrevision)
164 wrapfunction(filelog, 'renamed', wrapper.filelogrenamed)
164 wrapfunction(filelog, 'renamed', wrapper.filelogrenamed)
165 wrapfunction(filelog, 'size', wrapper.filelogsize)
165 wrapfunction(filelog, 'size', wrapper.filelogsize)
166
166
167 def extsetup(ui):
167 def extsetup(ui):
168 wrapfilelog(filelog.filelog)
168 wrapfilelog(filelog.filelog)
169
169
170 wrapfunction = extensions.wrapfunction
170 wrapfunction = extensions.wrapfunction
171
171
172 wrapfunction(scmutil, 'wrapconvertsink', wrapper.convertsink)
172 wrapfunction(scmutil, 'wrapconvertsink', wrapper.convertsink)
173
173
174 wrapfunction(upgrade, '_finishdatamigration',
174 wrapfunction(upgrade, '_finishdatamigration',
175 wrapper.upgradefinishdatamigration)
175 wrapper.upgradefinishdatamigration)
176
176
177 wrapfunction(upgrade, 'preservedrequirements',
177 wrapfunction(upgrade, 'preservedrequirements',
178 wrapper.upgraderequirements)
178 wrapper.upgraderequirements)
179
179
180 wrapfunction(upgrade, 'supporteddestrequirements',
180 wrapfunction(upgrade, 'supporteddestrequirements',
181 wrapper.upgraderequirements)
181 wrapper.upgraderequirements)
182
182
183 wrapfunction(changegroup,
183 wrapfunction(changegroup,
184 'supportedoutgoingversions',
184 'supportedoutgoingversions',
185 wrapper.supportedoutgoingversions)
185 wrapper.supportedoutgoingversions)
186 wrapfunction(changegroup,
186 wrapfunction(changegroup,
187 'allsupportedversions',
187 'allsupportedversions',
188 wrapper.allsupportedversions)
188 wrapper.allsupportedversions)
189
189
190 wrapfunction(exchange, 'push', wrapper.push)
190 wrapfunction(exchange, 'push', wrapper.push)
191 wrapfunction(wireproto, '_capabilities', wrapper._capabilities)
191 wrapfunction(wireproto, '_capabilities', wrapper._capabilities)
192
192
193 wrapfunction(context.basefilectx, 'cmp', wrapper.filectxcmp)
193 wrapfunction(context.basefilectx, 'cmp', wrapper.filectxcmp)
194 wrapfunction(context.basefilectx, 'isbinary', wrapper.filectxisbinary)
194 wrapfunction(context.basefilectx, 'isbinary', wrapper.filectxisbinary)
195 context.basefilectx.islfs = wrapper.filectxislfs
195 context.basefilectx.islfs = wrapper.filectxislfs
196
196
197 revlog.addflagprocessor(
197 revlog.addflagprocessor(
198 revlog.REVIDX_EXTSTORED,
198 revlog.REVIDX_EXTSTORED,
199 (
199 (
200 wrapper.readfromstore,
200 wrapper.readfromstore,
201 wrapper.writetostore,
201 wrapper.writetostore,
202 wrapper.bypasscheckhash,
202 wrapper.bypasscheckhash,
203 ),
203 ),
204 )
204 )
205
205
206 wrapfunction(hg, 'clone', wrapper.hgclone)
206 wrapfunction(hg, 'clone', wrapper.hgclone)
207 wrapfunction(hg, 'postshare', wrapper.hgpostshare)
207 wrapfunction(hg, 'postshare', wrapper.hgpostshare)
208
208
209 # Make bundle choose changegroup3 instead of changegroup2. This affects
209 # Make bundle choose changegroup3 instead of changegroup2. This affects
210 # "hg bundle" command. Note: it does not cover all bundle formats like
210 # "hg bundle" command. Note: it does not cover all bundle formats like
211 # "packed1". Using "packed1" with lfs will likely cause trouble.
211 # "packed1". Using "packed1" with lfs will likely cause trouble.
212 names = [k for k, v in exchange._bundlespeccgversions.items() if v == '02']
212 names = [k for k, v in exchange._bundlespeccgversions.items() if v == '02']
213 for k in names:
213 for k in names:
214 exchange._bundlespeccgversions[k] = '03'
214 exchange._bundlespeccgversions[k] = '03'
215
215
216 # bundlerepo uses "vfsmod.readonlyvfs(othervfs)", we need to make sure lfs
216 # bundlerepo uses "vfsmod.readonlyvfs(othervfs)", we need to make sure lfs
217 # options and blob stores are passed from othervfs to the new readonlyvfs.
217 # options and blob stores are passed from othervfs to the new readonlyvfs.
218 wrapfunction(vfsmod.readonlyvfs, '__init__', wrapper.vfsinit)
218 wrapfunction(vfsmod.readonlyvfs, '__init__', wrapper.vfsinit)
219
219
220 # when writing a bundle via "hg bundle" command, upload related LFS blobs
220 # when writing a bundle via "hg bundle" command, upload related LFS blobs
221 wrapfunction(bundle2, 'writenewbundle', wrapper.writenewbundle)
221 wrapfunction(bundle2, 'writenewbundle', wrapper.writenewbundle)
222
222
223 @templatekeyword('lfs_files')
223 @templatekeyword('lfs_files')
224 def lfsfiles(repo, ctx, **args):
224 def lfsfiles(repo, ctx, **args):
225 """List of strings. LFS files added or modified by the changeset."""
225 """List of strings. LFS files added or modified by the changeset."""
226 args = pycompat.byteskwargs(args)
226 args = pycompat.byteskwargs(args)
227
227
228 pointers = wrapper.pointersfromctx(ctx) # {path: pointer}
228 pointers = wrapper.pointersfromctx(ctx) # {path: pointer}
229 files = sorted(pointers.keys())
229 files = sorted(pointers.keys())
230
230
231 makemap = lambda v: {
231 makemap = lambda v: {
232 'file': v,
232 'file': v,
233 'oid': pointers[v].oid(),
233 }
234 }
234
235
235 # TODO: make the separator ', '?
236 # TODO: make the separator ', '?
236 f = templatekw._showlist('lfs_file', files, args)
237 f = templatekw._showlist('lfs_file', files, args)
237 return templatekw._hybrid(f, files, makemap, pycompat.identity)
238 return templatekw._hybrid(f, files, makemap, pycompat.identity)
238
239
239 @command('debuglfsupload',
240 @command('debuglfsupload',
240 [('r', 'rev', [], _('upload large files introduced by REV'))])
241 [('r', 'rev', [], _('upload large files introduced by REV'))])
241 def debuglfsupload(ui, repo, **opts):
242 def debuglfsupload(ui, repo, **opts):
242 """upload lfs blobs added by the working copy parent or given revisions"""
243 """upload lfs blobs added by the working copy parent or given revisions"""
243 revs = opts.get('rev', [])
244 revs = opts.get('rev', [])
244 pointers = wrapper.extractpointers(repo, scmutil.revrange(repo, revs))
245 pointers = wrapper.extractpointers(repo, scmutil.revrange(repo, revs))
245 wrapper.uploadblobs(repo, pointers)
246 wrapper.uploadblobs(repo, pointers)
@@ -1,974 +1,975 b''
1 # Initial setup
1 # Initial setup
2
2
3 $ cat >> $HGRCPATH << EOF
3 $ cat >> $HGRCPATH << EOF
4 > [extensions]
4 > [extensions]
5 > lfs=
5 > lfs=
6 > [lfs]
6 > [lfs]
7 > # Test deprecated config
7 > # Test deprecated config
8 > threshold=1000B
8 > threshold=1000B
9 > EOF
9 > EOF
10
10
11 $ LONG=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
11 $ LONG=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
12
12
13 # Prepare server and enable extension
13 # Prepare server and enable extension
14 $ hg init server
14 $ hg init server
15 $ hg clone -q server client
15 $ hg clone -q server client
16 $ cd client
16 $ cd client
17
17
18 # Commit small file
18 # Commit small file
19 $ echo s > smallfile
19 $ echo s > smallfile
20 $ echo '**.py = LF' > .hgeol
20 $ echo '**.py = LF' > .hgeol
21 $ hg --config lfs.track='size(">1000B") | "path:.hgeol"' commit -Aqm "add small file"
21 $ hg --config lfs.track='size(">1000B") | "path:.hgeol"' commit -Aqm "add small file"
22 $ hg debugdata .hgeol 0
22 $ hg debugdata .hgeol 0
23 **.py = LF
23 **.py = LF
24
24
25 # Commit large file
25 # Commit large file
26 $ echo $LONG > largefile
26 $ echo $LONG > largefile
27 $ grep lfs .hg/requires
27 $ grep lfs .hg/requires
28 [1]
28 [1]
29 $ hg commit --traceback -Aqm "add large file"
29 $ hg commit --traceback -Aqm "add large file"
30 $ grep lfs .hg/requires
30 $ grep lfs .hg/requires
31 lfs
31 lfs
32
32
33 # Ensure metadata is stored
33 # Ensure metadata is stored
34 $ hg debugdata largefile 0
34 $ hg debugdata largefile 0
35 version https://git-lfs.github.com/spec/v1
35 version https://git-lfs.github.com/spec/v1
36 oid sha256:f11e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
36 oid sha256:f11e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
37 size 1501
37 size 1501
38 x-is-binary 0
38 x-is-binary 0
39
39
40 # Check the blobstore is populated
40 # Check the blobstore is populated
41 $ find .hg/store/lfs/objects | sort
41 $ find .hg/store/lfs/objects | sort
42 .hg/store/lfs/objects
42 .hg/store/lfs/objects
43 .hg/store/lfs/objects/f1
43 .hg/store/lfs/objects/f1
44 .hg/store/lfs/objects/f1/1e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
44 .hg/store/lfs/objects/f1/1e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
45
45
46 # Check the blob stored contains the actual contents of the file
46 # Check the blob stored contains the actual contents of the file
47 $ cat .hg/store/lfs/objects/f1/1e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
47 $ cat .hg/store/lfs/objects/f1/1e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
48 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
48 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
49
49
50 # Push changes to the server
50 # Push changes to the server
51
51
52 $ hg push
52 $ hg push
53 pushing to $TESTTMP/server
53 pushing to $TESTTMP/server
54 searching for changes
54 searching for changes
55 abort: lfs.url needs to be configured
55 abort: lfs.url needs to be configured
56 [255]
56 [255]
57
57
58 $ cat >> $HGRCPATH << EOF
58 $ cat >> $HGRCPATH << EOF
59 > [lfs]
59 > [lfs]
60 > url=file:$TESTTMP/dummy-remote/
60 > url=file:$TESTTMP/dummy-remote/
61 > EOF
61 > EOF
62
62
63 Push to a local non-lfs repo with the extension enabled will add the
63 Push to a local non-lfs repo with the extension enabled will add the
64 lfs requirement
64 lfs requirement
65
65
66 $ grep lfs $TESTTMP/server/.hg/requires
66 $ grep lfs $TESTTMP/server/.hg/requires
67 [1]
67 [1]
68 $ hg push -v | egrep -v '^(uncompressed| )'
68 $ hg push -v | egrep -v '^(uncompressed| )'
69 pushing to $TESTTMP/server
69 pushing to $TESTTMP/server
70 searching for changes
70 searching for changes
71 lfs: found f11e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b in the local lfs store
71 lfs: found f11e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b in the local lfs store
72 2 changesets found
72 2 changesets found
73 adding changesets
73 adding changesets
74 adding manifests
74 adding manifests
75 adding file changes
75 adding file changes
76 added 2 changesets with 3 changes to 3 files
76 added 2 changesets with 3 changes to 3 files
77 calling hook pretxnchangegroup.lfs: hgext.lfs.checkrequireslfs
77 calling hook pretxnchangegroup.lfs: hgext.lfs.checkrequireslfs
78 $ grep lfs $TESTTMP/server/.hg/requires
78 $ grep lfs $TESTTMP/server/.hg/requires
79 lfs
79 lfs
80
80
81 # Unknown URL scheme
81 # Unknown URL scheme
82
82
83 $ hg push --config lfs.url=ftp://foobar
83 $ hg push --config lfs.url=ftp://foobar
84 abort: lfs: unknown url scheme: ftp
84 abort: lfs: unknown url scheme: ftp
85 [255]
85 [255]
86
86
87 $ cd ../
87 $ cd ../
88
88
89 # Initialize new client (not cloning) and setup extension
89 # Initialize new client (not cloning) and setup extension
90 $ hg init client2
90 $ hg init client2
91 $ cd client2
91 $ cd client2
92 $ cat >> .hg/hgrc <<EOF
92 $ cat >> .hg/hgrc <<EOF
93 > [paths]
93 > [paths]
94 > default = $TESTTMP/server
94 > default = $TESTTMP/server
95 > EOF
95 > EOF
96
96
97 # Pull from server
97 # Pull from server
98
98
99 Pulling a local lfs repo into a local non-lfs repo with the extension
99 Pulling a local lfs repo into a local non-lfs repo with the extension
100 enabled adds the lfs requirement
100 enabled adds the lfs requirement
101
101
102 $ grep lfs .hg/requires $TESTTMP/server/.hg/requires
102 $ grep lfs .hg/requires $TESTTMP/server/.hg/requires
103 $TESTTMP/server/.hg/requires:lfs
103 $TESTTMP/server/.hg/requires:lfs
104 $ hg pull default
104 $ hg pull default
105 pulling from $TESTTMP/server
105 pulling from $TESTTMP/server
106 requesting all changes
106 requesting all changes
107 adding changesets
107 adding changesets
108 adding manifests
108 adding manifests
109 adding file changes
109 adding file changes
110 added 2 changesets with 3 changes to 3 files
110 added 2 changesets with 3 changes to 3 files
111 new changesets 0ead593177f7:b88141481348
111 new changesets 0ead593177f7:b88141481348
112 (run 'hg update' to get a working copy)
112 (run 'hg update' to get a working copy)
113 $ grep lfs .hg/requires $TESTTMP/server/.hg/requires
113 $ grep lfs .hg/requires $TESTTMP/server/.hg/requires
114 .hg/requires:lfs
114 .hg/requires:lfs
115 $TESTTMP/server/.hg/requires:lfs
115 $TESTTMP/server/.hg/requires:lfs
116
116
117 # Check the blobstore is not yet populated
117 # Check the blobstore is not yet populated
118 $ [ -d .hg/store/lfs/objects ]
118 $ [ -d .hg/store/lfs/objects ]
119 [1]
119 [1]
120
120
121 # Update to the last revision containing the large file
121 # Update to the last revision containing the large file
122 $ hg update
122 $ hg update
123 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
124
124
125 # Check the blobstore has been populated on update
125 # Check the blobstore has been populated on update
126 $ find .hg/store/lfs/objects | sort
126 $ find .hg/store/lfs/objects | sort
127 .hg/store/lfs/objects
127 .hg/store/lfs/objects
128 .hg/store/lfs/objects/f1
128 .hg/store/lfs/objects/f1
129 .hg/store/lfs/objects/f1/1e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
129 .hg/store/lfs/objects/f1/1e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
130
130
131 # Check the contents of the file are fetched from blobstore when requested
131 # Check the contents of the file are fetched from blobstore when requested
132 $ hg cat -r . largefile
132 $ hg cat -r . largefile
133 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
133 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
134
134
135 # Check the file has been copied in the working copy
135 # Check the file has been copied in the working copy
136 $ cat largefile
136 $ cat largefile
137 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
137 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
138
138
139 $ cd ..
139 $ cd ..
140
140
141 # Check rename, and switch between large and small files
141 # Check rename, and switch between large and small files
142
142
143 $ hg init repo3
143 $ hg init repo3
144 $ cd repo3
144 $ cd repo3
145 $ cat >> .hg/hgrc << EOF
145 $ cat >> .hg/hgrc << EOF
146 > [lfs]
146 > [lfs]
147 > track=size(">10B")
147 > track=size(">10B")
148 > EOF
148 > EOF
149
149
150 $ echo LONGER-THAN-TEN-BYTES-WILL-TRIGGER-LFS > large
150 $ echo LONGER-THAN-TEN-BYTES-WILL-TRIGGER-LFS > large
151 $ echo SHORTER > small
151 $ echo SHORTER > small
152 $ hg add . -q
152 $ hg add . -q
153 $ hg commit -m 'commit with lfs content'
153 $ hg commit -m 'commit with lfs content'
154
154
155 $ hg mv large l
155 $ hg mv large l
156 $ hg mv small s
156 $ hg mv small s
157 $ hg commit -m 'renames'
157 $ hg commit -m 'renames'
158
158
159 $ echo SHORT > l
159 $ echo SHORT > l
160 $ echo BECOME-LARGER-FROM-SHORTER > s
160 $ echo BECOME-LARGER-FROM-SHORTER > s
161 $ hg commit -m 'large to small, small to large'
161 $ hg commit -m 'large to small, small to large'
162
162
163 $ echo 1 >> l
163 $ echo 1 >> l
164 $ echo 2 >> s
164 $ echo 2 >> s
165 $ hg commit -m 'random modifications'
165 $ hg commit -m 'random modifications'
166
166
167 $ echo RESTORE-TO-BE-LARGE > l
167 $ echo RESTORE-TO-BE-LARGE > l
168 $ echo SHORTER > s
168 $ echo SHORTER > s
169 $ hg commit -m 'switch large and small again'
169 $ hg commit -m 'switch large and small again'
170
170
171 # Test lfs_files template
171 # Test lfs_files template
172
172
173 $ hg log -r 'all()' -T '{rev} {join(lfs_files, ", ")}\n'
173 $ hg log -r 'all()' -T '{rev} {join(lfs_files, ", ")}\n'
174 0 large
174 0 large
175 1 l
175 1 l
176 2 s
176 2 s
177 3 s
177 3 s
178 4 l
178 4 l
179
179
180 # Push and pull the above repo
180 # Push and pull the above repo
181
181
182 $ hg --cwd .. init repo4
182 $ hg --cwd .. init repo4
183 $ hg push ../repo4
183 $ hg push ../repo4
184 pushing to ../repo4
184 pushing to ../repo4
185 searching for changes
185 searching for changes
186 adding changesets
186 adding changesets
187 adding manifests
187 adding manifests
188 adding file changes
188 adding file changes
189 added 5 changesets with 10 changes to 4 files
189 added 5 changesets with 10 changes to 4 files
190
190
191 $ hg --cwd .. init repo5
191 $ hg --cwd .. init repo5
192 $ hg --cwd ../repo5 pull ../repo3
192 $ hg --cwd ../repo5 pull ../repo3
193 pulling from ../repo3
193 pulling from ../repo3
194 requesting all changes
194 requesting all changes
195 adding changesets
195 adding changesets
196 adding manifests
196 adding manifests
197 adding file changes
197 adding file changes
198 added 5 changesets with 10 changes to 4 files
198 added 5 changesets with 10 changes to 4 files
199 new changesets fd47a419c4f7:5adf850972b9
199 new changesets fd47a419c4f7:5adf850972b9
200 (run 'hg update' to get a working copy)
200 (run 'hg update' to get a working copy)
201
201
202 $ cd ..
202 $ cd ..
203
203
204 # Test clone
204 # Test clone
205
205
206 $ hg init repo6
206 $ hg init repo6
207 $ cd repo6
207 $ cd repo6
208 $ cat >> .hg/hgrc << EOF
208 $ cat >> .hg/hgrc << EOF
209 > [lfs]
209 > [lfs]
210 > track=size(">30B")
210 > track=size(">30B")
211 > EOF
211 > EOF
212
212
213 $ echo LARGE-BECAUSE-IT-IS-MORE-THAN-30-BYTES > large
213 $ echo LARGE-BECAUSE-IT-IS-MORE-THAN-30-BYTES > large
214 $ echo SMALL > small
214 $ echo SMALL > small
215 $ hg commit -Aqm 'create a lfs file' large small
215 $ hg commit -Aqm 'create a lfs file' large small
216 $ hg debuglfsupload -r 'all()' -v
216 $ hg debuglfsupload -r 'all()' -v
217 lfs: found 8e92251415339ae9b148c8da89ed5ec665905166a1ab11b09dca8fad83344738 in the local lfs store
217 lfs: found 8e92251415339ae9b148c8da89ed5ec665905166a1ab11b09dca8fad83344738 in the local lfs store
218
218
219 $ cd ..
219 $ cd ..
220
220
221 $ hg clone repo6 repo7
221 $ hg clone repo6 repo7
222 updating to branch default
222 updating to branch default
223 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
223 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
224 $ cd repo7
224 $ cd repo7
225 $ hg config extensions --debug | grep lfs
225 $ hg config extensions --debug | grep lfs
226 $TESTTMP/repo7/.hg/hgrc:*: extensions.lfs= (glob)
226 $TESTTMP/repo7/.hg/hgrc:*: extensions.lfs= (glob)
227 $ cat large
227 $ cat large
228 LARGE-BECAUSE-IT-IS-MORE-THAN-30-BYTES
228 LARGE-BECAUSE-IT-IS-MORE-THAN-30-BYTES
229 $ cat small
229 $ cat small
230 SMALL
230 SMALL
231
231
232 $ cd ..
232 $ cd ..
233
233
234 $ hg --config extensions.share= share repo7 sharedrepo
234 $ hg --config extensions.share= share repo7 sharedrepo
235 updating working directory
235 updating working directory
236 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
236 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
237 $ hg -R sharedrepo config extensions --debug | grep lfs
237 $ hg -R sharedrepo config extensions --debug | grep lfs
238 $TESTTMP/sharedrepo/.hg/hgrc:*: extensions.lfs= (glob)
238 $TESTTMP/sharedrepo/.hg/hgrc:*: extensions.lfs= (glob)
239
239
240 # Test rename and status
240 # Test rename and status
241
241
242 $ hg init repo8
242 $ hg init repo8
243 $ cd repo8
243 $ cd repo8
244 $ cat >> .hg/hgrc << EOF
244 $ cat >> .hg/hgrc << EOF
245 > [lfs]
245 > [lfs]
246 > track=size(">10B")
246 > track=size(">10B")
247 > EOF
247 > EOF
248
248
249 $ echo THIS-IS-LFS-BECAUSE-10-BYTES > a1
249 $ echo THIS-IS-LFS-BECAUSE-10-BYTES > a1
250 $ echo SMALL > a2
250 $ echo SMALL > a2
251 $ hg commit -m a -A a1 a2
251 $ hg commit -m a -A a1 a2
252 $ hg status
252 $ hg status
253 $ hg mv a1 b1
253 $ hg mv a1 b1
254 $ hg mv a2 a1
254 $ hg mv a2 a1
255 $ hg mv b1 a2
255 $ hg mv b1 a2
256 $ hg commit -m b
256 $ hg commit -m b
257 $ hg status
257 $ hg status
258 >>> with open('a2', 'wb') as f:
258 >>> with open('a2', 'wb') as f:
259 ... f.write(b'\1\nSTART-WITH-HG-FILELOG-METADATA')
259 ... f.write(b'\1\nSTART-WITH-HG-FILELOG-METADATA')
260 >>> with open('a1', 'wb') as f:
260 >>> with open('a1', 'wb') as f:
261 ... f.write(b'\1\nMETA\n')
261 ... f.write(b'\1\nMETA\n')
262 $ hg commit -m meta
262 $ hg commit -m meta
263 $ hg status
263 $ hg status
264 $ hg log -T '{rev}: {file_copies} | {file_dels} | {file_adds}\n'
264 $ hg log -T '{rev}: {file_copies} | {file_dels} | {file_adds}\n'
265 2: | |
265 2: | |
266 1: a1 (a2)a2 (a1) | |
266 1: a1 (a2)a2 (a1) | |
267 0: | | a1 a2
267 0: | | a1 a2
268
268
269 $ for n in a1 a2; do
269 $ for n in a1 a2; do
270 > for r in 0 1 2; do
270 > for r in 0 1 2; do
271 > printf '\n%s @ %s\n' $n $r
271 > printf '\n%s @ %s\n' $n $r
272 > hg debugdata $n $r
272 > hg debugdata $n $r
273 > done
273 > done
274 > done
274 > done
275
275
276 a1 @ 0
276 a1 @ 0
277 version https://git-lfs.github.com/spec/v1
277 version https://git-lfs.github.com/spec/v1
278 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
278 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
279 size 29
279 size 29
280 x-is-binary 0
280 x-is-binary 0
281
281
282 a1 @ 1
282 a1 @ 1
283 \x01 (esc)
283 \x01 (esc)
284 copy: a2
284 copy: a2
285 copyrev: 50470ad23cf937b1f4b9f80bfe54df38e65b50d9
285 copyrev: 50470ad23cf937b1f4b9f80bfe54df38e65b50d9
286 \x01 (esc)
286 \x01 (esc)
287 SMALL
287 SMALL
288
288
289 a1 @ 2
289 a1 @ 2
290 \x01 (esc)
290 \x01 (esc)
291 \x01 (esc)
291 \x01 (esc)
292 \x01 (esc)
292 \x01 (esc)
293 META
293 META
294
294
295 a2 @ 0
295 a2 @ 0
296 SMALL
296 SMALL
297
297
298 a2 @ 1
298 a2 @ 1
299 version https://git-lfs.github.com/spec/v1
299 version https://git-lfs.github.com/spec/v1
300 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
300 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
301 size 29
301 size 29
302 x-hg-copy a1
302 x-hg-copy a1
303 x-hg-copyrev be23af27908a582af43e5cda209a5a9b319de8d4
303 x-hg-copyrev be23af27908a582af43e5cda209a5a9b319de8d4
304 x-is-binary 0
304 x-is-binary 0
305
305
306 a2 @ 2
306 a2 @ 2
307 version https://git-lfs.github.com/spec/v1
307 version https://git-lfs.github.com/spec/v1
308 oid sha256:876dadc86a8542f9798048f2c47f51dbf8e4359aed883e8ec80c5db825f0d943
308 oid sha256:876dadc86a8542f9798048f2c47f51dbf8e4359aed883e8ec80c5db825f0d943
309 size 32
309 size 32
310 x-is-binary 0
310 x-is-binary 0
311
311
312 # Verify commit hashes include rename metadata
312 # Verify commit hashes include rename metadata
313
313
314 $ hg log -T '{rev}:{node|short} {desc}\n'
314 $ hg log -T '{rev}:{node|short} {desc}\n'
315 2:0fae949de7fa meta
315 2:0fae949de7fa meta
316 1:9cd6bdffdac0 b
316 1:9cd6bdffdac0 b
317 0:7f96794915f7 a
317 0:7f96794915f7 a
318
318
319 $ cd ..
319 $ cd ..
320
320
321 # Test bundle
321 # Test bundle
322
322
323 $ hg init repo9
323 $ hg init repo9
324 $ cd repo9
324 $ cd repo9
325 $ cat >> .hg/hgrc << EOF
325 $ cat >> .hg/hgrc << EOF
326 > [lfs]
326 > [lfs]
327 > track=size(">10B")
327 > track=size(">10B")
328 > [diff]
328 > [diff]
329 > git=1
329 > git=1
330 > EOF
330 > EOF
331
331
332 $ for i in 0 single two three 4; do
332 $ for i in 0 single two three 4; do
333 > echo 'THIS-IS-LFS-'$i > a
333 > echo 'THIS-IS-LFS-'$i > a
334 > hg commit -m a-$i -A a
334 > hg commit -m a-$i -A a
335 > done
335 > done
336
336
337 $ hg update 2 -q
337 $ hg update 2 -q
338 $ echo 'THIS-IS-LFS-2-CHILD' > a
338 $ echo 'THIS-IS-LFS-2-CHILD' > a
339 $ hg commit -m branching -q
339 $ hg commit -m branching -q
340
340
341 $ hg bundle --base 1 bundle.hg -v
341 $ hg bundle --base 1 bundle.hg -v
342 lfs: found 5ab7a3739a5feec94a562d070a14f36dba7cad17e5484a4a89eea8e5f3166888 in the local lfs store
342 lfs: found 5ab7a3739a5feec94a562d070a14f36dba7cad17e5484a4a89eea8e5f3166888 in the local lfs store
343 lfs: found a9c7d1cd6ce2b9bbdf46ed9a862845228717b921c089d0d42e3bcaed29eb612e in the local lfs store
343 lfs: found a9c7d1cd6ce2b9bbdf46ed9a862845228717b921c089d0d42e3bcaed29eb612e in the local lfs store
344 lfs: found f693890c49c409ec33673b71e53f297681f76c1166daf33b2ad7ebf8b1d3237e in the local lfs store
344 lfs: found f693890c49c409ec33673b71e53f297681f76c1166daf33b2ad7ebf8b1d3237e in the local lfs store
345 lfs: found fda198fea753eb66a252e9856915e1f5cddbe41723bd4b695ece2604ad3c9f75 in the local lfs store
345 lfs: found fda198fea753eb66a252e9856915e1f5cddbe41723bd4b695ece2604ad3c9f75 in the local lfs store
346 4 changesets found
346 4 changesets found
347 uncompressed size of bundle content:
347 uncompressed size of bundle content:
348 * (changelog) (glob)
348 * (changelog) (glob)
349 * (manifests) (glob)
349 * (manifests) (glob)
350 * a (glob)
350 * a (glob)
351 $ hg --config extensions.strip= strip -r 2 --no-backup --force -q
351 $ hg --config extensions.strip= strip -r 2 --no-backup --force -q
352 $ hg -R bundle.hg log -p -T '{rev} {desc}\n' a
352 $ hg -R bundle.hg log -p -T '{rev} {desc}\n' a
353 5 branching
353 5 branching
354 diff --git a/a b/a
354 diff --git a/a b/a
355 --- a/a
355 --- a/a
356 +++ b/a
356 +++ b/a
357 @@ -1,1 +1,1 @@
357 @@ -1,1 +1,1 @@
358 -THIS-IS-LFS-two
358 -THIS-IS-LFS-two
359 +THIS-IS-LFS-2-CHILD
359 +THIS-IS-LFS-2-CHILD
360
360
361 4 a-4
361 4 a-4
362 diff --git a/a b/a
362 diff --git a/a b/a
363 --- a/a
363 --- a/a
364 +++ b/a
364 +++ b/a
365 @@ -1,1 +1,1 @@
365 @@ -1,1 +1,1 @@
366 -THIS-IS-LFS-three
366 -THIS-IS-LFS-three
367 +THIS-IS-LFS-4
367 +THIS-IS-LFS-4
368
368
369 3 a-three
369 3 a-three
370 diff --git a/a b/a
370 diff --git a/a b/a
371 --- a/a
371 --- a/a
372 +++ b/a
372 +++ b/a
373 @@ -1,1 +1,1 @@
373 @@ -1,1 +1,1 @@
374 -THIS-IS-LFS-two
374 -THIS-IS-LFS-two
375 +THIS-IS-LFS-three
375 +THIS-IS-LFS-three
376
376
377 2 a-two
377 2 a-two
378 diff --git a/a b/a
378 diff --git a/a b/a
379 --- a/a
379 --- a/a
380 +++ b/a
380 +++ b/a
381 @@ -1,1 +1,1 @@
381 @@ -1,1 +1,1 @@
382 -THIS-IS-LFS-single
382 -THIS-IS-LFS-single
383 +THIS-IS-LFS-two
383 +THIS-IS-LFS-two
384
384
385 1 a-single
385 1 a-single
386 diff --git a/a b/a
386 diff --git a/a b/a
387 --- a/a
387 --- a/a
388 +++ b/a
388 +++ b/a
389 @@ -1,1 +1,1 @@
389 @@ -1,1 +1,1 @@
390 -THIS-IS-LFS-0
390 -THIS-IS-LFS-0
391 +THIS-IS-LFS-single
391 +THIS-IS-LFS-single
392
392
393 0 a-0
393 0 a-0
394 diff --git a/a b/a
394 diff --git a/a b/a
395 new file mode 100644
395 new file mode 100644
396 --- /dev/null
396 --- /dev/null
397 +++ b/a
397 +++ b/a
398 @@ -0,0 +1,1 @@
398 @@ -0,0 +1,1 @@
399 +THIS-IS-LFS-0
399 +THIS-IS-LFS-0
400
400
401 $ hg bundle -R bundle.hg --base 1 bundle-again.hg -q
401 $ hg bundle -R bundle.hg --base 1 bundle-again.hg -q
402 $ hg -R bundle-again.hg log -p -T '{rev} {desc}\n' a
402 $ hg -R bundle-again.hg log -p -T '{rev} {desc}\n' a
403 5 branching
403 5 branching
404 diff --git a/a b/a
404 diff --git a/a b/a
405 --- a/a
405 --- a/a
406 +++ b/a
406 +++ b/a
407 @@ -1,1 +1,1 @@
407 @@ -1,1 +1,1 @@
408 -THIS-IS-LFS-two
408 -THIS-IS-LFS-two
409 +THIS-IS-LFS-2-CHILD
409 +THIS-IS-LFS-2-CHILD
410
410
411 4 a-4
411 4 a-4
412 diff --git a/a b/a
412 diff --git a/a b/a
413 --- a/a
413 --- a/a
414 +++ b/a
414 +++ b/a
415 @@ -1,1 +1,1 @@
415 @@ -1,1 +1,1 @@
416 -THIS-IS-LFS-three
416 -THIS-IS-LFS-three
417 +THIS-IS-LFS-4
417 +THIS-IS-LFS-4
418
418
419 3 a-three
419 3 a-three
420 diff --git a/a b/a
420 diff --git a/a b/a
421 --- a/a
421 --- a/a
422 +++ b/a
422 +++ b/a
423 @@ -1,1 +1,1 @@
423 @@ -1,1 +1,1 @@
424 -THIS-IS-LFS-two
424 -THIS-IS-LFS-two
425 +THIS-IS-LFS-three
425 +THIS-IS-LFS-three
426
426
427 2 a-two
427 2 a-two
428 diff --git a/a b/a
428 diff --git a/a b/a
429 --- a/a
429 --- a/a
430 +++ b/a
430 +++ b/a
431 @@ -1,1 +1,1 @@
431 @@ -1,1 +1,1 @@
432 -THIS-IS-LFS-single
432 -THIS-IS-LFS-single
433 +THIS-IS-LFS-two
433 +THIS-IS-LFS-two
434
434
435 1 a-single
435 1 a-single
436 diff --git a/a b/a
436 diff --git a/a b/a
437 --- a/a
437 --- a/a
438 +++ b/a
438 +++ b/a
439 @@ -1,1 +1,1 @@
439 @@ -1,1 +1,1 @@
440 -THIS-IS-LFS-0
440 -THIS-IS-LFS-0
441 +THIS-IS-LFS-single
441 +THIS-IS-LFS-single
442
442
443 0 a-0
443 0 a-0
444 diff --git a/a b/a
444 diff --git a/a b/a
445 new file mode 100644
445 new file mode 100644
446 --- /dev/null
446 --- /dev/null
447 +++ b/a
447 +++ b/a
448 @@ -0,0 +1,1 @@
448 @@ -0,0 +1,1 @@
449 +THIS-IS-LFS-0
449 +THIS-IS-LFS-0
450
450
451 $ cd ..
451 $ cd ..
452
452
453 # Test isbinary
453 # Test isbinary
454
454
455 $ hg init repo10
455 $ hg init repo10
456 $ cd repo10
456 $ cd repo10
457 $ cat >> .hg/hgrc << EOF
457 $ cat >> .hg/hgrc << EOF
458 > [extensions]
458 > [extensions]
459 > lfs=
459 > lfs=
460 > [lfs]
460 > [lfs]
461 > track=all()
461 > track=all()
462 > EOF
462 > EOF
463 $ $PYTHON <<'EOF'
463 $ $PYTHON <<'EOF'
464 > def write(path, content):
464 > def write(path, content):
465 > with open(path, 'wb') as f:
465 > with open(path, 'wb') as f:
466 > f.write(content)
466 > f.write(content)
467 > write('a', b'\0\0')
467 > write('a', b'\0\0')
468 > write('b', b'\1\n')
468 > write('b', b'\1\n')
469 > write('c', b'\1\n\0')
469 > write('c', b'\1\n\0')
470 > write('d', b'xx')
470 > write('d', b'xx')
471 > EOF
471 > EOF
472 $ hg add a b c d
472 $ hg add a b c d
473 $ hg diff --stat
473 $ hg diff --stat
474 a | Bin
474 a | Bin
475 b | 1 +
475 b | 1 +
476 c | Bin
476 c | Bin
477 d | 1 +
477 d | 1 +
478 4 files changed, 2 insertions(+), 0 deletions(-)
478 4 files changed, 2 insertions(+), 0 deletions(-)
479 $ hg commit -m binarytest
479 $ hg commit -m binarytest
480 $ cat > $TESTTMP/dumpbinary.py << EOF
480 $ cat > $TESTTMP/dumpbinary.py << EOF
481 > def reposetup(ui, repo):
481 > def reposetup(ui, repo):
482 > for n in 'abcd':
482 > for n in 'abcd':
483 > ui.write(('%s: binary=%s\n') % (n, repo['.'][n].isbinary()))
483 > ui.write(('%s: binary=%s\n') % (n, repo['.'][n].isbinary()))
484 > EOF
484 > EOF
485 $ hg --config extensions.dumpbinary=$TESTTMP/dumpbinary.py id --trace
485 $ hg --config extensions.dumpbinary=$TESTTMP/dumpbinary.py id --trace
486 a: binary=True
486 a: binary=True
487 b: binary=False
487 b: binary=False
488 c: binary=True
488 c: binary=True
489 d: binary=False
489 d: binary=False
490 b55353847f02 tip
490 b55353847f02 tip
491
491
492 $ cd ..
492 $ cd ..
493
493
494 # Test fctx.cmp fastpath - diff without LFS blobs
494 # Test fctx.cmp fastpath - diff without LFS blobs
495
495
496 $ hg init repo12
496 $ hg init repo12
497 $ cd repo12
497 $ cd repo12
498 $ cat >> .hg/hgrc <<EOF
498 $ cat >> .hg/hgrc <<EOF
499 > [lfs]
499 > [lfs]
500 > threshold=1
500 > threshold=1
501 > EOF
501 > EOF
502 $ cat > ../patch.diff <<EOF
502 $ cat > ../patch.diff <<EOF
503 > # HG changeset patch
503 > # HG changeset patch
504 > 2
504 > 2
505 >
505 >
506 > diff --git a/a b/a
506 > diff --git a/a b/a
507 > old mode 100644
507 > old mode 100644
508 > new mode 100755
508 > new mode 100755
509 > EOF
509 > EOF
510
510
511 $ for i in 1 2 3; do
511 $ for i in 1 2 3; do
512 > cp ../repo10/a a
512 > cp ../repo10/a a
513 > if [ $i = 3 ]; then
513 > if [ $i = 3 ]; then
514 > # make a content-only change
514 > # make a content-only change
515 > hg import -q --bypass ../patch.diff
515 > hg import -q --bypass ../patch.diff
516 > hg update -q
516 > hg update -q
517 > rm ../patch.diff
517 > rm ../patch.diff
518 > else
518 > else
519 > echo $i >> a
519 > echo $i >> a
520 > hg commit -m $i -A a
520 > hg commit -m $i -A a
521 > fi
521 > fi
522 > done
522 > done
523 $ [ -d .hg/store/lfs/objects ]
523 $ [ -d .hg/store/lfs/objects ]
524
524
525 $ cd ..
525 $ cd ..
526
526
527 $ hg clone repo12 repo13 --noupdate
527 $ hg clone repo12 repo13 --noupdate
528 $ cd repo13
528 $ cd repo13
529 $ hg log --removed -p a -T '{desc}\n' --config diff.nobinary=1 --git
529 $ hg log --removed -p a -T '{desc}\n' --config diff.nobinary=1 --git
530 2
530 2
531 diff --git a/a b/a
531 diff --git a/a b/a
532 old mode 100644
532 old mode 100644
533 new mode 100755
533 new mode 100755
534
534
535 2
535 2
536 diff --git a/a b/a
536 diff --git a/a b/a
537 Binary file a has changed
537 Binary file a has changed
538
538
539 1
539 1
540 diff --git a/a b/a
540 diff --git a/a b/a
541 new file mode 100644
541 new file mode 100644
542 Binary file a has changed
542 Binary file a has changed
543
543
544 $ [ -d .hg/store/lfs/objects ]
544 $ [ -d .hg/store/lfs/objects ]
545 [1]
545 [1]
546
546
547 $ cd ..
547 $ cd ..
548
548
549 # Test filter
549 # Test filter
550
550
551 $ hg init repo11
551 $ hg init repo11
552 $ cd repo11
552 $ cd repo11
553 $ cat >> .hg/hgrc << EOF
553 $ cat >> .hg/hgrc << EOF
554 > [lfs]
554 > [lfs]
555 > track=(**.a & size(">5B")) | (**.b & !size(">5B"))
555 > track=(**.a & size(">5B")) | (**.b & !size(">5B"))
556 > | (**.c & "path:d" & !"path:d/c.c") | size(">10B")
556 > | (**.c & "path:d" & !"path:d/c.c") | size(">10B")
557 > EOF
557 > EOF
558
558
559 $ mkdir a
559 $ mkdir a
560 $ echo aaaaaa > a/1.a
560 $ echo aaaaaa > a/1.a
561 $ echo a > a/2.a
561 $ echo a > a/2.a
562 $ echo aaaaaa > 1.b
562 $ echo aaaaaa > 1.b
563 $ echo a > 2.b
563 $ echo a > 2.b
564 $ echo a > 1.c
564 $ echo a > 1.c
565 $ mkdir d
565 $ mkdir d
566 $ echo a > d/c.c
566 $ echo a > d/c.c
567 $ echo a > d/d.c
567 $ echo a > d/d.c
568 $ echo aaaaaaaaaaaa > x
568 $ echo aaaaaaaaaaaa > x
569 $ hg add . -q
569 $ hg add . -q
570 $ hg commit -m files
570 $ hg commit -m files
571
571
572 $ for p in a/1.a a/2.a 1.b 2.b 1.c d/c.c d/d.c x; do
572 $ for p in a/1.a a/2.a 1.b 2.b 1.c d/c.c d/d.c x; do
573 > if hg debugdata $p 0 2>&1 | grep git-lfs >/dev/null; then
573 > if hg debugdata $p 0 2>&1 | grep git-lfs >/dev/null; then
574 > echo "${p}: is lfs"
574 > echo "${p}: is lfs"
575 > else
575 > else
576 > echo "${p}: not lfs"
576 > echo "${p}: not lfs"
577 > fi
577 > fi
578 > done
578 > done
579 a/1.a: is lfs
579 a/1.a: is lfs
580 a/2.a: not lfs
580 a/2.a: not lfs
581 1.b: not lfs
581 1.b: not lfs
582 2.b: is lfs
582 2.b: is lfs
583 1.c: not lfs
583 1.c: not lfs
584 d/c.c: not lfs
584 d/c.c: not lfs
585 d/d.c: is lfs
585 d/d.c: is lfs
586 x: is lfs
586 x: is lfs
587
587
588 $ cd ..
588 $ cd ..
589
589
590 # Verify the repos
590 # Verify the repos
591
591
592 $ cat > $TESTTMP/dumpflog.py << EOF
592 $ cat > $TESTTMP/dumpflog.py << EOF
593 > # print raw revision sizes, flags, and hashes for certain files
593 > # print raw revision sizes, flags, and hashes for certain files
594 > import hashlib
594 > import hashlib
595 > from mercurial import revlog
595 > from mercurial import revlog
596 > from mercurial.node import short
596 > from mercurial.node import short
597 > def hash(rawtext):
597 > def hash(rawtext):
598 > h = hashlib.sha512()
598 > h = hashlib.sha512()
599 > h.update(rawtext)
599 > h.update(rawtext)
600 > return h.hexdigest()[:4]
600 > return h.hexdigest()[:4]
601 > def reposetup(ui, repo):
601 > def reposetup(ui, repo):
602 > # these 2 files are interesting
602 > # these 2 files are interesting
603 > for name in ['l', 's']:
603 > for name in ['l', 's']:
604 > fl = repo.file(name)
604 > fl = repo.file(name)
605 > if len(fl) == 0:
605 > if len(fl) == 0:
606 > continue
606 > continue
607 > sizes = [revlog.revlog.rawsize(fl, i) for i in fl]
607 > sizes = [revlog.revlog.rawsize(fl, i) for i in fl]
608 > texts = [fl.revision(i, raw=True) for i in fl]
608 > texts = [fl.revision(i, raw=True) for i in fl]
609 > flags = [int(fl.flags(i)) for i in fl]
609 > flags = [int(fl.flags(i)) for i in fl]
610 > hashes = [hash(t) for t in texts]
610 > hashes = [hash(t) for t in texts]
611 > print(' %s: rawsizes=%r flags=%r hashes=%r'
611 > print(' %s: rawsizes=%r flags=%r hashes=%r'
612 > % (name, sizes, flags, hashes))
612 > % (name, sizes, flags, hashes))
613 > EOF
613 > EOF
614
614
615 $ for i in client client2 server repo3 repo4 repo5 repo6 repo7 repo8 repo9 \
615 $ for i in client client2 server repo3 repo4 repo5 repo6 repo7 repo8 repo9 \
616 > repo10; do
616 > repo10; do
617 > echo 'repo:' $i
617 > echo 'repo:' $i
618 > hg --cwd $i verify --config extensions.dumpflog=$TESTTMP/dumpflog.py -q
618 > hg --cwd $i verify --config extensions.dumpflog=$TESTTMP/dumpflog.py -q
619 > done
619 > done
620 repo: client
620 repo: client
621 repo: client2
621 repo: client2
622 repo: server
622 repo: server
623 repo: repo3
623 repo: repo3
624 l: rawsizes=[211, 6, 8, 141] flags=[8192, 0, 0, 8192] hashes=['d2b8', '948c', 'cc88', '724d']
624 l: rawsizes=[211, 6, 8, 141] flags=[8192, 0, 0, 8192] hashes=['d2b8', '948c', 'cc88', '724d']
625 s: rawsizes=[74, 141, 141, 8] flags=[0, 8192, 8192, 0] hashes=['3c80', 'fce0', '874a', '826b']
625 s: rawsizes=[74, 141, 141, 8] flags=[0, 8192, 8192, 0] hashes=['3c80', 'fce0', '874a', '826b']
626 repo: repo4
626 repo: repo4
627 l: rawsizes=[211, 6, 8, 141] flags=[8192, 0, 0, 8192] hashes=['d2b8', '948c', 'cc88', '724d']
627 l: rawsizes=[211, 6, 8, 141] flags=[8192, 0, 0, 8192] hashes=['d2b8', '948c', 'cc88', '724d']
628 s: rawsizes=[74, 141, 141, 8] flags=[0, 8192, 8192, 0] hashes=['3c80', 'fce0', '874a', '826b']
628 s: rawsizes=[74, 141, 141, 8] flags=[0, 8192, 8192, 0] hashes=['3c80', 'fce0', '874a', '826b']
629 repo: repo5
629 repo: repo5
630 l: rawsizes=[211, 6, 8, 141] flags=[8192, 0, 0, 8192] hashes=['d2b8', '948c', 'cc88', '724d']
630 l: rawsizes=[211, 6, 8, 141] flags=[8192, 0, 0, 8192] hashes=['d2b8', '948c', 'cc88', '724d']
631 s: rawsizes=[74, 141, 141, 8] flags=[0, 8192, 8192, 0] hashes=['3c80', 'fce0', '874a', '826b']
631 s: rawsizes=[74, 141, 141, 8] flags=[0, 8192, 8192, 0] hashes=['3c80', 'fce0', '874a', '826b']
632 repo: repo6
632 repo: repo6
633 repo: repo7
633 repo: repo7
634 repo: repo8
634 repo: repo8
635 repo: repo9
635 repo: repo9
636 repo: repo10
636 repo: repo10
637
637
638 repo13 doesn't have any cached lfs files and its source never pushed its
638 repo13 doesn't have any cached lfs files and its source never pushed its
639 files. Therefore, the files don't exist in the remote store. Use the files in
639 files. Therefore, the files don't exist in the remote store. Use the files in
640 the user cache.
640 the user cache.
641
641
642 $ test -d $TESTTMP/repo13/.hg/store/lfs/objects
642 $ test -d $TESTTMP/repo13/.hg/store/lfs/objects
643 [1]
643 [1]
644
644
645 $ hg --config extensions.share= share repo13 repo14
645 $ hg --config extensions.share= share repo13 repo14
646 updating working directory
646 updating working directory
647 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
647 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
648 $ hg -R repo14 -q verify
648 $ hg -R repo14 -q verify
649
649
650 $ hg clone repo13 repo15
650 $ hg clone repo13 repo15
651 updating to branch default
651 updating to branch default
652 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
652 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
653 $ hg -R repo15 -q verify
653 $ hg -R repo15 -q verify
654
654
655 If the source repo doesn't have the blob (maybe it was pulled or cloned with
655 If the source repo doesn't have the blob (maybe it was pulled or cloned with
656 --noupdate), the blob is still accessible via the global cache to send to the
656 --noupdate), the blob is still accessible via the global cache to send to the
657 remote store.
657 remote store.
658
658
659 $ rm -rf $TESTTMP/repo15/.hg/store/lfs
659 $ rm -rf $TESTTMP/repo15/.hg/store/lfs
660 $ hg init repo16
660 $ hg init repo16
661 $ hg -R repo15 push repo16
661 $ hg -R repo15 push repo16
662 pushing to repo16
662 pushing to repo16
663 searching for changes
663 searching for changes
664 adding changesets
664 adding changesets
665 adding manifests
665 adding manifests
666 adding file changes
666 adding file changes
667 added 3 changesets with 2 changes to 1 files
667 added 3 changesets with 2 changes to 1 files
668 $ hg -R repo15 -q verify
668 $ hg -R repo15 -q verify
669
669
670 Test damaged file scenarios. (This also damages the usercache because of the
670 Test damaged file scenarios. (This also damages the usercache because of the
671 hardlinks.)
671 hardlinks.)
672
672
673 $ echo 'damage' >> repo5/.hg/store/lfs/objects/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
673 $ echo 'damage' >> repo5/.hg/store/lfs/objects/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
674
674
675 Repo with damaged lfs objects in any revision will fail verification.
675 Repo with damaged lfs objects in any revision will fail verification.
676
676
677 $ hg -R repo5 verify
677 $ hg -R repo5 verify
678 checking changesets
678 checking changesets
679 checking manifests
679 checking manifests
680 crosschecking files in changesets and manifests
680 crosschecking files in changesets and manifests
681 checking files
681 checking files
682 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
682 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
683 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
683 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
684 4 files, 5 changesets, 10 total revisions
684 4 files, 5 changesets, 10 total revisions
685 2 integrity errors encountered!
685 2 integrity errors encountered!
686 (first damaged changeset appears to be 0)
686 (first damaged changeset appears to be 0)
687 [1]
687 [1]
688
688
689 Updates work after cloning a damaged repo, if the damaged lfs objects aren't in
689 Updates work after cloning a damaged repo, if the damaged lfs objects aren't in
690 the update destination. Those objects won't be added to the new repo's store
690 the update destination. Those objects won't be added to the new repo's store
691 because they aren't accessed.
691 because they aren't accessed.
692
692
693 $ hg clone -v repo5 fromcorrupt
693 $ hg clone -v repo5 fromcorrupt
694 updating to branch default
694 updating to branch default
695 resolving manifests
695 resolving manifests
696 getting l
696 getting l
697 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the usercache
697 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the usercache
698 getting s
698 getting s
699 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
699 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
700 $ test -f fromcorrupt/.hg/store/lfs/objects/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
700 $ test -f fromcorrupt/.hg/store/lfs/objects/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
701 [1]
701 [1]
702
702
703 Verify will copy/link all lfs objects into the local store that aren't already
703 Verify will copy/link all lfs objects into the local store that aren't already
704 present. Bypass the corrupted usercache to show that verify works when fed by
704 present. Bypass the corrupted usercache to show that verify works when fed by
705 the (uncorrupted) remote store.
705 the (uncorrupted) remote store.
706
706
707 $ hg -R fromcorrupt --config lfs.usercache=emptycache verify -v
707 $ hg -R fromcorrupt --config lfs.usercache=emptycache verify -v
708 repository uses revlog format 1
708 repository uses revlog format 1
709 checking changesets
709 checking changesets
710 checking manifests
710 checking manifests
711 crosschecking files in changesets and manifests
711 crosschecking files in changesets and manifests
712 checking files
712 checking files
713 lfs: adding 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e to the usercache
713 lfs: adding 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e to the usercache
714 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the local lfs store
714 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the local lfs store
715 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
715 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
716 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the local lfs store
716 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the local lfs store
717 lfs: adding 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 to the usercache
717 lfs: adding 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 to the usercache
718 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
718 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
719 lfs: adding b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c to the usercache
719 lfs: adding b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c to the usercache
720 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
720 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
721 4 files, 5 changesets, 10 total revisions
721 4 files, 5 changesets, 10 total revisions
722
722
723 Verify will not copy/link a corrupted file from the usercache into the local
723 Verify will not copy/link a corrupted file from the usercache into the local
724 store, and poison it. (The verify with a good remote now works.)
724 store, and poison it. (The verify with a good remote now works.)
725
725
726 $ rm -r fromcorrupt/.hg/store/lfs/objects/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
726 $ rm -r fromcorrupt/.hg/store/lfs/objects/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
727 $ hg -R fromcorrupt verify -v
727 $ hg -R fromcorrupt verify -v
728 repository uses revlog format 1
728 repository uses revlog format 1
729 checking changesets
729 checking changesets
730 checking manifests
730 checking manifests
731 crosschecking files in changesets and manifests
731 crosschecking files in changesets and manifests
732 checking files
732 checking files
733 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
733 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
734 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
734 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
735 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
735 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
736 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
736 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
737 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
737 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
738 4 files, 5 changesets, 10 total revisions
738 4 files, 5 changesets, 10 total revisions
739 2 integrity errors encountered!
739 2 integrity errors encountered!
740 (first damaged changeset appears to be 0)
740 (first damaged changeset appears to be 0)
741 [1]
741 [1]
742 $ hg -R fromcorrupt --config lfs.usercache=emptycache verify -v
742 $ hg -R fromcorrupt --config lfs.usercache=emptycache verify -v
743 repository uses revlog format 1
743 repository uses revlog format 1
744 checking changesets
744 checking changesets
745 checking manifests
745 checking manifests
746 crosschecking files in changesets and manifests
746 crosschecking files in changesets and manifests
747 checking files
747 checking files
748 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the usercache
748 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the usercache
749 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
749 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
750 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the local lfs store
750 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the local lfs store
751 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
751 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
752 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
752 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
753 4 files, 5 changesets, 10 total revisions
753 4 files, 5 changesets, 10 total revisions
754
754
755 Damaging a file required by the update destination fails the update.
755 Damaging a file required by the update destination fails the update.
756
756
757 $ echo 'damage' >> $TESTTMP/dummy-remote/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
757 $ echo 'damage' >> $TESTTMP/dummy-remote/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
758 $ hg --config lfs.usercache=emptycache clone -v repo5 fromcorrupt2
758 $ hg --config lfs.usercache=emptycache clone -v repo5 fromcorrupt2
759 updating to branch default
759 updating to branch default
760 resolving manifests
760 resolving manifests
761 getting l
761 getting l
762 abort: corrupt remote lfs object: 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
762 abort: corrupt remote lfs object: 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
763 [255]
763 [255]
764
764
765 A corrupted lfs blob is not transferred from a file://remotestore to the
765 A corrupted lfs blob is not transferred from a file://remotestore to the
766 usercache or local store.
766 usercache or local store.
767
767
768 $ test -f emptycache/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
768 $ test -f emptycache/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
769 [1]
769 [1]
770 $ test -f fromcorrupt2/.hg/store/lfs/objects/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
770 $ test -f fromcorrupt2/.hg/store/lfs/objects/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
771 [1]
771 [1]
772
772
773 $ hg -R fromcorrupt2 verify
773 $ hg -R fromcorrupt2 verify
774 checking changesets
774 checking changesets
775 checking manifests
775 checking manifests
776 crosschecking files in changesets and manifests
776 crosschecking files in changesets and manifests
777 checking files
777 checking files
778 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
778 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
779 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
779 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
780 4 files, 5 changesets, 10 total revisions
780 4 files, 5 changesets, 10 total revisions
781 2 integrity errors encountered!
781 2 integrity errors encountered!
782 (first damaged changeset appears to be 0)
782 (first damaged changeset appears to be 0)
783 [1]
783 [1]
784
784
785 Corrupt local files are not sent upstream. (The alternate dummy remote
785 Corrupt local files are not sent upstream. (The alternate dummy remote
786 avoids the corrupt lfs object in the original remote.)
786 avoids the corrupt lfs object in the original remote.)
787
787
788 $ mkdir $TESTTMP/dummy-remote2
788 $ mkdir $TESTTMP/dummy-remote2
789 $ hg init dest
789 $ hg init dest
790 $ hg -R fromcorrupt2 --config lfs.url=file:///$TESTTMP/dummy-remote2 push -v dest
790 $ hg -R fromcorrupt2 --config lfs.url=file:///$TESTTMP/dummy-remote2 push -v dest
791 pushing to dest
791 pushing to dest
792 searching for changes
792 searching for changes
793 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
793 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
794 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
794 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
795 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
795 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
796 abort: detected corrupt lfs object: 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
796 abort: detected corrupt lfs object: 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
797 (run hg verify)
797 (run hg verify)
798 [255]
798 [255]
799
799
800 $ hg -R fromcorrupt2 --config lfs.url=file:///$TESTTMP/dummy-remote2 verify -v
800 $ hg -R fromcorrupt2 --config lfs.url=file:///$TESTTMP/dummy-remote2 verify -v
801 repository uses revlog format 1
801 repository uses revlog format 1
802 checking changesets
802 checking changesets
803 checking manifests
803 checking manifests
804 crosschecking files in changesets and manifests
804 crosschecking files in changesets and manifests
805 checking files
805 checking files
806 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
806 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
807 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
807 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
808 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
808 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
809 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
809 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
810 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
810 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
811 4 files, 5 changesets, 10 total revisions
811 4 files, 5 changesets, 10 total revisions
812 2 integrity errors encountered!
812 2 integrity errors encountered!
813 (first damaged changeset appears to be 0)
813 (first damaged changeset appears to be 0)
814 [1]
814 [1]
815
815
816 $ cat $TESTTMP/dummy-remote2/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b | $TESTDIR/f --sha256
816 $ cat $TESTTMP/dummy-remote2/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b | $TESTDIR/f --sha256
817 sha256=22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
817 sha256=22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
818 $ cat fromcorrupt2/.hg/store/lfs/objects/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b | $TESTDIR/f --sha256
818 $ cat fromcorrupt2/.hg/store/lfs/objects/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b | $TESTDIR/f --sha256
819 sha256=22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
819 sha256=22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
820 $ test -f $TESTTMP/dummy-remote2/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
820 $ test -f $TESTTMP/dummy-remote2/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
821 [1]
821 [1]
822
822
823 Accessing a corrupt file will complain
823 Accessing a corrupt file will complain
824
824
825 $ hg --cwd fromcorrupt2 cat -r 0 large
825 $ hg --cwd fromcorrupt2 cat -r 0 large
826 abort: integrity check failed on data/large.i:0!
826 abort: integrity check failed on data/large.i:0!
827 [255]
827 [255]
828
828
829 lfs -> normal -> lfs round trip conversions are possible. The 'none()'
829 lfs -> normal -> lfs round trip conversions are possible. The 'none()'
830 predicate on the command line will override whatever is configured globally and
830 predicate on the command line will override whatever is configured globally and
831 locally, and ensures everything converts to a regular file. For lfs -> normal,
831 locally, and ensures everything converts to a regular file. For lfs -> normal,
832 there's no 'lfs' destination repo requirement. For normal -> lfs, there is.
832 there's no 'lfs' destination repo requirement. For normal -> lfs, there is.
833
833
834 $ hg --config extensions.convert= --config 'lfs.track=none()' \
834 $ hg --config extensions.convert= --config 'lfs.track=none()' \
835 > convert repo8 convert_normal
835 > convert repo8 convert_normal
836 initializing destination convert_normal repository
836 initializing destination convert_normal repository
837 scanning source...
837 scanning source...
838 sorting...
838 sorting...
839 converting...
839 converting...
840 2 a
840 2 a
841 1 b
841 1 b
842 0 meta
842 0 meta
843 $ grep 'lfs' convert_normal/.hg/requires
843 $ grep 'lfs' convert_normal/.hg/requires
844 [1]
844 [1]
845 $ hg --cwd convert_normal debugdata a1 0
845 $ hg --cwd convert_normal debugdata a1 0
846 THIS-IS-LFS-BECAUSE-10-BYTES
846 THIS-IS-LFS-BECAUSE-10-BYTES
847
847
848 $ hg --config extensions.convert= --config lfs.threshold=10B \
848 $ hg --config extensions.convert= --config lfs.threshold=10B \
849 > convert convert_normal convert_lfs
849 > convert convert_normal convert_lfs
850 initializing destination convert_lfs repository
850 initializing destination convert_lfs repository
851 scanning source...
851 scanning source...
852 sorting...
852 sorting...
853 converting...
853 converting...
854 2 a
854 2 a
855 1 b
855 1 b
856 0 meta
856 0 meta
857 $ hg --cwd convert_lfs debugdata a1 0
857 $ hg --cwd convert_lfs debugdata a1 0
858 version https://git-lfs.github.com/spec/v1
858 version https://git-lfs.github.com/spec/v1
859 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
859 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
860 size 29
860 size 29
861 x-is-binary 0
861 x-is-binary 0
862 $ hg --cwd convert_lfs log -r 'all()' -T '{rev}: {lfs_files % "{file}\n"}'
862 $ hg --cwd convert_lfs \
863 0: a1
863 > log -r 'all()' -T '{rev}: {lfs_files % "{file}: {oid}\n"}'
864 1: a2
864 0: a1: 5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
865 2: a2
865 1: a2: 5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
866 2: a2: 876dadc86a8542f9798048f2c47f51dbf8e4359aed883e8ec80c5db825f0d943
866
867
867 $ grep 'lfs' convert_lfs/.hg/requires
868 $ grep 'lfs' convert_lfs/.hg/requires
868 lfs
869 lfs
869
870
870 The hashes in all stages of the conversion are unchanged.
871 The hashes in all stages of the conversion are unchanged.
871
872
872 $ hg -R repo8 log -T '{node|short}\n'
873 $ hg -R repo8 log -T '{node|short}\n'
873 0fae949de7fa
874 0fae949de7fa
874 9cd6bdffdac0
875 9cd6bdffdac0
875 7f96794915f7
876 7f96794915f7
876 $ hg -R convert_normal log -T '{node|short}\n'
877 $ hg -R convert_normal log -T '{node|short}\n'
877 0fae949de7fa
878 0fae949de7fa
878 9cd6bdffdac0
879 9cd6bdffdac0
879 7f96794915f7
880 7f96794915f7
880 $ hg -R convert_lfs log -T '{node|short}\n'
881 $ hg -R convert_lfs log -T '{node|short}\n'
881 0fae949de7fa
882 0fae949de7fa
882 9cd6bdffdac0
883 9cd6bdffdac0
883 7f96794915f7
884 7f96794915f7
884
885
885 This convert is trickier, because it contains deleted files (via `hg mv`)
886 This convert is trickier, because it contains deleted files (via `hg mv`)
886
887
887 $ hg --config extensions.convert= --config lfs.threshold=1000M \
888 $ hg --config extensions.convert= --config lfs.threshold=1000M \
888 > convert repo3 convert_normal2
889 > convert repo3 convert_normal2
889 initializing destination convert_normal2 repository
890 initializing destination convert_normal2 repository
890 scanning source...
891 scanning source...
891 sorting...
892 sorting...
892 converting...
893 converting...
893 4 commit with lfs content
894 4 commit with lfs content
894 3 renames
895 3 renames
895 2 large to small, small to large
896 2 large to small, small to large
896 1 random modifications
897 1 random modifications
897 0 switch large and small again
898 0 switch large and small again
898 $ grep 'lfs' convert_normal2/.hg/requires
899 $ grep 'lfs' convert_normal2/.hg/requires
899 [1]
900 [1]
900 $ hg --cwd convert_normal2 debugdata large 0
901 $ hg --cwd convert_normal2 debugdata large 0
901 LONGER-THAN-TEN-BYTES-WILL-TRIGGER-LFS
902 LONGER-THAN-TEN-BYTES-WILL-TRIGGER-LFS
902
903
903 $ hg --config extensions.convert= --config lfs.threshold=10B \
904 $ hg --config extensions.convert= --config lfs.threshold=10B \
904 > convert convert_normal2 convert_lfs2
905 > convert convert_normal2 convert_lfs2
905 initializing destination convert_lfs2 repository
906 initializing destination convert_lfs2 repository
906 scanning source...
907 scanning source...
907 sorting...
908 sorting...
908 converting...
909 converting...
909 4 commit with lfs content
910 4 commit with lfs content
910 3 renames
911 3 renames
911 2 large to small, small to large
912 2 large to small, small to large
912 1 random modifications
913 1 random modifications
913 0 switch large and small again
914 0 switch large and small again
914 $ grep 'lfs' convert_lfs2/.hg/requires
915 $ grep 'lfs' convert_lfs2/.hg/requires
915 lfs
916 lfs
916 $ hg --cwd convert_lfs2 debugdata large 0
917 $ hg --cwd convert_lfs2 debugdata large 0
917 version https://git-lfs.github.com/spec/v1
918 version https://git-lfs.github.com/spec/v1
918 oid sha256:66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
919 oid sha256:66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
919 size 39
920 size 39
920 x-is-binary 0
921 x-is-binary 0
921
922
922 $ hg -R convert_lfs2 config --debug extensions | grep lfs
923 $ hg -R convert_lfs2 config --debug extensions | grep lfs
923 $TESTTMP/convert_lfs2/.hg/hgrc:*: extensions.lfs= (glob)
924 $TESTTMP/convert_lfs2/.hg/hgrc:*: extensions.lfs= (glob)
924
925
925 Committing deleted files works:
926 Committing deleted files works:
926
927
927 $ hg init $TESTTMP/repo-del
928 $ hg init $TESTTMP/repo-del
928 $ cd $TESTTMP/repo-del
929 $ cd $TESTTMP/repo-del
929 $ echo 1 > A
930 $ echo 1 > A
930 $ hg commit -m 'add A' -A A
931 $ hg commit -m 'add A' -A A
931 $ hg rm A
932 $ hg rm A
932 $ hg commit -m 'rm A'
933 $ hg commit -m 'rm A'
933 $ cd ..
934 $ cd ..
934
935
935 Unbundling adds a requirement to a non-lfs repo, if necessary.
936 Unbundling adds a requirement to a non-lfs repo, if necessary.
936
937
937 $ hg bundle -R $TESTTMP/repo-del -qr 0 --base null nolfs.hg
938 $ hg bundle -R $TESTTMP/repo-del -qr 0 --base null nolfs.hg
938 $ hg bundle -R convert_lfs2 -qr tip --base null lfs.hg
939 $ hg bundle -R convert_lfs2 -qr tip --base null lfs.hg
939 $ hg init unbundle
940 $ hg init unbundle
940 $ hg pull -R unbundle -q nolfs.hg
941 $ hg pull -R unbundle -q nolfs.hg
941 $ grep lfs unbundle/.hg/requires
942 $ grep lfs unbundle/.hg/requires
942 [1]
943 [1]
943 $ hg pull -R unbundle -q lfs.hg
944 $ hg pull -R unbundle -q lfs.hg
944 $ grep lfs unbundle/.hg/requires
945 $ grep lfs unbundle/.hg/requires
945 lfs
946 lfs
946
947
947 $ hg init no_lfs
948 $ hg init no_lfs
948 $ cat >> no_lfs/.hg/hgrc <<EOF
949 $ cat >> no_lfs/.hg/hgrc <<EOF
949 > [experimental]
950 > [experimental]
950 > changegroup3 = True
951 > changegroup3 = True
951 > [extensions]
952 > [extensions]
952 > lfs=!
953 > lfs=!
953 > EOF
954 > EOF
954 $ cp -R no_lfs no_lfs2
955 $ cp -R no_lfs no_lfs2
955
956
956 Pushing from a local lfs repo to a local repo without an lfs requirement and
957 Pushing from a local lfs repo to a local repo without an lfs requirement and
957 with lfs disabled, fails.
958 with lfs disabled, fails.
958
959
959 $ hg push -R convert_lfs2 no_lfs
960 $ hg push -R convert_lfs2 no_lfs
960 pushing to no_lfs
961 pushing to no_lfs
961 abort: required features are not supported in the destination: lfs
962 abort: required features are not supported in the destination: lfs
962 [255]
963 [255]
963 $ grep lfs no_lfs/.hg/requires
964 $ grep lfs no_lfs/.hg/requires
964 [1]
965 [1]
965
966
966 Pulling from a local lfs repo to a local repo without an lfs requirement and
967 Pulling from a local lfs repo to a local repo without an lfs requirement and
967 with lfs disabled, fails.
968 with lfs disabled, fails.
968
969
969 $ hg pull -R no_lfs2 convert_lfs2
970 $ hg pull -R no_lfs2 convert_lfs2
970 pulling from convert_lfs2
971 pulling from convert_lfs2
971 abort: required features are not supported in the destination: lfs
972 abort: required features are not supported in the destination: lfs
972 [255]
973 [255]
973 $ grep lfs no_lfs2/.hg/requires
974 $ grep lfs no_lfs2/.hg/requires
974 [1]
975 [1]
General Comments 0
You need to be logged in to leave comments. Login now