##// END OF EJS Templates
lfs: add a switch to `hg verify` to ignore the content of blobs...
Matt Harbison -
r44528:34e8305f default
parent child Browse files
Show More
@@ -1,404 +1,425 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 This extension allows large files to be tracked outside of the normal
10 This extension allows large files to be tracked outside of the normal
11 repository storage and stored on a centralized server, similar to the
11 repository storage and stored on a centralized server, similar to the
12 ``largefiles`` extension. The ``git-lfs`` protocol is used when
12 ``largefiles`` extension. The ``git-lfs`` protocol is used when
13 communicating with the server, so existing git infrastructure can be
13 communicating with the server, so existing git infrastructure can be
14 harnessed. Even though the files are stored outside of the repository,
14 harnessed. Even though the files are stored outside of the repository,
15 they are still integrity checked in the same manner as normal files.
15 they are still integrity checked in the same manner as normal files.
16
16
17 The files stored outside of the repository are downloaded on demand,
17 The files stored outside of the repository are downloaded on demand,
18 which reduces the time to clone, and possibly the local disk usage.
18 which reduces the time to clone, and possibly the local disk usage.
19 This changes fundamental workflows in a DVCS, so careful thought
19 This changes fundamental workflows in a DVCS, so careful thought
20 should be given before deploying it. :hg:`convert` can be used to
20 should be given before deploying it. :hg:`convert` can be used to
21 convert LFS repositories to normal repositories that no longer
21 convert LFS repositories to normal repositories that no longer
22 require this extension, and do so without changing the commit hashes.
22 require this extension, and do so without changing the commit hashes.
23 This allows the extension to be disabled if the centralized workflow
23 This allows the extension to be disabled if the centralized workflow
24 becomes burdensome. However, the pre and post convert clones will
24 becomes burdensome. However, the pre and post convert clones will
25 not be able to communicate with each other unless the extension is
25 not be able to communicate with each other unless the extension is
26 enabled on both.
26 enabled on both.
27
27
28 To start a new repository, or to add LFS files to an existing one, just
28 To start a new repository, or to add LFS files to an existing one, just
29 create an ``.hglfs`` file as described below in the root directory of
29 create an ``.hglfs`` file as described below in the root directory of
30 the repository. Typically, this file should be put under version
30 the repository. Typically, this file should be put under version
31 control, so that the settings will propagate to other repositories with
31 control, so that the settings will propagate to other repositories with
32 push and pull. During any commit, Mercurial will consult this file to
32 push and pull. During any commit, Mercurial will consult this file to
33 determine if an added or modified file should be stored externally. The
33 determine if an added or modified file should be stored externally. The
34 type of storage depends on the characteristics of the file at each
34 type of storage depends on the characteristics of the file at each
35 commit. A file that is near a size threshold may switch back and forth
35 commit. A file that is near a size threshold may switch back and forth
36 between LFS and normal storage, as needed.
36 between LFS and normal storage, as needed.
37
37
38 Alternately, both normal repositories and largefile controlled
38 Alternately, both normal repositories and largefile controlled
39 repositories can be converted to LFS by using :hg:`convert` and the
39 repositories can be converted to LFS by using :hg:`convert` and the
40 ``lfs.track`` config option described below. The ``.hglfs`` file
40 ``lfs.track`` config option described below. The ``.hglfs`` file
41 should then be created and added, to control subsequent LFS selection.
41 should then be created and added, to control subsequent LFS selection.
42 The hashes are also unchanged in this case. The LFS and non-LFS
42 The hashes are also unchanged in this case. The LFS and non-LFS
43 repositories can be distinguished because the LFS repository will
43 repositories can be distinguished because the LFS repository will
44 abort any command if this extension is disabled.
44 abort any command if this extension is disabled.
45
45
46 Committed LFS files are held locally, until the repository is pushed.
46 Committed LFS files are held locally, until the repository is pushed.
47 Prior to pushing the normal repository data, the LFS files that are
47 Prior to pushing the normal repository data, the LFS files that are
48 tracked by the outgoing commits are automatically uploaded to the
48 tracked by the outgoing commits are automatically uploaded to the
49 configured central server. No LFS files are transferred on
49 configured central server. No LFS files are transferred on
50 :hg:`pull` or :hg:`clone`. Instead, the files are downloaded on
50 :hg:`pull` or :hg:`clone`. Instead, the files are downloaded on
51 demand as they need to be read, if a cached copy cannot be found
51 demand as they need to be read, if a cached copy cannot be found
52 locally. Both committing and downloading an LFS file will link the
52 locally. Both committing and downloading an LFS file will link the
53 file to a usercache, to speed up future access. See the `usercache`
53 file to a usercache, to speed up future access. See the `usercache`
54 config setting described below.
54 config setting described below.
55
55
56 The extension reads its configuration from a versioned ``.hglfs``
56 The extension reads its configuration from a versioned ``.hglfs``
57 configuration file found in the root of the working directory. The
57 configuration file found in the root of the working directory. The
58 ``.hglfs`` file uses the same syntax as all other Mercurial
58 ``.hglfs`` file uses the same syntax as all other Mercurial
59 configuration files. It uses a single section, ``[track]``.
59 configuration files. It uses a single section, ``[track]``.
60
60
61 The ``[track]`` section specifies which files are stored as LFS (or
61 The ``[track]`` section specifies which files are stored as LFS (or
62 not). Each line is keyed by a file pattern, with a predicate value.
62 not). Each line is keyed by a file pattern, with a predicate value.
63 The first file pattern match is used, so put more specific patterns
63 The first file pattern match is used, so put more specific patterns
64 first. The available predicates are ``all()``, ``none()``, and
64 first. The available predicates are ``all()``, ``none()``, and
65 ``size()``. See "hg help filesets.size" for the latter.
65 ``size()``. See "hg help filesets.size" for the latter.
66
66
67 Example versioned ``.hglfs`` file::
67 Example versioned ``.hglfs`` file::
68
68
69 [track]
69 [track]
70 # No Makefile or python file, anywhere, will be LFS
70 # No Makefile or python file, anywhere, will be LFS
71 **Makefile = none()
71 **Makefile = none()
72 **.py = none()
72 **.py = none()
73
73
74 **.zip = all()
74 **.zip = all()
75 **.exe = size(">1MB")
75 **.exe = size(">1MB")
76
76
77 # Catchall for everything not matched above
77 # Catchall for everything not matched above
78 ** = size(">10MB")
78 ** = size(">10MB")
79
79
80 Configs::
80 Configs::
81
81
82 [lfs]
82 [lfs]
83 # Remote endpoint. Multiple protocols are supported:
83 # Remote endpoint. Multiple protocols are supported:
84 # - http(s)://user:pass@example.com/path
84 # - http(s)://user:pass@example.com/path
85 # git-lfs endpoint
85 # git-lfs endpoint
86 # - file:///tmp/path
86 # - file:///tmp/path
87 # local filesystem, usually for testing
87 # local filesystem, usually for testing
88 # if unset, lfs will assume the remote repository also handles blob storage
88 # if unset, lfs will assume the remote repository also handles blob storage
89 # for http(s) URLs. Otherwise, lfs will prompt to set this when it must
89 # for http(s) URLs. Otherwise, lfs will prompt to set this when it must
90 # use this value.
90 # use this value.
91 # (default: unset)
91 # (default: unset)
92 url = https://example.com/repo.git/info/lfs
92 url = https://example.com/repo.git/info/lfs
93
93
94 # Which files to track in LFS. Path tests are "**.extname" for file
94 # Which files to track in LFS. Path tests are "**.extname" for file
95 # extensions, and "path:under/some/directory" for path prefix. Both
95 # extensions, and "path:under/some/directory" for path prefix. Both
96 # are relative to the repository root.
96 # are relative to the repository root.
97 # File size can be tested with the "size()" fileset, and tests can be
97 # File size can be tested with the "size()" fileset, and tests can be
98 # joined with fileset operators. (See "hg help filesets.operators".)
98 # joined with fileset operators. (See "hg help filesets.operators".)
99 #
99 #
100 # Some examples:
100 # Some examples:
101 # - all() # everything
101 # - all() # everything
102 # - none() # nothing
102 # - none() # nothing
103 # - size(">20MB") # larger than 20MB
103 # - size(">20MB") # larger than 20MB
104 # - !**.txt # anything not a *.txt file
104 # - !**.txt # anything not a *.txt file
105 # - **.zip | **.tar.gz | **.7z # some types of compressed files
105 # - **.zip | **.tar.gz | **.7z # some types of compressed files
106 # - path:bin # files under "bin" in the project root
106 # - path:bin # files under "bin" in the project root
107 # - (**.php & size(">2MB")) | (**.js & size(">5MB")) | **.tar.gz
107 # - (**.php & size(">2MB")) | (**.js & size(">5MB")) | **.tar.gz
108 # | (path:bin & !path:/bin/README) | size(">1GB")
108 # | (path:bin & !path:/bin/README) | size(">1GB")
109 # (default: none())
109 # (default: none())
110 #
110 #
111 # This is ignored if there is a tracked '.hglfs' file, and this setting
111 # This is ignored if there is a tracked '.hglfs' file, and this setting
112 # will eventually be deprecated and removed.
112 # will eventually be deprecated and removed.
113 track = size(">10M")
113 track = size(">10M")
114
114
115 # how many times to retry before giving up on transferring an object
115 # how many times to retry before giving up on transferring an object
116 retry = 5
116 retry = 5
117
117
118 # the local directory to store lfs files for sharing across local clones.
118 # the local directory to store lfs files for sharing across local clones.
119 # If not set, the cache is located in an OS specific cache location.
119 # If not set, the cache is located in an OS specific cache location.
120 usercache = /path/to/global/cache
120 usercache = /path/to/global/cache
121 """
121 """
122
122
123 from __future__ import absolute_import
123 from __future__ import absolute_import
124
124
125 import sys
125 import sys
126
126
127 from mercurial.i18n import _
127 from mercurial.i18n import _
128
128
129 from mercurial import (
129 from mercurial import (
130 config,
130 config,
131 context,
131 context,
132 error,
132 error,
133 exchange,
133 exchange,
134 extensions,
134 extensions,
135 exthelper,
135 exthelper,
136 filelog,
136 filelog,
137 filesetlang,
137 filesetlang,
138 localrepo,
138 localrepo,
139 minifileset,
139 minifileset,
140 node,
140 node,
141 pycompat,
141 pycompat,
142 revlog,
142 revlog,
143 scmutil,
143 scmutil,
144 templateutil,
144 templateutil,
145 util,
145 util,
146 )
146 )
147
147
148 from mercurial.interfaces import repository
148 from mercurial.interfaces import repository
149
149
150 from . import (
150 from . import (
151 blobstore,
151 blobstore,
152 wireprotolfsserver,
152 wireprotolfsserver,
153 wrapper,
153 wrapper,
154 )
154 )
155
155
156 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
156 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
157 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
157 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
158 # be specifying the version(s) of Mercurial they are tested with, or
158 # be specifying the version(s) of Mercurial they are tested with, or
159 # leave the attribute unspecified.
159 # leave the attribute unspecified.
160 testedwith = b'ships-with-hg-core'
160 testedwith = b'ships-with-hg-core'
161
161
162 eh = exthelper.exthelper()
162 eh = exthelper.exthelper()
163 eh.merge(wrapper.eh)
163 eh.merge(wrapper.eh)
164 eh.merge(wireprotolfsserver.eh)
164 eh.merge(wireprotolfsserver.eh)
165
165
166 cmdtable = eh.cmdtable
166 cmdtable = eh.cmdtable
167 configtable = eh.configtable
167 configtable = eh.configtable
168 extsetup = eh.finalextsetup
168 extsetup = eh.finalextsetup
169 uisetup = eh.finaluisetup
169 uisetup = eh.finaluisetup
170 filesetpredicate = eh.filesetpredicate
170 filesetpredicate = eh.filesetpredicate
171 reposetup = eh.finalreposetup
171 reposetup = eh.finalreposetup
172 templatekeyword = eh.templatekeyword
172 templatekeyword = eh.templatekeyword
173
173
174 eh.configitem(
174 eh.configitem(
175 b'experimental', b'lfs.serve', default=True,
175 b'experimental', b'lfs.serve', default=True,
176 )
176 )
177 eh.configitem(
177 eh.configitem(
178 b'experimental', b'lfs.user-agent', default=None,
178 b'experimental', b'lfs.user-agent', default=None,
179 )
179 )
180 eh.configitem(
180 eh.configitem(
181 b'experimental', b'lfs.disableusercache', default=False,
181 b'experimental', b'lfs.disableusercache', default=False,
182 )
182 )
183 eh.configitem(
183 eh.configitem(
184 b'experimental', b'lfs.worker-enable', default=False,
184 b'experimental', b'lfs.worker-enable', default=False,
185 )
185 )
186
186
187 eh.configitem(
187 eh.configitem(
188 b'lfs', b'url', default=None,
188 b'lfs', b'url', default=None,
189 )
189 )
190 eh.configitem(
190 eh.configitem(
191 b'lfs', b'usercache', default=None,
191 b'lfs', b'usercache', default=None,
192 )
192 )
193 # Deprecated
193 # Deprecated
194 eh.configitem(
194 eh.configitem(
195 b'lfs', b'threshold', default=None,
195 b'lfs', b'threshold', default=None,
196 )
196 )
197 eh.configitem(
197 eh.configitem(
198 b'lfs', b'track', default=b'none()',
198 b'lfs', b'track', default=b'none()',
199 )
199 )
200 eh.configitem(
200 eh.configitem(
201 b'lfs', b'retry', default=5,
201 b'lfs', b'retry', default=5,
202 )
202 )
203
203
204 lfsprocessor = (
204 lfsprocessor = (
205 wrapper.readfromstore,
205 wrapper.readfromstore,
206 wrapper.writetostore,
206 wrapper.writetostore,
207 wrapper.bypasscheckhash,
207 wrapper.bypasscheckhash,
208 )
208 )
209
209
210
210
211 def featuresetup(ui, supported):
211 def featuresetup(ui, supported):
212 # don't die on seeing a repo with the lfs requirement
212 # don't die on seeing a repo with the lfs requirement
213 supported |= {b'lfs'}
213 supported |= {b'lfs'}
214
214
215
215
216 @eh.uisetup
216 @eh.uisetup
217 def _uisetup(ui):
217 def _uisetup(ui):
218 localrepo.featuresetupfuncs.add(featuresetup)
218 localrepo.featuresetupfuncs.add(featuresetup)
219
219
220
220
221 @eh.reposetup
221 @eh.reposetup
222 def _reposetup(ui, repo):
222 def _reposetup(ui, repo):
223 # Nothing to do with a remote repo
223 # Nothing to do with a remote repo
224 if not repo.local():
224 if not repo.local():
225 return
225 return
226
226
227 repo.svfs.lfslocalblobstore = blobstore.local(repo)
227 repo.svfs.lfslocalblobstore = blobstore.local(repo)
228 repo.svfs.lfsremoteblobstore = blobstore.remote(repo)
228 repo.svfs.lfsremoteblobstore = blobstore.remote(repo)
229
229
230 class lfsrepo(repo.__class__):
230 class lfsrepo(repo.__class__):
231 @localrepo.unfilteredmethod
231 @localrepo.unfilteredmethod
232 def commitctx(self, ctx, error=False, origctx=None):
232 def commitctx(self, ctx, error=False, origctx=None):
233 repo.svfs.options[b'lfstrack'] = _trackedmatcher(self)
233 repo.svfs.options[b'lfstrack'] = _trackedmatcher(self)
234 return super(lfsrepo, self).commitctx(ctx, error, origctx=origctx)
234 return super(lfsrepo, self).commitctx(ctx, error, origctx=origctx)
235
235
236 repo.__class__ = lfsrepo
236 repo.__class__ = lfsrepo
237
237
238 if b'lfs' not in repo.requirements:
238 if b'lfs' not in repo.requirements:
239
239
240 def checkrequireslfs(ui, repo, **kwargs):
240 def checkrequireslfs(ui, repo, **kwargs):
241 if b'lfs' in repo.requirements:
241 if b'lfs' in repo.requirements:
242 return 0
242 return 0
243
243
244 last = kwargs.get('node_last')
244 last = kwargs.get('node_last')
245 _bin = node.bin
245 _bin = node.bin
246 if last:
246 if last:
247 s = repo.set(b'%n:%n', _bin(kwargs['node']), _bin(last))
247 s = repo.set(b'%n:%n', _bin(kwargs['node']), _bin(last))
248 else:
248 else:
249 s = repo.set(b'%n', _bin(kwargs['node']))
249 s = repo.set(b'%n', _bin(kwargs['node']))
250 match = repo._storenarrowmatch
250 match = repo._storenarrowmatch
251 for ctx in s:
251 for ctx in s:
252 # TODO: is there a way to just walk the files in the commit?
252 # TODO: is there a way to just walk the files in the commit?
253 if any(
253 if any(
254 ctx[f].islfs() for f in ctx.files() if f in ctx and match(f)
254 ctx[f].islfs() for f in ctx.files() if f in ctx and match(f)
255 ):
255 ):
256 repo.requirements.add(b'lfs')
256 repo.requirements.add(b'lfs')
257 repo.features.add(repository.REPO_FEATURE_LFS)
257 repo.features.add(repository.REPO_FEATURE_LFS)
258 repo._writerequirements()
258 repo._writerequirements()
259 repo.prepushoutgoinghooks.add(b'lfs', wrapper.prepush)
259 repo.prepushoutgoinghooks.add(b'lfs', wrapper.prepush)
260 break
260 break
261
261
262 ui.setconfig(b'hooks', b'commit.lfs', checkrequireslfs, b'lfs')
262 ui.setconfig(b'hooks', b'commit.lfs', checkrequireslfs, b'lfs')
263 ui.setconfig(
263 ui.setconfig(
264 b'hooks', b'pretxnchangegroup.lfs', checkrequireslfs, b'lfs'
264 b'hooks', b'pretxnchangegroup.lfs', checkrequireslfs, b'lfs'
265 )
265 )
266 else:
266 else:
267 repo.prepushoutgoinghooks.add(b'lfs', wrapper.prepush)
267 repo.prepushoutgoinghooks.add(b'lfs', wrapper.prepush)
268
268
269
269
270 def _trackedmatcher(repo):
270 def _trackedmatcher(repo):
271 """Return a function (path, size) -> bool indicating whether or not to
271 """Return a function (path, size) -> bool indicating whether or not to
272 track a given file with lfs."""
272 track a given file with lfs."""
273 if not repo.wvfs.exists(b'.hglfs'):
273 if not repo.wvfs.exists(b'.hglfs'):
274 # No '.hglfs' in wdir. Fallback to config for now.
274 # No '.hglfs' in wdir. Fallback to config for now.
275 trackspec = repo.ui.config(b'lfs', b'track')
275 trackspec = repo.ui.config(b'lfs', b'track')
276
276
277 # deprecated config: lfs.threshold
277 # deprecated config: lfs.threshold
278 threshold = repo.ui.configbytes(b'lfs', b'threshold')
278 threshold = repo.ui.configbytes(b'lfs', b'threshold')
279 if threshold:
279 if threshold:
280 filesetlang.parse(trackspec) # make sure syntax errors are confined
280 filesetlang.parse(trackspec) # make sure syntax errors are confined
281 trackspec = b"(%s) | size('>%d')" % (trackspec, threshold)
281 trackspec = b"(%s) | size('>%d')" % (trackspec, threshold)
282
282
283 return minifileset.compile(trackspec)
283 return minifileset.compile(trackspec)
284
284
285 data = repo.wvfs.tryread(b'.hglfs')
285 data = repo.wvfs.tryread(b'.hglfs')
286 if not data:
286 if not data:
287 return lambda p, s: False
287 return lambda p, s: False
288
288
289 # Parse errors here will abort with a message that points to the .hglfs file
289 # Parse errors here will abort with a message that points to the .hglfs file
290 # and line number.
290 # and line number.
291 cfg = config.config()
291 cfg = config.config()
292 cfg.parse(b'.hglfs', data)
292 cfg.parse(b'.hglfs', data)
293
293
294 try:
294 try:
295 rules = [
295 rules = [
296 (minifileset.compile(pattern), minifileset.compile(rule))
296 (minifileset.compile(pattern), minifileset.compile(rule))
297 for pattern, rule in cfg.items(b'track')
297 for pattern, rule in cfg.items(b'track')
298 ]
298 ]
299 except error.ParseError as e:
299 except error.ParseError as e:
300 # The original exception gives no indicator that the error is in the
300 # The original exception gives no indicator that the error is in the
301 # .hglfs file, so add that.
301 # .hglfs file, so add that.
302
302
303 # TODO: See if the line number of the file can be made available.
303 # TODO: See if the line number of the file can be made available.
304 raise error.Abort(_(b'parse error in .hglfs: %s') % e)
304 raise error.Abort(_(b'parse error in .hglfs: %s') % e)
305
305
306 def _match(path, size):
306 def _match(path, size):
307 for pat, rule in rules:
307 for pat, rule in rules:
308 if pat(path, size):
308 if pat(path, size):
309 return rule(path, size)
309 return rule(path, size)
310
310
311 return False
311 return False
312
312
313 return _match
313 return _match
314
314
315
315
316 # Called by remotefilelog
316 # Called by remotefilelog
317 def wrapfilelog(filelog):
317 def wrapfilelog(filelog):
318 wrapfunction = extensions.wrapfunction
318 wrapfunction = extensions.wrapfunction
319
319
320 wrapfunction(filelog, 'addrevision', wrapper.filelogaddrevision)
320 wrapfunction(filelog, 'addrevision', wrapper.filelogaddrevision)
321 wrapfunction(filelog, 'renamed', wrapper.filelogrenamed)
321 wrapfunction(filelog, 'renamed', wrapper.filelogrenamed)
322 wrapfunction(filelog, 'size', wrapper.filelogsize)
322 wrapfunction(filelog, 'size', wrapper.filelogsize)
323
323
324
324
325 @eh.wrapfunction(localrepo, b'resolverevlogstorevfsoptions')
325 @eh.wrapfunction(localrepo, b'resolverevlogstorevfsoptions')
326 def _resolverevlogstorevfsoptions(orig, ui, requirements, features):
326 def _resolverevlogstorevfsoptions(orig, ui, requirements, features):
327 opts = orig(ui, requirements, features)
327 opts = orig(ui, requirements, features)
328 for name, module in extensions.extensions(ui):
328 for name, module in extensions.extensions(ui):
329 if module is sys.modules[__name__]:
329 if module is sys.modules[__name__]:
330 if revlog.REVIDX_EXTSTORED in opts[b'flagprocessors']:
330 if revlog.REVIDX_EXTSTORED in opts[b'flagprocessors']:
331 msg = (
331 msg = (
332 _(b"cannot register multiple processors on flag '%#x'.")
332 _(b"cannot register multiple processors on flag '%#x'.")
333 % revlog.REVIDX_EXTSTORED
333 % revlog.REVIDX_EXTSTORED
334 )
334 )
335 raise error.Abort(msg)
335 raise error.Abort(msg)
336
336
337 opts[b'flagprocessors'][revlog.REVIDX_EXTSTORED] = lfsprocessor
337 opts[b'flagprocessors'][revlog.REVIDX_EXTSTORED] = lfsprocessor
338 break
338 break
339
339
340 return opts
340 return opts
341
341
342
342
343 @eh.extsetup
343 @eh.extsetup
344 def _extsetup(ui):
344 def _extsetup(ui):
345 wrapfilelog(filelog.filelog)
345 wrapfilelog(filelog.filelog)
346
346
347 context.basefilectx.islfs = wrapper.filectxislfs
347 context.basefilectx.islfs = wrapper.filectxislfs
348
348
349 scmutil.fileprefetchhooks.add(b'lfs', wrapper._prefetchfiles)
349 scmutil.fileprefetchhooks.add(b'lfs', wrapper._prefetchfiles)
350
350
351 # Make bundle choose changegroup3 instead of changegroup2. This affects
351 # Make bundle choose changegroup3 instead of changegroup2. This affects
352 # "hg bundle" command. Note: it does not cover all bundle formats like
352 # "hg bundle" command. Note: it does not cover all bundle formats like
353 # "packed1". Using "packed1" with lfs will likely cause trouble.
353 # "packed1". Using "packed1" with lfs will likely cause trouble.
354 exchange._bundlespeccontentopts[b"v2"][b"cg.version"] = b"03"
354 exchange._bundlespeccontentopts[b"v2"][b"cg.version"] = b"03"
355
355
356
356
357 @eh.filesetpredicate(b'lfs()')
357 @eh.filesetpredicate(b'lfs()')
358 def lfsfileset(mctx, x):
358 def lfsfileset(mctx, x):
359 """File that uses LFS storage."""
359 """File that uses LFS storage."""
360 # i18n: "lfs" is a keyword
360 # i18n: "lfs" is a keyword
361 filesetlang.getargs(x, 0, 0, _(b"lfs takes no arguments"))
361 filesetlang.getargs(x, 0, 0, _(b"lfs takes no arguments"))
362 ctx = mctx.ctx
362 ctx = mctx.ctx
363
363
364 def lfsfilep(f):
364 def lfsfilep(f):
365 return wrapper.pointerfromctx(ctx, f, removed=True) is not None
365 return wrapper.pointerfromctx(ctx, f, removed=True) is not None
366
366
367 return mctx.predicate(lfsfilep, predrepr=b'<lfs>')
367 return mctx.predicate(lfsfilep, predrepr=b'<lfs>')
368
368
369
369
370 @eh.templatekeyword(b'lfs_files', requires={b'ctx'})
370 @eh.templatekeyword(b'lfs_files', requires={b'ctx'})
371 def lfsfiles(context, mapping):
371 def lfsfiles(context, mapping):
372 """List of strings. All files modified, added, or removed by this
372 """List of strings. All files modified, added, or removed by this
373 changeset."""
373 changeset."""
374 ctx = context.resource(mapping, b'ctx')
374 ctx = context.resource(mapping, b'ctx')
375
375
376 pointers = wrapper.pointersfromctx(ctx, removed=True) # {path: pointer}
376 pointers = wrapper.pointersfromctx(ctx, removed=True) # {path: pointer}
377 files = sorted(pointers.keys())
377 files = sorted(pointers.keys())
378
378
379 def pointer(v):
379 def pointer(v):
380 # In the file spec, version is first and the other keys are sorted.
380 # In the file spec, version is first and the other keys are sorted.
381 sortkeyfunc = lambda x: (x[0] != b'version', x)
381 sortkeyfunc = lambda x: (x[0] != b'version', x)
382 items = sorted(pycompat.iteritems(pointers[v]), key=sortkeyfunc)
382 items = sorted(pycompat.iteritems(pointers[v]), key=sortkeyfunc)
383 return util.sortdict(items)
383 return util.sortdict(items)
384
384
385 makemap = lambda v: {
385 makemap = lambda v: {
386 b'file': v,
386 b'file': v,
387 b'lfsoid': pointers[v].oid() if pointers[v] else None,
387 b'lfsoid': pointers[v].oid() if pointers[v] else None,
388 b'lfspointer': templateutil.hybriddict(pointer(v)),
388 b'lfspointer': templateutil.hybriddict(pointer(v)),
389 }
389 }
390
390
391 # TODO: make the separator ', '?
391 # TODO: make the separator ', '?
392 f = templateutil._showcompatlist(context, mapping, b'lfs_file', files)
392 f = templateutil._showcompatlist(context, mapping, b'lfs_file', files)
393 return templateutil.hybrid(f, files, makemap, pycompat.identity)
393 return templateutil.hybrid(f, files, makemap, pycompat.identity)
394
394
395
395
396 @eh.command(
396 @eh.command(
397 b'debuglfsupload',
397 b'debuglfsupload',
398 [(b'r', b'rev', [], _(b'upload large files introduced by REV'))],
398 [(b'r', b'rev', [], _(b'upload large files introduced by REV'))],
399 )
399 )
400 def debuglfsupload(ui, repo, **opts):
400 def debuglfsupload(ui, repo, **opts):
401 """upload lfs blobs added by the working copy parent or given revisions"""
401 """upload lfs blobs added by the working copy parent or given revisions"""
402 revs = opts.get('rev', [])
402 revs = opts.get('rev', [])
403 pointers = wrapper.extractpointers(repo, scmutil.revrange(repo, revs))
403 pointers = wrapper.extractpointers(repo, scmutil.revrange(repo, revs))
404 wrapper.uploadblobs(repo, pointers)
404 wrapper.uploadblobs(repo, pointers)
405
406
407 @eh.wrapcommand(
408 b'verify', opts=[(b'', b'no-lfs', None, _(b'skip all lfs blob content'))]
409 )
410 def verify(orig, ui, repo, **opts):
411 skipflags = repo.ui.configint(b'verify', b'skipflags')
412 no_lfs = opts.pop('no_lfs')
413
414 if skipflags:
415 # --lfs overrides the config bit, if set.
416 if no_lfs is False:
417 skipflags &= ~repository.REVISION_FLAG_EXTSTORED
418 else:
419 skipflags = 0
420
421 if no_lfs is True:
422 skipflags |= repository.REVISION_FLAG_EXTSTORED
423
424 with ui.configoverride({(b'verify', b'skipflags'): skipflags}):
425 return orig(ui, repo, **opts)
@@ -1,1169 +1,1190 b''
1 #require no-reposimplestore no-chg
1 #require no-reposimplestore no-chg
2
2
3 $ hg init requirements
3 $ hg init requirements
4 $ cd requirements
4 $ cd requirements
5
5
6 # LFS not loaded by default.
6 # LFS not loaded by default.
7
7
8 $ hg config extensions
8 $ hg config extensions
9 [1]
9 [1]
10
10
11 # Adding lfs to requires file will auto-load lfs extension.
11 # Adding lfs to requires file will auto-load lfs extension.
12
12
13 $ echo lfs >> .hg/requires
13 $ echo lfs >> .hg/requires
14 $ hg config extensions
14 $ hg config extensions
15 extensions.lfs=
15 extensions.lfs=
16
16
17 # But only if there is no config entry for the extension already.
17 # But only if there is no config entry for the extension already.
18
18
19 $ cat > .hg/hgrc << EOF
19 $ cat > .hg/hgrc << EOF
20 > [extensions]
20 > [extensions]
21 > lfs=!
21 > lfs=!
22 > EOF
22 > EOF
23
23
24 $ hg config extensions
24 $ hg config extensions
25 abort: repository requires features unknown to this Mercurial: lfs!
25 abort: repository requires features unknown to this Mercurial: lfs!
26 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
26 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
27 [255]
27 [255]
28
28
29 $ cat > .hg/hgrc << EOF
29 $ cat > .hg/hgrc << EOF
30 > [extensions]
30 > [extensions]
31 > lfs=
31 > lfs=
32 > EOF
32 > EOF
33
33
34 $ hg config extensions
34 $ hg config extensions
35 extensions.lfs=
35 extensions.lfs=
36
36
37 $ cat > .hg/hgrc << EOF
37 $ cat > .hg/hgrc << EOF
38 > [extensions]
38 > [extensions]
39 > lfs = missing.py
39 > lfs = missing.py
40 > EOF
40 > EOF
41
41
42 $ hg config extensions
42 $ hg config extensions
43 \*\*\* failed to import extension lfs from missing.py: [Errno *] $ENOENT$: 'missing.py' (glob)
43 \*\*\* failed to import extension lfs from missing.py: [Errno *] $ENOENT$: 'missing.py' (glob)
44 abort: repository requires features unknown to this Mercurial: lfs!
44 abort: repository requires features unknown to this Mercurial: lfs!
45 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
45 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
46 [255]
46 [255]
47
47
48 $ cd ..
48 $ cd ..
49
49
50 # Initial setup
50 # Initial setup
51
51
52 $ cat >> $HGRCPATH << EOF
52 $ cat >> $HGRCPATH << EOF
53 > [extensions]
53 > [extensions]
54 > lfs=
54 > lfs=
55 > [lfs]
55 > [lfs]
56 > # Test deprecated config
56 > # Test deprecated config
57 > threshold=1000B
57 > threshold=1000B
58 > EOF
58 > EOF
59
59
60 $ LONG=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
60 $ LONG=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
61
61
62 # Prepare server and enable extension
62 # Prepare server and enable extension
63 $ hg init server
63 $ hg init server
64 $ hg clone -q server client
64 $ hg clone -q server client
65 $ cd client
65 $ cd client
66
66
67 # Commit small file
67 # Commit small file
68 $ echo s > smallfile
68 $ echo s > smallfile
69 $ echo '**.py = LF' > .hgeol
69 $ echo '**.py = LF' > .hgeol
70 $ hg --config lfs.track='"size(\">1000B\")"' commit -Aqm "add small file"
70 $ hg --config lfs.track='"size(\">1000B\")"' commit -Aqm "add small file"
71 hg: parse error: unsupported file pattern: size(">1000B")
71 hg: parse error: unsupported file pattern: size(">1000B")
72 (paths must be prefixed with "path:")
72 (paths must be prefixed with "path:")
73 [255]
73 [255]
74 $ hg --config lfs.track='size(">1000B")' commit -Aqm "add small file"
74 $ hg --config lfs.track='size(">1000B")' commit -Aqm "add small file"
75
75
76 # Commit large file
76 # Commit large file
77 $ echo $LONG > largefile
77 $ echo $LONG > largefile
78 $ grep lfs .hg/requires
78 $ grep lfs .hg/requires
79 [1]
79 [1]
80 $ hg commit --traceback -Aqm "add large file"
80 $ hg commit --traceback -Aqm "add large file"
81 $ grep lfs .hg/requires
81 $ grep lfs .hg/requires
82 lfs
82 lfs
83
83
84 # Ensure metadata is stored
84 # Ensure metadata is stored
85 $ hg debugdata largefile 0
85 $ hg debugdata largefile 0
86 version https://git-lfs.github.com/spec/v1
86 version https://git-lfs.github.com/spec/v1
87 oid sha256:f11e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
87 oid sha256:f11e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
88 size 1501
88 size 1501
89 x-is-binary 0
89 x-is-binary 0
90
90
91 # Check the blobstore is populated
91 # Check the blobstore is populated
92 $ find .hg/store/lfs/objects | sort
92 $ find .hg/store/lfs/objects | sort
93 .hg/store/lfs/objects
93 .hg/store/lfs/objects
94 .hg/store/lfs/objects/f1
94 .hg/store/lfs/objects/f1
95 .hg/store/lfs/objects/f1/1e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
95 .hg/store/lfs/objects/f1/1e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
96
96
97 # Check the blob stored contains the actual contents of the file
97 # Check the blob stored contains the actual contents of the file
98 $ cat .hg/store/lfs/objects/f1/1e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
98 $ cat .hg/store/lfs/objects/f1/1e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
99 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
99 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
100
100
101 # Push changes to the server
101 # Push changes to the server
102
102
103 $ hg push
103 $ hg push
104 pushing to $TESTTMP/server
104 pushing to $TESTTMP/server
105 searching for changes
105 searching for changes
106 abort: lfs.url needs to be configured
106 abort: lfs.url needs to be configured
107 [255]
107 [255]
108
108
109 $ cat >> $HGRCPATH << EOF
109 $ cat >> $HGRCPATH << EOF
110 > [lfs]
110 > [lfs]
111 > url=file:$TESTTMP/dummy-remote/
111 > url=file:$TESTTMP/dummy-remote/
112 > EOF
112 > EOF
113
113
114 Push to a local non-lfs repo with the extension enabled will add the
114 Push to a local non-lfs repo with the extension enabled will add the
115 lfs requirement
115 lfs requirement
116
116
117 $ grep lfs $TESTTMP/server/.hg/requires
117 $ grep lfs $TESTTMP/server/.hg/requires
118 [1]
118 [1]
119 $ hg push -v | egrep -v '^(uncompressed| )'
119 $ hg push -v | egrep -v '^(uncompressed| )'
120 pushing to $TESTTMP/server
120 pushing to $TESTTMP/server
121 searching for changes
121 searching for changes
122 lfs: found f11e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b in the local lfs store
122 lfs: found f11e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b in the local lfs store
123 2 changesets found
123 2 changesets found
124 adding changesets
124 adding changesets
125 adding manifests
125 adding manifests
126 adding file changes
126 adding file changes
127 calling hook pretxnchangegroup.lfs: hgext.lfs.checkrequireslfs
127 calling hook pretxnchangegroup.lfs: hgext.lfs.checkrequireslfs
128 added 2 changesets with 3 changes to 3 files
128 added 2 changesets with 3 changes to 3 files
129 $ grep lfs $TESTTMP/server/.hg/requires
129 $ grep lfs $TESTTMP/server/.hg/requires
130 lfs
130 lfs
131
131
132 # Unknown URL scheme
132 # Unknown URL scheme
133
133
134 $ hg push --config lfs.url=ftp://foobar
134 $ hg push --config lfs.url=ftp://foobar
135 abort: lfs: unknown url scheme: ftp
135 abort: lfs: unknown url scheme: ftp
136 [255]
136 [255]
137
137
138 $ cd ../
138 $ cd ../
139
139
140 # Initialize new client (not cloning) and setup extension
140 # Initialize new client (not cloning) and setup extension
141 $ hg init client2
141 $ hg init client2
142 $ cd client2
142 $ cd client2
143 $ cat >> .hg/hgrc <<EOF
143 $ cat >> .hg/hgrc <<EOF
144 > [paths]
144 > [paths]
145 > default = $TESTTMP/server
145 > default = $TESTTMP/server
146 > EOF
146 > EOF
147
147
148 # Pull from server
148 # Pull from server
149
149
150 Pulling a local lfs repo into a local non-lfs repo with the extension
150 Pulling a local lfs repo into a local non-lfs repo with the extension
151 enabled adds the lfs requirement
151 enabled adds the lfs requirement
152
152
153 $ grep lfs .hg/requires $TESTTMP/server/.hg/requires
153 $ grep lfs .hg/requires $TESTTMP/server/.hg/requires
154 $TESTTMP/server/.hg/requires:lfs
154 $TESTTMP/server/.hg/requires:lfs
155 $ hg pull default
155 $ hg pull default
156 pulling from $TESTTMP/server
156 pulling from $TESTTMP/server
157 requesting all changes
157 requesting all changes
158 adding changesets
158 adding changesets
159 adding manifests
159 adding manifests
160 adding file changes
160 adding file changes
161 added 2 changesets with 3 changes to 3 files
161 added 2 changesets with 3 changes to 3 files
162 new changesets 0ead593177f7:b88141481348
162 new changesets 0ead593177f7:b88141481348
163 (run 'hg update' to get a working copy)
163 (run 'hg update' to get a working copy)
164 $ grep lfs .hg/requires $TESTTMP/server/.hg/requires
164 $ grep lfs .hg/requires $TESTTMP/server/.hg/requires
165 .hg/requires:lfs
165 .hg/requires:lfs
166 $TESTTMP/server/.hg/requires:lfs
166 $TESTTMP/server/.hg/requires:lfs
167
167
168 # Check the blobstore is not yet populated
168 # Check the blobstore is not yet populated
169 $ [ -d .hg/store/lfs/objects ]
169 $ [ -d .hg/store/lfs/objects ]
170 [1]
170 [1]
171
171
172 # Update to the last revision containing the large file
172 # Update to the last revision containing the large file
173 $ hg update
173 $ hg update
174 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
174 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
175
175
176 # Check the blobstore has been populated on update
176 # Check the blobstore has been populated on update
177 $ find .hg/store/lfs/objects | sort
177 $ find .hg/store/lfs/objects | sort
178 .hg/store/lfs/objects
178 .hg/store/lfs/objects
179 .hg/store/lfs/objects/f1
179 .hg/store/lfs/objects/f1
180 .hg/store/lfs/objects/f1/1e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
180 .hg/store/lfs/objects/f1/1e77c257047a398492d8d6cb9f6acf3aa7c4384bb23080b43546053e183e4b
181
181
182 # Check the contents of the file are fetched from blobstore when requested
182 # Check the contents of the file are fetched from blobstore when requested
183 $ hg cat -r . largefile
183 $ hg cat -r . largefile
184 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
184 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
185
185
186 # Check the file has been copied in the working copy
186 # Check the file has been copied in the working copy
187 $ cat largefile
187 $ cat largefile
188 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
188 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
189
189
190 $ cd ..
190 $ cd ..
191
191
192 # Check rename, and switch between large and small files
192 # Check rename, and switch between large and small files
193
193
194 $ hg init repo3
194 $ hg init repo3
195 $ cd repo3
195 $ cd repo3
196 $ cat >> .hg/hgrc << EOF
196 $ cat >> .hg/hgrc << EOF
197 > [lfs]
197 > [lfs]
198 > track=size(">10B")
198 > track=size(">10B")
199 > EOF
199 > EOF
200
200
201 $ echo LONGER-THAN-TEN-BYTES-WILL-TRIGGER-LFS > large
201 $ echo LONGER-THAN-TEN-BYTES-WILL-TRIGGER-LFS > large
202 $ echo SHORTER > small
202 $ echo SHORTER > small
203 $ hg add . -q
203 $ hg add . -q
204 $ hg commit -m 'commit with lfs content'
204 $ hg commit -m 'commit with lfs content'
205
205
206 $ hg files -r . 'set:added()'
206 $ hg files -r . 'set:added()'
207 large
207 large
208 small
208 small
209 $ hg files -r . 'set:added() & lfs()'
209 $ hg files -r . 'set:added() & lfs()'
210 large
210 large
211
211
212 $ hg mv large l
212 $ hg mv large l
213 $ hg mv small s
213 $ hg mv small s
214 $ hg status 'set:removed()'
214 $ hg status 'set:removed()'
215 R large
215 R large
216 R small
216 R small
217 $ hg status 'set:removed() & lfs()'
217 $ hg status 'set:removed() & lfs()'
218 R large
218 R large
219 $ hg commit -m 'renames'
219 $ hg commit -m 'renames'
220
220
221 $ hg files -r . 'set:copied()'
221 $ hg files -r . 'set:copied()'
222 l
222 l
223 s
223 s
224 $ hg files -r . 'set:copied() & lfs()'
224 $ hg files -r . 'set:copied() & lfs()'
225 l
225 l
226 $ hg status --change . 'set:removed()'
226 $ hg status --change . 'set:removed()'
227 R large
227 R large
228 R small
228 R small
229 $ hg status --change . 'set:removed() & lfs()'
229 $ hg status --change . 'set:removed() & lfs()'
230 R large
230 R large
231
231
232 $ echo SHORT > l
232 $ echo SHORT > l
233 $ echo BECOME-LARGER-FROM-SHORTER > s
233 $ echo BECOME-LARGER-FROM-SHORTER > s
234 $ hg commit -m 'large to small, small to large'
234 $ hg commit -m 'large to small, small to large'
235
235
236 $ echo 1 >> l
236 $ echo 1 >> l
237 $ echo 2 >> s
237 $ echo 2 >> s
238 $ hg commit -m 'random modifications'
238 $ hg commit -m 'random modifications'
239
239
240 $ echo RESTORE-TO-BE-LARGE > l
240 $ echo RESTORE-TO-BE-LARGE > l
241 $ echo SHORTER > s
241 $ echo SHORTER > s
242 $ hg commit -m 'switch large and small again'
242 $ hg commit -m 'switch large and small again'
243
243
244 # Test lfs_files template
244 # Test lfs_files template
245
245
246 $ hg log -r 'all()' -T '{rev} {join(lfs_files, ", ")}\n'
246 $ hg log -r 'all()' -T '{rev} {join(lfs_files, ", ")}\n'
247 0 large
247 0 large
248 1 l, large
248 1 l, large
249 2 s
249 2 s
250 3 s
250 3 s
251 4 l
251 4 l
252
252
253 # Push and pull the above repo
253 # Push and pull the above repo
254
254
255 $ hg --cwd .. init repo4
255 $ hg --cwd .. init repo4
256 $ hg push ../repo4
256 $ hg push ../repo4
257 pushing to ../repo4
257 pushing to ../repo4
258 searching for changes
258 searching for changes
259 adding changesets
259 adding changesets
260 adding manifests
260 adding manifests
261 adding file changes
261 adding file changes
262 added 5 changesets with 10 changes to 4 files
262 added 5 changesets with 10 changes to 4 files
263
263
264 $ hg --cwd .. init repo5
264 $ hg --cwd .. init repo5
265 $ hg --cwd ../repo5 pull ../repo3
265 $ hg --cwd ../repo5 pull ../repo3
266 pulling from ../repo3
266 pulling from ../repo3
267 requesting all changes
267 requesting all changes
268 adding changesets
268 adding changesets
269 adding manifests
269 adding manifests
270 adding file changes
270 adding file changes
271 added 5 changesets with 10 changes to 4 files
271 added 5 changesets with 10 changes to 4 files
272 new changesets fd47a419c4f7:5adf850972b9
272 new changesets fd47a419c4f7:5adf850972b9
273 (run 'hg update' to get a working copy)
273 (run 'hg update' to get a working copy)
274
274
275 $ cd ..
275 $ cd ..
276
276
277 # Test clone
277 # Test clone
278
278
279 $ hg init repo6
279 $ hg init repo6
280 $ cd repo6
280 $ cd repo6
281 $ cat >> .hg/hgrc << EOF
281 $ cat >> .hg/hgrc << EOF
282 > [lfs]
282 > [lfs]
283 > track=size(">30B")
283 > track=size(">30B")
284 > EOF
284 > EOF
285
285
286 $ echo LARGE-BECAUSE-IT-IS-MORE-THAN-30-BYTES > large
286 $ echo LARGE-BECAUSE-IT-IS-MORE-THAN-30-BYTES > large
287 $ echo SMALL > small
287 $ echo SMALL > small
288 $ hg commit -Aqm 'create a lfs file' large small
288 $ hg commit -Aqm 'create a lfs file' large small
289 $ hg debuglfsupload -r 'all()' -v
289 $ hg debuglfsupload -r 'all()' -v
290 lfs: found 8e92251415339ae9b148c8da89ed5ec665905166a1ab11b09dca8fad83344738 in the local lfs store
290 lfs: found 8e92251415339ae9b148c8da89ed5ec665905166a1ab11b09dca8fad83344738 in the local lfs store
291
291
292 $ cd ..
292 $ cd ..
293
293
294 $ hg clone repo6 repo7
294 $ hg clone repo6 repo7
295 updating to branch default
295 updating to branch default
296 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
296 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
297 $ cd repo7
297 $ cd repo7
298 $ cat large
298 $ cat large
299 LARGE-BECAUSE-IT-IS-MORE-THAN-30-BYTES
299 LARGE-BECAUSE-IT-IS-MORE-THAN-30-BYTES
300 $ cat small
300 $ cat small
301 SMALL
301 SMALL
302
302
303 $ cd ..
303 $ cd ..
304
304
305 $ hg --config extensions.share= share repo7 sharedrepo
305 $ hg --config extensions.share= share repo7 sharedrepo
306 updating working directory
306 updating working directory
307 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
307 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
308 $ grep lfs sharedrepo/.hg/requires
308 $ grep lfs sharedrepo/.hg/requires
309 lfs
309 lfs
310
310
311 # Test rename and status
311 # Test rename and status
312
312
313 $ hg init repo8
313 $ hg init repo8
314 $ cd repo8
314 $ cd repo8
315 $ cat >> .hg/hgrc << EOF
315 $ cat >> .hg/hgrc << EOF
316 > [lfs]
316 > [lfs]
317 > track=size(">10B")
317 > track=size(">10B")
318 > EOF
318 > EOF
319
319
320 $ echo THIS-IS-LFS-BECAUSE-10-BYTES > a1
320 $ echo THIS-IS-LFS-BECAUSE-10-BYTES > a1
321 $ echo SMALL > a2
321 $ echo SMALL > a2
322 $ hg commit -m a -A a1 a2
322 $ hg commit -m a -A a1 a2
323 $ hg status
323 $ hg status
324 $ hg mv a1 b1
324 $ hg mv a1 b1
325 $ hg mv a2 a1
325 $ hg mv a2 a1
326 $ hg mv b1 a2
326 $ hg mv b1 a2
327 $ hg commit -m b
327 $ hg commit -m b
328 $ hg status
328 $ hg status
329 >>> with open('a2', 'wb') as f:
329 >>> with open('a2', 'wb') as f:
330 ... f.write(b'\1\nSTART-WITH-HG-FILELOG-METADATA') and None
330 ... f.write(b'\1\nSTART-WITH-HG-FILELOG-METADATA') and None
331 >>> with open('a1', 'wb') as f:
331 >>> with open('a1', 'wb') as f:
332 ... f.write(b'\1\nMETA\n') and None
332 ... f.write(b'\1\nMETA\n') and None
333 $ hg commit -m meta
333 $ hg commit -m meta
334 $ hg status
334 $ hg status
335 $ hg log -T '{rev}: {file_copies} | {file_dels} | {file_adds}\n'
335 $ hg log -T '{rev}: {file_copies} | {file_dels} | {file_adds}\n'
336 2: | |
336 2: | |
337 1: a1 (a2)a2 (a1) | |
337 1: a1 (a2)a2 (a1) | |
338 0: | | a1 a2
338 0: | | a1 a2
339
339
340 $ for n in a1 a2; do
340 $ for n in a1 a2; do
341 > for r in 0 1 2; do
341 > for r in 0 1 2; do
342 > printf '\n%s @ %s\n' $n $r
342 > printf '\n%s @ %s\n' $n $r
343 > hg debugdata $n $r
343 > hg debugdata $n $r
344 > done
344 > done
345 > done
345 > done
346
346
347 a1 @ 0
347 a1 @ 0
348 version https://git-lfs.github.com/spec/v1
348 version https://git-lfs.github.com/spec/v1
349 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
349 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
350 size 29
350 size 29
351 x-is-binary 0
351 x-is-binary 0
352
352
353 a1 @ 1
353 a1 @ 1
354 \x01 (esc)
354 \x01 (esc)
355 copy: a2
355 copy: a2
356 copyrev: 50470ad23cf937b1f4b9f80bfe54df38e65b50d9
356 copyrev: 50470ad23cf937b1f4b9f80bfe54df38e65b50d9
357 \x01 (esc)
357 \x01 (esc)
358 SMALL
358 SMALL
359
359
360 a1 @ 2
360 a1 @ 2
361 \x01 (esc)
361 \x01 (esc)
362 \x01 (esc)
362 \x01 (esc)
363 \x01 (esc)
363 \x01 (esc)
364 META
364 META
365
365
366 a2 @ 0
366 a2 @ 0
367 SMALL
367 SMALL
368
368
369 a2 @ 1
369 a2 @ 1
370 version https://git-lfs.github.com/spec/v1
370 version https://git-lfs.github.com/spec/v1
371 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
371 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
372 size 29
372 size 29
373 x-hg-copy a1
373 x-hg-copy a1
374 x-hg-copyrev be23af27908a582af43e5cda209a5a9b319de8d4
374 x-hg-copyrev be23af27908a582af43e5cda209a5a9b319de8d4
375 x-is-binary 0
375 x-is-binary 0
376
376
377 a2 @ 2
377 a2 @ 2
378 version https://git-lfs.github.com/spec/v1
378 version https://git-lfs.github.com/spec/v1
379 oid sha256:876dadc86a8542f9798048f2c47f51dbf8e4359aed883e8ec80c5db825f0d943
379 oid sha256:876dadc86a8542f9798048f2c47f51dbf8e4359aed883e8ec80c5db825f0d943
380 size 32
380 size 32
381 x-is-binary 0
381 x-is-binary 0
382
382
383 # Verify commit hashes include rename metadata
383 # Verify commit hashes include rename metadata
384
384
385 $ hg log -T '{rev}:{node|short} {desc}\n'
385 $ hg log -T '{rev}:{node|short} {desc}\n'
386 2:0fae949de7fa meta
386 2:0fae949de7fa meta
387 1:9cd6bdffdac0 b
387 1:9cd6bdffdac0 b
388 0:7f96794915f7 a
388 0:7f96794915f7 a
389
389
390 $ cd ..
390 $ cd ..
391
391
392 # Test bundle
392 # Test bundle
393
393
394 $ hg init repo9
394 $ hg init repo9
395 $ cd repo9
395 $ cd repo9
396 $ cat >> .hg/hgrc << EOF
396 $ cat >> .hg/hgrc << EOF
397 > [lfs]
397 > [lfs]
398 > track=size(">10B")
398 > track=size(">10B")
399 > [diff]
399 > [diff]
400 > git=1
400 > git=1
401 > EOF
401 > EOF
402
402
403 $ for i in 0 single two three 4; do
403 $ for i in 0 single two three 4; do
404 > echo 'THIS-IS-LFS-'$i > a
404 > echo 'THIS-IS-LFS-'$i > a
405 > hg commit -m a-$i -A a
405 > hg commit -m a-$i -A a
406 > done
406 > done
407
407
408 $ hg update 2 -q
408 $ hg update 2 -q
409 $ echo 'THIS-IS-LFS-2-CHILD' > a
409 $ echo 'THIS-IS-LFS-2-CHILD' > a
410 $ hg commit -m branching -q
410 $ hg commit -m branching -q
411
411
412 $ hg bundle --base 1 bundle.hg -v
412 $ hg bundle --base 1 bundle.hg -v
413 lfs: found 5ab7a3739a5feec94a562d070a14f36dba7cad17e5484a4a89eea8e5f3166888 in the local lfs store
413 lfs: found 5ab7a3739a5feec94a562d070a14f36dba7cad17e5484a4a89eea8e5f3166888 in the local lfs store
414 lfs: found a9c7d1cd6ce2b9bbdf46ed9a862845228717b921c089d0d42e3bcaed29eb612e in the local lfs store
414 lfs: found a9c7d1cd6ce2b9bbdf46ed9a862845228717b921c089d0d42e3bcaed29eb612e in the local lfs store
415 lfs: found f693890c49c409ec33673b71e53f297681f76c1166daf33b2ad7ebf8b1d3237e in the local lfs store
415 lfs: found f693890c49c409ec33673b71e53f297681f76c1166daf33b2ad7ebf8b1d3237e in the local lfs store
416 lfs: found fda198fea753eb66a252e9856915e1f5cddbe41723bd4b695ece2604ad3c9f75 in the local lfs store
416 lfs: found fda198fea753eb66a252e9856915e1f5cddbe41723bd4b695ece2604ad3c9f75 in the local lfs store
417 4 changesets found
417 4 changesets found
418 uncompressed size of bundle content:
418 uncompressed size of bundle content:
419 * (changelog) (glob)
419 * (changelog) (glob)
420 * (manifests) (glob)
420 * (manifests) (glob)
421 * a (glob)
421 * a (glob)
422 $ hg --config extensions.strip= strip -r 2 --no-backup --force -q
422 $ hg --config extensions.strip= strip -r 2 --no-backup --force -q
423 $ hg -R bundle.hg log -p -T '{rev} {desc}\n' a
423 $ hg -R bundle.hg log -p -T '{rev} {desc}\n' a
424 5 branching
424 5 branching
425 diff --git a/a b/a
425 diff --git a/a b/a
426 --- a/a
426 --- a/a
427 +++ b/a
427 +++ b/a
428 @@ -1,1 +1,1 @@
428 @@ -1,1 +1,1 @@
429 -THIS-IS-LFS-two
429 -THIS-IS-LFS-two
430 +THIS-IS-LFS-2-CHILD
430 +THIS-IS-LFS-2-CHILD
431
431
432 4 a-4
432 4 a-4
433 diff --git a/a b/a
433 diff --git a/a b/a
434 --- a/a
434 --- a/a
435 +++ b/a
435 +++ b/a
436 @@ -1,1 +1,1 @@
436 @@ -1,1 +1,1 @@
437 -THIS-IS-LFS-three
437 -THIS-IS-LFS-three
438 +THIS-IS-LFS-4
438 +THIS-IS-LFS-4
439
439
440 3 a-three
440 3 a-three
441 diff --git a/a b/a
441 diff --git a/a b/a
442 --- a/a
442 --- a/a
443 +++ b/a
443 +++ b/a
444 @@ -1,1 +1,1 @@
444 @@ -1,1 +1,1 @@
445 -THIS-IS-LFS-two
445 -THIS-IS-LFS-two
446 +THIS-IS-LFS-three
446 +THIS-IS-LFS-three
447
447
448 2 a-two
448 2 a-two
449 diff --git a/a b/a
449 diff --git a/a b/a
450 --- a/a
450 --- a/a
451 +++ b/a
451 +++ b/a
452 @@ -1,1 +1,1 @@
452 @@ -1,1 +1,1 @@
453 -THIS-IS-LFS-single
453 -THIS-IS-LFS-single
454 +THIS-IS-LFS-two
454 +THIS-IS-LFS-two
455
455
456 1 a-single
456 1 a-single
457 diff --git a/a b/a
457 diff --git a/a b/a
458 --- a/a
458 --- a/a
459 +++ b/a
459 +++ b/a
460 @@ -1,1 +1,1 @@
460 @@ -1,1 +1,1 @@
461 -THIS-IS-LFS-0
461 -THIS-IS-LFS-0
462 +THIS-IS-LFS-single
462 +THIS-IS-LFS-single
463
463
464 0 a-0
464 0 a-0
465 diff --git a/a b/a
465 diff --git a/a b/a
466 new file mode 100644
466 new file mode 100644
467 --- /dev/null
467 --- /dev/null
468 +++ b/a
468 +++ b/a
469 @@ -0,0 +1,1 @@
469 @@ -0,0 +1,1 @@
470 +THIS-IS-LFS-0
470 +THIS-IS-LFS-0
471
471
472 $ hg bundle -R bundle.hg --base 1 bundle-again.hg -q
472 $ hg bundle -R bundle.hg --base 1 bundle-again.hg -q
473 $ hg -R bundle-again.hg log -p -T '{rev} {desc}\n' a
473 $ hg -R bundle-again.hg log -p -T '{rev} {desc}\n' a
474 5 branching
474 5 branching
475 diff --git a/a b/a
475 diff --git a/a b/a
476 --- a/a
476 --- a/a
477 +++ b/a
477 +++ b/a
478 @@ -1,1 +1,1 @@
478 @@ -1,1 +1,1 @@
479 -THIS-IS-LFS-two
479 -THIS-IS-LFS-two
480 +THIS-IS-LFS-2-CHILD
480 +THIS-IS-LFS-2-CHILD
481
481
482 4 a-4
482 4 a-4
483 diff --git a/a b/a
483 diff --git a/a b/a
484 --- a/a
484 --- a/a
485 +++ b/a
485 +++ b/a
486 @@ -1,1 +1,1 @@
486 @@ -1,1 +1,1 @@
487 -THIS-IS-LFS-three
487 -THIS-IS-LFS-three
488 +THIS-IS-LFS-4
488 +THIS-IS-LFS-4
489
489
490 3 a-three
490 3 a-three
491 diff --git a/a b/a
491 diff --git a/a b/a
492 --- a/a
492 --- a/a
493 +++ b/a
493 +++ b/a
494 @@ -1,1 +1,1 @@
494 @@ -1,1 +1,1 @@
495 -THIS-IS-LFS-two
495 -THIS-IS-LFS-two
496 +THIS-IS-LFS-three
496 +THIS-IS-LFS-three
497
497
498 2 a-two
498 2 a-two
499 diff --git a/a b/a
499 diff --git a/a b/a
500 --- a/a
500 --- a/a
501 +++ b/a
501 +++ b/a
502 @@ -1,1 +1,1 @@
502 @@ -1,1 +1,1 @@
503 -THIS-IS-LFS-single
503 -THIS-IS-LFS-single
504 +THIS-IS-LFS-two
504 +THIS-IS-LFS-two
505
505
506 1 a-single
506 1 a-single
507 diff --git a/a b/a
507 diff --git a/a b/a
508 --- a/a
508 --- a/a
509 +++ b/a
509 +++ b/a
510 @@ -1,1 +1,1 @@
510 @@ -1,1 +1,1 @@
511 -THIS-IS-LFS-0
511 -THIS-IS-LFS-0
512 +THIS-IS-LFS-single
512 +THIS-IS-LFS-single
513
513
514 0 a-0
514 0 a-0
515 diff --git a/a b/a
515 diff --git a/a b/a
516 new file mode 100644
516 new file mode 100644
517 --- /dev/null
517 --- /dev/null
518 +++ b/a
518 +++ b/a
519 @@ -0,0 +1,1 @@
519 @@ -0,0 +1,1 @@
520 +THIS-IS-LFS-0
520 +THIS-IS-LFS-0
521
521
522 $ cd ..
522 $ cd ..
523
523
524 # Test isbinary
524 # Test isbinary
525
525
526 $ hg init repo10
526 $ hg init repo10
527 $ cd repo10
527 $ cd repo10
528 $ cat >> .hg/hgrc << EOF
528 $ cat >> .hg/hgrc << EOF
529 > [extensions]
529 > [extensions]
530 > lfs=
530 > lfs=
531 > [lfs]
531 > [lfs]
532 > track=all()
532 > track=all()
533 > EOF
533 > EOF
534 $ "$PYTHON" <<'EOF'
534 $ "$PYTHON" <<'EOF'
535 > def write(path, content):
535 > def write(path, content):
536 > with open(path, 'wb') as f:
536 > with open(path, 'wb') as f:
537 > f.write(content)
537 > f.write(content)
538 > write('a', b'\0\0')
538 > write('a', b'\0\0')
539 > write('b', b'\1\n')
539 > write('b', b'\1\n')
540 > write('c', b'\1\n\0')
540 > write('c', b'\1\n\0')
541 > write('d', b'xx')
541 > write('d', b'xx')
542 > EOF
542 > EOF
543 $ hg add a b c d
543 $ hg add a b c d
544 $ hg diff --stat
544 $ hg diff --stat
545 a | Bin
545 a | Bin
546 b | 1 +
546 b | 1 +
547 c | Bin
547 c | Bin
548 d | 1 +
548 d | 1 +
549 4 files changed, 2 insertions(+), 0 deletions(-)
549 4 files changed, 2 insertions(+), 0 deletions(-)
550 $ hg commit -m binarytest
550 $ hg commit -m binarytest
551 $ cat > $TESTTMP/dumpbinary.py << EOF
551 $ cat > $TESTTMP/dumpbinary.py << EOF
552 > from mercurial.utils import (
552 > from mercurial.utils import (
553 > stringutil,
553 > stringutil,
554 > )
554 > )
555 > def reposetup(ui, repo):
555 > def reposetup(ui, repo):
556 > for n in (b'a', b'b', b'c', b'd'):
556 > for n in (b'a', b'b', b'c', b'd'):
557 > ui.write((b'%s: binary=%s\n')
557 > ui.write((b'%s: binary=%s\n')
558 > % (n, stringutil.pprint(repo[b'.'][n].isbinary())))
558 > % (n, stringutil.pprint(repo[b'.'][n].isbinary())))
559 > EOF
559 > EOF
560 $ hg --config extensions.dumpbinary=$TESTTMP/dumpbinary.py id --trace
560 $ hg --config extensions.dumpbinary=$TESTTMP/dumpbinary.py id --trace
561 a: binary=True
561 a: binary=True
562 b: binary=False
562 b: binary=False
563 c: binary=True
563 c: binary=True
564 d: binary=False
564 d: binary=False
565 b55353847f02 tip
565 b55353847f02 tip
566
566
567 Binary blobs don't need to be present to be skipped in filesets. (And their
567 Binary blobs don't need to be present to be skipped in filesets. (And their
568 absence doesn't cause an abort.)
568 absence doesn't cause an abort.)
569
569
570 $ rm .hg/store/lfs/objects/96/a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7
570 $ rm .hg/store/lfs/objects/96/a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7
571 $ rm .hg/store/lfs/objects/92/f76135a4baf4faccb8586a60faf830c2bdfce147cefa188aaf4b790bd01b7e
571 $ rm .hg/store/lfs/objects/92/f76135a4baf4faccb8586a60faf830c2bdfce147cefa188aaf4b790bd01b7e
572
572
573 $ hg files --debug -r . 'set:eol("unix")' --config 'experimental.lfs.disableusercache=True'
573 $ hg files --debug -r . 'set:eol("unix")' --config 'experimental.lfs.disableusercache=True'
574 lfs: found c04b5bb1a5b2eb3e9cd4805420dba5a9d133da5b7adeeafb5474c4adae9faa80 in the local lfs store
574 lfs: found c04b5bb1a5b2eb3e9cd4805420dba5a9d133da5b7adeeafb5474c4adae9faa80 in the local lfs store
575 2 b
575 2 b
576 lfs: found 5dde896887f6754c9b15bfe3a441ae4806df2fde94001311e08bf110622e0bbe in the local lfs store
576 lfs: found 5dde896887f6754c9b15bfe3a441ae4806df2fde94001311e08bf110622e0bbe in the local lfs store
577
577
578 $ hg files --debug -r . 'set:binary()' --config 'experimental.lfs.disableusercache=True'
578 $ hg files --debug -r . 'set:binary()' --config 'experimental.lfs.disableusercache=True'
579 2 a
579 2 a
580 3 c
580 3 c
581
581
582 $ cd ..
582 $ cd ..
583
583
584 # Test fctx.cmp fastpath - diff without LFS blobs
584 # Test fctx.cmp fastpath - diff without LFS blobs
585
585
586 $ hg init repo12
586 $ hg init repo12
587 $ cd repo12
587 $ cd repo12
588 $ cat >> .hg/hgrc <<EOF
588 $ cat >> .hg/hgrc <<EOF
589 > [lfs]
589 > [lfs]
590 > threshold=1
590 > threshold=1
591 > EOF
591 > EOF
592 $ cat > ../patch.diff <<EOF
592 $ cat > ../patch.diff <<EOF
593 > # HG changeset patch
593 > # HG changeset patch
594 > 2
594 > 2
595 >
595 >
596 > diff --git a/a b/a
596 > diff --git a/a b/a
597 > old mode 100644
597 > old mode 100644
598 > new mode 100755
598 > new mode 100755
599 > EOF
599 > EOF
600
600
601 $ for i in 1 2 3; do
601 $ for i in 1 2 3; do
602 > cp ../repo10/a a
602 > cp ../repo10/a a
603 > if [ $i = 3 ]; then
603 > if [ $i = 3 ]; then
604 > # make a content-only change
604 > # make a content-only change
605 > hg import -q --bypass ../patch.diff
605 > hg import -q --bypass ../patch.diff
606 > hg update -q
606 > hg update -q
607 > rm ../patch.diff
607 > rm ../patch.diff
608 > else
608 > else
609 > echo $i >> a
609 > echo $i >> a
610 > hg commit -m $i -A a
610 > hg commit -m $i -A a
611 > fi
611 > fi
612 > done
612 > done
613 $ [ -d .hg/store/lfs/objects ]
613 $ [ -d .hg/store/lfs/objects ]
614
614
615 $ cd ..
615 $ cd ..
616
616
617 $ hg clone repo12 repo13 --noupdate
617 $ hg clone repo12 repo13 --noupdate
618 $ cd repo13
618 $ cd repo13
619 $ hg log --removed -p a -T '{desc}\n' --config diff.nobinary=1 --git
619 $ hg log --removed -p a -T '{desc}\n' --config diff.nobinary=1 --git
620 2
620 2
621 diff --git a/a b/a
621 diff --git a/a b/a
622 old mode 100644
622 old mode 100644
623 new mode 100755
623 new mode 100755
624
624
625 2
625 2
626 diff --git a/a b/a
626 diff --git a/a b/a
627 Binary file a has changed
627 Binary file a has changed
628
628
629 1
629 1
630 diff --git a/a b/a
630 diff --git a/a b/a
631 new file mode 100644
631 new file mode 100644
632 Binary file a has changed
632 Binary file a has changed
633
633
634 $ [ -d .hg/store/lfs/objects ]
634 $ [ -d .hg/store/lfs/objects ]
635 [1]
635 [1]
636
636
637 $ cd ..
637 $ cd ..
638
638
639 # Test filter
639 # Test filter
640
640
641 $ hg init repo11
641 $ hg init repo11
642 $ cd repo11
642 $ cd repo11
643 $ cat >> .hg/hgrc << EOF
643 $ cat >> .hg/hgrc << EOF
644 > [lfs]
644 > [lfs]
645 > track=(**.a & size(">5B")) | (**.b & !size(">5B"))
645 > track=(**.a & size(">5B")) | (**.b & !size(">5B"))
646 > | (**.c & "path:d" & !"path:d/c.c") | size(">10B")
646 > | (**.c & "path:d" & !"path:d/c.c") | size(">10B")
647 > EOF
647 > EOF
648
648
649 $ mkdir a
649 $ mkdir a
650 $ echo aaaaaa > a/1.a
650 $ echo aaaaaa > a/1.a
651 $ echo a > a/2.a
651 $ echo a > a/2.a
652 $ echo aaaaaa > 1.b
652 $ echo aaaaaa > 1.b
653 $ echo a > 2.b
653 $ echo a > 2.b
654 $ echo a > 1.c
654 $ echo a > 1.c
655 $ mkdir d
655 $ mkdir d
656 $ echo a > d/c.c
656 $ echo a > d/c.c
657 $ echo a > d/d.c
657 $ echo a > d/d.c
658 $ echo aaaaaaaaaaaa > x
658 $ echo aaaaaaaaaaaa > x
659 $ hg add . -q
659 $ hg add . -q
660 $ hg commit -m files
660 $ hg commit -m files
661
661
662 $ for p in a/1.a a/2.a 1.b 2.b 1.c d/c.c d/d.c x; do
662 $ for p in a/1.a a/2.a 1.b 2.b 1.c d/c.c d/d.c x; do
663 > if hg debugdata $p 0 2>&1 | grep git-lfs >/dev/null; then
663 > if hg debugdata $p 0 2>&1 | grep git-lfs >/dev/null; then
664 > echo "${p}: is lfs"
664 > echo "${p}: is lfs"
665 > else
665 > else
666 > echo "${p}: not lfs"
666 > echo "${p}: not lfs"
667 > fi
667 > fi
668 > done
668 > done
669 a/1.a: is lfs
669 a/1.a: is lfs
670 a/2.a: not lfs
670 a/2.a: not lfs
671 1.b: not lfs
671 1.b: not lfs
672 2.b: is lfs
672 2.b: is lfs
673 1.c: not lfs
673 1.c: not lfs
674 d/c.c: not lfs
674 d/c.c: not lfs
675 d/d.c: is lfs
675 d/d.c: is lfs
676 x: is lfs
676 x: is lfs
677
677
678 $ cd ..
678 $ cd ..
679
679
680 # Verify the repos
680 # Verify the repos
681
681
682 $ cat > $TESTTMP/dumpflog.py << EOF
682 $ cat > $TESTTMP/dumpflog.py << EOF
683 > # print raw revision sizes, flags, and hashes for certain files
683 > # print raw revision sizes, flags, and hashes for certain files
684 > import hashlib
684 > import hashlib
685 > from mercurial.node import short
685 > from mercurial.node import short
686 > from mercurial import (
686 > from mercurial import (
687 > pycompat,
687 > pycompat,
688 > revlog,
688 > revlog,
689 > )
689 > )
690 > from mercurial.utils import (
690 > from mercurial.utils import (
691 > stringutil,
691 > stringutil,
692 > )
692 > )
693 > def hash(rawtext):
693 > def hash(rawtext):
694 > h = hashlib.sha512()
694 > h = hashlib.sha512()
695 > h.update(rawtext)
695 > h.update(rawtext)
696 > return pycompat.sysbytes(h.hexdigest()[:4])
696 > return pycompat.sysbytes(h.hexdigest()[:4])
697 > def reposetup(ui, repo):
697 > def reposetup(ui, repo):
698 > # these 2 files are interesting
698 > # these 2 files are interesting
699 > for name in [b'l', b's']:
699 > for name in [b'l', b's']:
700 > fl = repo.file(name)
700 > fl = repo.file(name)
701 > if len(fl) == 0:
701 > if len(fl) == 0:
702 > continue
702 > continue
703 > sizes = [fl._revlog.rawsize(i) for i in fl]
703 > sizes = [fl._revlog.rawsize(i) for i in fl]
704 > texts = [fl.rawdata(i) for i in fl]
704 > texts = [fl.rawdata(i) for i in fl]
705 > flags = [int(fl._revlog.flags(i)) for i in fl]
705 > flags = [int(fl._revlog.flags(i)) for i in fl]
706 > hashes = [hash(t) for t in texts]
706 > hashes = [hash(t) for t in texts]
707 > pycompat.stdout.write(b' %s: rawsizes=%r flags=%r hashes=%s\n'
707 > pycompat.stdout.write(b' %s: rawsizes=%r flags=%r hashes=%s\n'
708 > % (name, sizes, flags, stringutil.pprint(hashes)))
708 > % (name, sizes, flags, stringutil.pprint(hashes)))
709 > EOF
709 > EOF
710
710
711 $ for i in client client2 server repo3 repo4 repo5 repo6 repo7 repo8 repo9 \
711 $ for i in client client2 server repo3 repo4 repo5 repo6 repo7 repo8 repo9 \
712 > repo10; do
712 > repo10; do
713 > echo 'repo:' $i
713 > echo 'repo:' $i
714 > hg --cwd $i verify --config extensions.dumpflog=$TESTTMP/dumpflog.py -q
714 > hg --cwd $i verify --config extensions.dumpflog=$TESTTMP/dumpflog.py -q
715 > done
715 > done
716 repo: client
716 repo: client
717 repo: client2
717 repo: client2
718 repo: server
718 repo: server
719 repo: repo3
719 repo: repo3
720 l: rawsizes=[211, 6, 8, 141] flags=[8192, 0, 0, 8192] hashes=['d2b8', '948c', 'cc88', '724d']
720 l: rawsizes=[211, 6, 8, 141] flags=[8192, 0, 0, 8192] hashes=['d2b8', '948c', 'cc88', '724d']
721 s: rawsizes=[74, 141, 141, 8] flags=[0, 8192, 8192, 0] hashes=['3c80', 'fce0', '874a', '826b']
721 s: rawsizes=[74, 141, 141, 8] flags=[0, 8192, 8192, 0] hashes=['3c80', 'fce0', '874a', '826b']
722 repo: repo4
722 repo: repo4
723 l: rawsizes=[211, 6, 8, 141] flags=[8192, 0, 0, 8192] hashes=['d2b8', '948c', 'cc88', '724d']
723 l: rawsizes=[211, 6, 8, 141] flags=[8192, 0, 0, 8192] hashes=['d2b8', '948c', 'cc88', '724d']
724 s: rawsizes=[74, 141, 141, 8] flags=[0, 8192, 8192, 0] hashes=['3c80', 'fce0', '874a', '826b']
724 s: rawsizes=[74, 141, 141, 8] flags=[0, 8192, 8192, 0] hashes=['3c80', 'fce0', '874a', '826b']
725 repo: repo5
725 repo: repo5
726 l: rawsizes=[211, 6, 8, 141] flags=[8192, 0, 0, 8192] hashes=['d2b8', '948c', 'cc88', '724d']
726 l: rawsizes=[211, 6, 8, 141] flags=[8192, 0, 0, 8192] hashes=['d2b8', '948c', 'cc88', '724d']
727 s: rawsizes=[74, 141, 141, 8] flags=[0, 8192, 8192, 0] hashes=['3c80', 'fce0', '874a', '826b']
727 s: rawsizes=[74, 141, 141, 8] flags=[0, 8192, 8192, 0] hashes=['3c80', 'fce0', '874a', '826b']
728 repo: repo6
728 repo: repo6
729 repo: repo7
729 repo: repo7
730 repo: repo8
730 repo: repo8
731 repo: repo9
731 repo: repo9
732 repo: repo10
732 repo: repo10
733
733
734 repo13 doesn't have any cached lfs files and its source never pushed its
734 repo13 doesn't have any cached lfs files and its source never pushed its
735 files. Therefore, the files don't exist in the remote store. Use the files in
735 files. Therefore, the files don't exist in the remote store. Use the files in
736 the user cache.
736 the user cache.
737
737
738 $ test -d $TESTTMP/repo13/.hg/store/lfs/objects
738 $ test -d $TESTTMP/repo13/.hg/store/lfs/objects
739 [1]
739 [1]
740
740
741 $ hg --config extensions.share= share repo13 repo14
741 $ hg --config extensions.share= share repo13 repo14
742 updating working directory
742 updating working directory
743 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
743 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
744 $ hg -R repo14 -q verify
744 $ hg -R repo14 -q verify
745
745
746 $ hg clone repo13 repo15
746 $ hg clone repo13 repo15
747 updating to branch default
747 updating to branch default
748 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
748 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
749 $ hg -R repo15 -q verify
749 $ hg -R repo15 -q verify
750
750
751 If the source repo doesn't have the blob (maybe it was pulled or cloned with
751 If the source repo doesn't have the blob (maybe it was pulled or cloned with
752 --noupdate), the blob is still accessible via the global cache to send to the
752 --noupdate), the blob is still accessible via the global cache to send to the
753 remote store.
753 remote store.
754
754
755 $ rm -rf $TESTTMP/repo15/.hg/store/lfs
755 $ rm -rf $TESTTMP/repo15/.hg/store/lfs
756 $ hg init repo16
756 $ hg init repo16
757 $ hg -R repo15 push repo16
757 $ hg -R repo15 push repo16
758 pushing to repo16
758 pushing to repo16
759 searching for changes
759 searching for changes
760 adding changesets
760 adding changesets
761 adding manifests
761 adding manifests
762 adding file changes
762 adding file changes
763 added 3 changesets with 2 changes to 1 files
763 added 3 changesets with 2 changes to 1 files
764 $ hg -R repo15 -q verify
764 $ hg -R repo15 -q verify
765
765
766 Test damaged file scenarios. (This also damages the usercache because of the
766 Test damaged file scenarios. (This also damages the usercache because of the
767 hardlinks.)
767 hardlinks.)
768
768
769 $ echo 'damage' >> repo5/.hg/store/lfs/objects/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
769 $ echo 'damage' >> repo5/.hg/store/lfs/objects/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
770
770
771 Repo with damaged lfs objects in any revision will fail verification.
771 Repo with damaged lfs objects in any revision will fail verification.
772
772
773 $ hg -R repo5 verify
773 $ hg -R repo5 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 checked 5 changesets with 10 changes to 4 files
780 checked 5 changesets with 10 changes to 4 files
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 Updates work after cloning a damaged repo, if the damaged lfs objects aren't in
785 Updates work after cloning a damaged repo, if the damaged lfs objects aren't in
786 the update destination. Those objects won't be added to the new repo's store
786 the update destination. Those objects won't be added to the new repo's store
787 because they aren't accessed.
787 because they aren't accessed.
788
788
789 $ hg clone -v repo5 fromcorrupt
789 $ hg clone -v repo5 fromcorrupt
790 updating to branch default
790 updating to branch default
791 resolving manifests
791 resolving manifests
792 getting l
792 getting l
793 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the usercache
793 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the usercache
794 getting s
794 getting s
795 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
795 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
796 $ test -f fromcorrupt/.hg/store/lfs/objects/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
796 $ test -f fromcorrupt/.hg/store/lfs/objects/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
797 [1]
797 [1]
798
798
799 Verify will not try to download lfs blobs, if told not to process lfs content
800
801 $ hg -R fromcorrupt --config lfs.usercache=emptycache verify -v --no-lfs
802 repository uses revlog format 1
803 checking changesets
804 checking manifests
805 crosschecking files in changesets and manifests
806 checking files
807 checked 5 changesets with 10 changes to 4 files
808
809 Verify will not try to download lfs blobs, if told not to by the config option
810
811 $ hg -R fromcorrupt --config lfs.usercache=emptycache verify -v \
812 > --config verify.skipflags=8192
813 repository uses revlog format 1
814 checking changesets
815 checking manifests
816 crosschecking files in changesets and manifests
817 checking files
818 checked 5 changesets with 10 changes to 4 files
819
799 Verify will copy/link all lfs objects into the local store that aren't already
820 Verify will copy/link all lfs objects into the local store that aren't already
800 present. Bypass the corrupted usercache to show that verify works when fed by
821 present. Bypass the corrupted usercache to show that verify works when fed by
801 the (uncorrupted) remote store.
822 the (uncorrupted) remote store.
802
823
803 $ hg -R fromcorrupt --config lfs.usercache=emptycache verify -v
824 $ hg -R fromcorrupt --config lfs.usercache=emptycache verify -v
804 repository uses revlog format 1
825 repository uses revlog format 1
805 checking changesets
826 checking changesets
806 checking manifests
827 checking manifests
807 crosschecking files in changesets and manifests
828 crosschecking files in changesets and manifests
808 checking files
829 checking files
809 lfs: adding 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e to the usercache
830 lfs: adding 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e to the usercache
810 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the local lfs store
831 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the local lfs store
811 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
832 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
812 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the local lfs store
833 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the local lfs store
813 lfs: adding 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 to the usercache
834 lfs: adding 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 to the usercache
814 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
835 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
815 lfs: adding b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c to the usercache
836 lfs: adding b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c to the usercache
816 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
837 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
817 checked 5 changesets with 10 changes to 4 files
838 checked 5 changesets with 10 changes to 4 files
818
839
819 Verify will not copy/link a corrupted file from the usercache into the local
840 Verify will not copy/link a corrupted file from the usercache into the local
820 store, and poison it. (The verify with a good remote now works.)
841 store, and poison it. (The verify with a good remote now works.)
821
842
822 $ rm -r fromcorrupt/.hg/store/lfs/objects/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
843 $ rm -r fromcorrupt/.hg/store/lfs/objects/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
823 $ hg -R fromcorrupt verify -v
844 $ hg -R fromcorrupt verify -v
824 repository uses revlog format 1
845 repository uses revlog format 1
825 checking changesets
846 checking changesets
826 checking manifests
847 checking manifests
827 crosschecking files in changesets and manifests
848 crosschecking files in changesets and manifests
828 checking files
849 checking files
829 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
850 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
830 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
851 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
831 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
852 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
832 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
853 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
833 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
854 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
834 checked 5 changesets with 10 changes to 4 files
855 checked 5 changesets with 10 changes to 4 files
835 2 integrity errors encountered!
856 2 integrity errors encountered!
836 (first damaged changeset appears to be 0)
857 (first damaged changeset appears to be 0)
837 [1]
858 [1]
838 $ hg -R fromcorrupt --config lfs.usercache=emptycache verify -v
859 $ hg -R fromcorrupt --config lfs.usercache=emptycache verify -v
839 repository uses revlog format 1
860 repository uses revlog format 1
840 checking changesets
861 checking changesets
841 checking manifests
862 checking manifests
842 crosschecking files in changesets and manifests
863 crosschecking files in changesets and manifests
843 checking files
864 checking files
844 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the usercache
865 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the usercache
845 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
866 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
846 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the local lfs store
867 lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the local lfs store
847 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
868 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
848 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
869 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
849 checked 5 changesets with 10 changes to 4 files
870 checked 5 changesets with 10 changes to 4 files
850
871
851 Damaging a file required by the update destination fails the update.
872 Damaging a file required by the update destination fails the update.
852
873
853 $ echo 'damage' >> $TESTTMP/dummy-remote/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
874 $ echo 'damage' >> $TESTTMP/dummy-remote/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
854 $ hg --config lfs.usercache=emptycache clone -v repo5 fromcorrupt2
875 $ hg --config lfs.usercache=emptycache clone -v repo5 fromcorrupt2
855 updating to branch default
876 updating to branch default
856 resolving manifests
877 resolving manifests
857 abort: corrupt remote lfs object: 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
878 abort: corrupt remote lfs object: 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
858 [255]
879 [255]
859
880
860 A corrupted lfs blob is not transferred from a file://remotestore to the
881 A corrupted lfs blob is not transferred from a file://remotestore to the
861 usercache or local store.
882 usercache or local store.
862
883
863 $ test -f emptycache/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
884 $ test -f emptycache/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
864 [1]
885 [1]
865 $ test -f fromcorrupt2/.hg/store/lfs/objects/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
886 $ test -f fromcorrupt2/.hg/store/lfs/objects/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
866 [1]
887 [1]
867
888
868 $ hg -R fromcorrupt2 verify
889 $ hg -R fromcorrupt2 verify
869 checking changesets
890 checking changesets
870 checking manifests
891 checking manifests
871 crosschecking files in changesets and manifests
892 crosschecking files in changesets and manifests
872 checking files
893 checking files
873 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
894 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
874 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
895 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
875 checked 5 changesets with 10 changes to 4 files
896 checked 5 changesets with 10 changes to 4 files
876 2 integrity errors encountered!
897 2 integrity errors encountered!
877 (first damaged changeset appears to be 0)
898 (first damaged changeset appears to be 0)
878 [1]
899 [1]
879
900
880 Corrupt local files are not sent upstream. (The alternate dummy remote
901 Corrupt local files are not sent upstream. (The alternate dummy remote
881 avoids the corrupt lfs object in the original remote.)
902 avoids the corrupt lfs object in the original remote.)
882
903
883 $ mkdir $TESTTMP/dummy-remote2
904 $ mkdir $TESTTMP/dummy-remote2
884 $ hg init dest
905 $ hg init dest
885 $ hg -R fromcorrupt2 --config lfs.url=file:///$TESTTMP/dummy-remote2 push -v dest
906 $ hg -R fromcorrupt2 --config lfs.url=file:///$TESTTMP/dummy-remote2 push -v dest
886 pushing to dest
907 pushing to dest
887 searching for changes
908 searching for changes
888 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
909 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
889 abort: detected corrupt lfs object: 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
910 abort: detected corrupt lfs object: 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
890 (run hg verify)
911 (run hg verify)
891 [255]
912 [255]
892
913
893 $ hg -R fromcorrupt2 --config lfs.url=file:///$TESTTMP/dummy-remote2 verify -v
914 $ hg -R fromcorrupt2 --config lfs.url=file:///$TESTTMP/dummy-remote2 verify -v
894 repository uses revlog format 1
915 repository uses revlog format 1
895 checking changesets
916 checking changesets
896 checking manifests
917 checking manifests
897 crosschecking files in changesets and manifests
918 crosschecking files in changesets and manifests
898 checking files
919 checking files
899 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
920 l@1: unpacking 46a2f24864bc: integrity check failed on data/l.i:0
900 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
921 lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
901 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
922 large@0: unpacking 2c531e0992ff: integrity check failed on data/large.i:0
902 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
923 lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
903 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
924 lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
904 checked 5 changesets with 10 changes to 4 files
925 checked 5 changesets with 10 changes to 4 files
905 2 integrity errors encountered!
926 2 integrity errors encountered!
906 (first damaged changeset appears to be 0)
927 (first damaged changeset appears to be 0)
907 [1]
928 [1]
908
929
909 $ cat $TESTTMP/dummy-remote2/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b | $TESTDIR/f --sha256
930 $ cat $TESTTMP/dummy-remote2/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b | $TESTDIR/f --sha256
910 sha256=22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
931 sha256=22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
911 $ cat fromcorrupt2/.hg/store/lfs/objects/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b | $TESTDIR/f --sha256
932 $ cat fromcorrupt2/.hg/store/lfs/objects/22/f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b | $TESTDIR/f --sha256
912 sha256=22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
933 sha256=22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b
913 $ test -f $TESTTMP/dummy-remote2/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
934 $ test -f $TESTTMP/dummy-remote2/66/100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
914 [1]
935 [1]
915
936
916 Accessing a corrupt file will complain
937 Accessing a corrupt file will complain
917
938
918 $ hg --cwd fromcorrupt2 cat -r 0 large
939 $ hg --cwd fromcorrupt2 cat -r 0 large
919 abort: integrity check failed on data/large.i:0!
940 abort: integrity check failed on data/large.i:0!
920 [255]
941 [255]
921
942
922 lfs -> normal -> lfs round trip conversions are possible. The 'none()'
943 lfs -> normal -> lfs round trip conversions are possible. The 'none()'
923 predicate on the command line will override whatever is configured globally and
944 predicate on the command line will override whatever is configured globally and
924 locally, and ensures everything converts to a regular file. For lfs -> normal,
945 locally, and ensures everything converts to a regular file. For lfs -> normal,
925 there's no 'lfs' destination repo requirement. For normal -> lfs, there is.
946 there's no 'lfs' destination repo requirement. For normal -> lfs, there is.
926
947
927 $ hg --config extensions.convert= --config 'lfs.track=none()' \
948 $ hg --config extensions.convert= --config 'lfs.track=none()' \
928 > convert repo8 convert_normal
949 > convert repo8 convert_normal
929 initializing destination convert_normal repository
950 initializing destination convert_normal repository
930 scanning source...
951 scanning source...
931 sorting...
952 sorting...
932 converting...
953 converting...
933 2 a
954 2 a
934 1 b
955 1 b
935 0 meta
956 0 meta
936 $ grep 'lfs' convert_normal/.hg/requires
957 $ grep 'lfs' convert_normal/.hg/requires
937 [1]
958 [1]
938 $ hg --cwd convert_normal cat a1 -r 0 -T '{rawdata}'
959 $ hg --cwd convert_normal cat a1 -r 0 -T '{rawdata}'
939 THIS-IS-LFS-BECAUSE-10-BYTES
960 THIS-IS-LFS-BECAUSE-10-BYTES
940
961
941 $ hg --config extensions.convert= --config lfs.threshold=10B \
962 $ hg --config extensions.convert= --config lfs.threshold=10B \
942 > convert convert_normal convert_lfs
963 > convert convert_normal convert_lfs
943 initializing destination convert_lfs repository
964 initializing destination convert_lfs repository
944 scanning source...
965 scanning source...
945 sorting...
966 sorting...
946 converting...
967 converting...
947 2 a
968 2 a
948 1 b
969 1 b
949 0 meta
970 0 meta
950
971
951 $ hg --cwd convert_lfs cat -r 0 a1 -T '{rawdata}'
972 $ hg --cwd convert_lfs cat -r 0 a1 -T '{rawdata}'
952 version https://git-lfs.github.com/spec/v1
973 version https://git-lfs.github.com/spec/v1
953 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
974 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
954 size 29
975 size 29
955 x-is-binary 0
976 x-is-binary 0
956 $ hg --cwd convert_lfs debugdata a1 0
977 $ hg --cwd convert_lfs debugdata a1 0
957 version https://git-lfs.github.com/spec/v1
978 version https://git-lfs.github.com/spec/v1
958 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
979 oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
959 size 29
980 size 29
960 x-is-binary 0
981 x-is-binary 0
961 $ hg --cwd convert_lfs log -r 0 -T "{lfs_files % '{lfspointer % '{key}={value}\n'}'}"
982 $ hg --cwd convert_lfs log -r 0 -T "{lfs_files % '{lfspointer % '{key}={value}\n'}'}"
962 version=https://git-lfs.github.com/spec/v1
983 version=https://git-lfs.github.com/spec/v1
963 oid=sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
984 oid=sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
964 size=29
985 size=29
965 x-is-binary=0
986 x-is-binary=0
966 $ hg --cwd convert_lfs log -r 0 \
987 $ hg --cwd convert_lfs log -r 0 \
967 > -T '{lfs_files % "{get(lfspointer, "oid")}\n"}{lfs_files % "{lfspointer.oid}\n"}'
988 > -T '{lfs_files % "{get(lfspointer, "oid")}\n"}{lfs_files % "{lfspointer.oid}\n"}'
968 sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
989 sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
969 sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
990 sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
970 $ hg --cwd convert_lfs log -r 0 -T '{lfs_files % "{lfspointer}\n"}'
991 $ hg --cwd convert_lfs log -r 0 -T '{lfs_files % "{lfspointer}\n"}'
971 version=https://git-lfs.github.com/spec/v1 oid=sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024 size=29 x-is-binary=0
992 version=https://git-lfs.github.com/spec/v1 oid=sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024 size=29 x-is-binary=0
972 $ hg --cwd convert_lfs \
993 $ hg --cwd convert_lfs \
973 > log -r 'all()' -T '{rev}: {lfs_files % "{file}: {lfsoid}\n"}'
994 > log -r 'all()' -T '{rev}: {lfs_files % "{file}: {lfsoid}\n"}'
974 0: a1: 5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
995 0: a1: 5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
975 1: a2: 5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
996 1: a2: 5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
976 2: a2: 876dadc86a8542f9798048f2c47f51dbf8e4359aed883e8ec80c5db825f0d943
997 2: a2: 876dadc86a8542f9798048f2c47f51dbf8e4359aed883e8ec80c5db825f0d943
977
998
978 $ grep 'lfs' convert_lfs/.hg/requires
999 $ grep 'lfs' convert_lfs/.hg/requires
979 lfs
1000 lfs
980
1001
981 The hashes in all stages of the conversion are unchanged.
1002 The hashes in all stages of the conversion are unchanged.
982
1003
983 $ hg -R repo8 log -T '{node|short}\n'
1004 $ hg -R repo8 log -T '{node|short}\n'
984 0fae949de7fa
1005 0fae949de7fa
985 9cd6bdffdac0
1006 9cd6bdffdac0
986 7f96794915f7
1007 7f96794915f7
987 $ hg -R convert_normal log -T '{node|short}\n'
1008 $ hg -R convert_normal log -T '{node|short}\n'
988 0fae949de7fa
1009 0fae949de7fa
989 9cd6bdffdac0
1010 9cd6bdffdac0
990 7f96794915f7
1011 7f96794915f7
991 $ hg -R convert_lfs log -T '{node|short}\n'
1012 $ hg -R convert_lfs log -T '{node|short}\n'
992 0fae949de7fa
1013 0fae949de7fa
993 9cd6bdffdac0
1014 9cd6bdffdac0
994 7f96794915f7
1015 7f96794915f7
995
1016
996 This convert is trickier, because it contains deleted files (via `hg mv`)
1017 This convert is trickier, because it contains deleted files (via `hg mv`)
997
1018
998 $ hg --config extensions.convert= --config lfs.threshold=1000M \
1019 $ hg --config extensions.convert= --config lfs.threshold=1000M \
999 > convert repo3 convert_normal2
1020 > convert repo3 convert_normal2
1000 initializing destination convert_normal2 repository
1021 initializing destination convert_normal2 repository
1001 scanning source...
1022 scanning source...
1002 sorting...
1023 sorting...
1003 converting...
1024 converting...
1004 4 commit with lfs content
1025 4 commit with lfs content
1005 3 renames
1026 3 renames
1006 2 large to small, small to large
1027 2 large to small, small to large
1007 1 random modifications
1028 1 random modifications
1008 0 switch large and small again
1029 0 switch large and small again
1009 $ grep 'lfs' convert_normal2/.hg/requires
1030 $ grep 'lfs' convert_normal2/.hg/requires
1010 [1]
1031 [1]
1011 $ hg --cwd convert_normal2 debugdata large 0
1032 $ hg --cwd convert_normal2 debugdata large 0
1012 LONGER-THAN-TEN-BYTES-WILL-TRIGGER-LFS
1033 LONGER-THAN-TEN-BYTES-WILL-TRIGGER-LFS
1013
1034
1014 $ hg --config extensions.convert= --config lfs.threshold=10B \
1035 $ hg --config extensions.convert= --config lfs.threshold=10B \
1015 > convert convert_normal2 convert_lfs2
1036 > convert convert_normal2 convert_lfs2
1016 initializing destination convert_lfs2 repository
1037 initializing destination convert_lfs2 repository
1017 scanning source...
1038 scanning source...
1018 sorting...
1039 sorting...
1019 converting...
1040 converting...
1020 4 commit with lfs content
1041 4 commit with lfs content
1021 3 renames
1042 3 renames
1022 2 large to small, small to large
1043 2 large to small, small to large
1023 1 random modifications
1044 1 random modifications
1024 0 switch large and small again
1045 0 switch large and small again
1025 $ grep 'lfs' convert_lfs2/.hg/requires
1046 $ grep 'lfs' convert_lfs2/.hg/requires
1026 lfs
1047 lfs
1027 $ hg --cwd convert_lfs2 debugdata large 0
1048 $ hg --cwd convert_lfs2 debugdata large 0
1028 version https://git-lfs.github.com/spec/v1
1049 version https://git-lfs.github.com/spec/v1
1029 oid sha256:66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
1050 oid sha256:66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e
1030 size 39
1051 size 39
1031 x-is-binary 0
1052 x-is-binary 0
1032
1053
1033 Committing deleted files works:
1054 Committing deleted files works:
1034
1055
1035 $ hg init $TESTTMP/repo-del
1056 $ hg init $TESTTMP/repo-del
1036 $ cd $TESTTMP/repo-del
1057 $ cd $TESTTMP/repo-del
1037 $ echo 1 > A
1058 $ echo 1 > A
1038 $ hg commit -m 'add A' -A A
1059 $ hg commit -m 'add A' -A A
1039 $ hg rm A
1060 $ hg rm A
1040 $ hg commit -m 'rm A'
1061 $ hg commit -m 'rm A'
1041
1062
1042 Bad .hglfs files will block the commit with a useful message
1063 Bad .hglfs files will block the commit with a useful message
1043
1064
1044 $ cat > .hglfs << EOF
1065 $ cat > .hglfs << EOF
1045 > [track]
1066 > [track]
1046 > **.test = size(">5B")
1067 > **.test = size(">5B")
1047 > bad file ... no commit
1068 > bad file ... no commit
1048 > EOF
1069 > EOF
1049
1070
1050 $ echo x > file.txt
1071 $ echo x > file.txt
1051 $ hg ci -Aqm 'should fail'
1072 $ hg ci -Aqm 'should fail'
1052 hg: parse error at .hglfs:3: bad file ... no commit
1073 hg: parse error at .hglfs:3: bad file ... no commit
1053 [255]
1074 [255]
1054
1075
1055 $ cat > .hglfs << EOF
1076 $ cat > .hglfs << EOF
1056 > [track]
1077 > [track]
1057 > **.test = size(">5B")
1078 > **.test = size(">5B")
1058 > ** = nonexistent()
1079 > ** = nonexistent()
1059 > EOF
1080 > EOF
1060
1081
1061 $ hg ci -Aqm 'should fail'
1082 $ hg ci -Aqm 'should fail'
1062 abort: parse error in .hglfs: unknown identifier: nonexistent
1083 abort: parse error in .hglfs: unknown identifier: nonexistent
1063 [255]
1084 [255]
1064
1085
1065 '**' works out to mean all files.
1086 '**' works out to mean all files.
1066
1087
1067 $ cat > .hglfs << EOF
1088 $ cat > .hglfs << EOF
1068 > [track]
1089 > [track]
1069 > path:.hglfs = none()
1090 > path:.hglfs = none()
1070 > **.test = size(">5B")
1091 > **.test = size(">5B")
1071 > **.exclude = none()
1092 > **.exclude = none()
1072 > ** = size(">10B")
1093 > ** = size(">10B")
1073 > EOF
1094 > EOF
1074
1095
1075 The LFS policy takes effect without tracking the .hglfs file
1096 The LFS policy takes effect without tracking the .hglfs file
1076
1097
1077 $ echo 'largefile' > lfs.test
1098 $ echo 'largefile' > lfs.test
1078 $ echo '012345678901234567890' > nolfs.exclude
1099 $ echo '012345678901234567890' > nolfs.exclude
1079 $ echo '01234567890123456' > lfs.catchall
1100 $ echo '01234567890123456' > lfs.catchall
1080 $ hg add *
1101 $ hg add *
1081 $ hg ci -qm 'before add .hglfs'
1102 $ hg ci -qm 'before add .hglfs'
1082 $ hg log -r . -T '{rev}: {lfs_files % "{file}: {lfsoid}\n"}\n'
1103 $ hg log -r . -T '{rev}: {lfs_files % "{file}: {lfsoid}\n"}\n'
1083 2: lfs.catchall: d4ec46c2869ba22eceb42a729377432052d9dd75d82fc40390ebaadecee87ee9
1104 2: lfs.catchall: d4ec46c2869ba22eceb42a729377432052d9dd75d82fc40390ebaadecee87ee9
1084 lfs.test: 5489e6ced8c36a7b267292bde9fd5242a5f80a7482e8f23fa0477393dfaa4d6c
1105 lfs.test: 5489e6ced8c36a7b267292bde9fd5242a5f80a7482e8f23fa0477393dfaa4d6c
1085
1106
1086 The .hglfs file works when tracked
1107 The .hglfs file works when tracked
1087
1108
1088 $ echo 'largefile2' > lfs.test
1109 $ echo 'largefile2' > lfs.test
1089 $ echo '012345678901234567890a' > nolfs.exclude
1110 $ echo '012345678901234567890a' > nolfs.exclude
1090 $ echo '01234567890123456a' > lfs.catchall
1111 $ echo '01234567890123456a' > lfs.catchall
1091 $ hg ci -Aqm 'after adding .hglfs'
1112 $ hg ci -Aqm 'after adding .hglfs'
1092 $ hg log -r . -T '{rev}: {lfs_files % "{file}: {lfsoid}\n"}\n'
1113 $ hg log -r . -T '{rev}: {lfs_files % "{file}: {lfsoid}\n"}\n'
1093 3: lfs.catchall: 31f43b9c62b540126b0ad5884dc013d21a61c9329b77de1fceeae2fc58511573
1114 3: lfs.catchall: 31f43b9c62b540126b0ad5884dc013d21a61c9329b77de1fceeae2fc58511573
1094 lfs.test: 8acd23467967bc7b8cc5a280056589b0ba0b17ff21dbd88a7b6474d6290378a6
1115 lfs.test: 8acd23467967bc7b8cc5a280056589b0ba0b17ff21dbd88a7b6474d6290378a6
1095
1116
1096 The LFS policy stops when the .hglfs is gone
1117 The LFS policy stops when the .hglfs is gone
1097
1118
1098 $ mv .hglfs .hglfs_
1119 $ mv .hglfs .hglfs_
1099 $ echo 'largefile3' > lfs.test
1120 $ echo 'largefile3' > lfs.test
1100 $ echo '012345678901234567890abc' > nolfs.exclude
1121 $ echo '012345678901234567890abc' > nolfs.exclude
1101 $ echo '01234567890123456abc' > lfs.catchall
1122 $ echo '01234567890123456abc' > lfs.catchall
1102 $ hg ci -qm 'file test' -X .hglfs
1123 $ hg ci -qm 'file test' -X .hglfs
1103 $ hg log -r . -T '{rev}: {lfs_files % "{file}: {lfsoid}\n"}\n'
1124 $ hg log -r . -T '{rev}: {lfs_files % "{file}: {lfsoid}\n"}\n'
1104 4:
1125 4:
1105
1126
1106 $ mv .hglfs_ .hglfs
1127 $ mv .hglfs_ .hglfs
1107 $ echo '012345678901234567890abc' > lfs.test
1128 $ echo '012345678901234567890abc' > lfs.test
1108 $ hg ci -m 'back to lfs'
1129 $ hg ci -m 'back to lfs'
1109 $ hg rm lfs.test
1130 $ hg rm lfs.test
1110 $ hg ci -qm 'remove lfs'
1131 $ hg ci -qm 'remove lfs'
1111
1132
1112 {lfs_files} will list deleted files too
1133 {lfs_files} will list deleted files too
1113
1134
1114 $ hg log -T "{lfs_files % '{rev} {file}: {lfspointer.oid}\n'}"
1135 $ hg log -T "{lfs_files % '{rev} {file}: {lfspointer.oid}\n'}"
1115 6 lfs.test:
1136 6 lfs.test:
1116 5 lfs.test: sha256:43f8f41171b6f62a6b61ba4ce98a8a6c1649240a47ebafd43120aa215ac9e7f6
1137 5 lfs.test: sha256:43f8f41171b6f62a6b61ba4ce98a8a6c1649240a47ebafd43120aa215ac9e7f6
1117 3 lfs.catchall: sha256:31f43b9c62b540126b0ad5884dc013d21a61c9329b77de1fceeae2fc58511573
1138 3 lfs.catchall: sha256:31f43b9c62b540126b0ad5884dc013d21a61c9329b77de1fceeae2fc58511573
1118 3 lfs.test: sha256:8acd23467967bc7b8cc5a280056589b0ba0b17ff21dbd88a7b6474d6290378a6
1139 3 lfs.test: sha256:8acd23467967bc7b8cc5a280056589b0ba0b17ff21dbd88a7b6474d6290378a6
1119 2 lfs.catchall: sha256:d4ec46c2869ba22eceb42a729377432052d9dd75d82fc40390ebaadecee87ee9
1140 2 lfs.catchall: sha256:d4ec46c2869ba22eceb42a729377432052d9dd75d82fc40390ebaadecee87ee9
1120 2 lfs.test: sha256:5489e6ced8c36a7b267292bde9fd5242a5f80a7482e8f23fa0477393dfaa4d6c
1141 2 lfs.test: sha256:5489e6ced8c36a7b267292bde9fd5242a5f80a7482e8f23fa0477393dfaa4d6c
1121
1142
1122 $ hg log -r 'file("set:lfs()")' -T '{rev} {join(lfs_files, ", ")}\n'
1143 $ hg log -r 'file("set:lfs()")' -T '{rev} {join(lfs_files, ", ")}\n'
1123 2 lfs.catchall, lfs.test
1144 2 lfs.catchall, lfs.test
1124 3 lfs.catchall, lfs.test
1145 3 lfs.catchall, lfs.test
1125 5 lfs.test
1146 5 lfs.test
1126 6 lfs.test
1147 6 lfs.test
1127
1148
1128 $ cd ..
1149 $ cd ..
1129
1150
1130 Unbundling adds a requirement to a non-lfs repo, if necessary.
1151 Unbundling adds a requirement to a non-lfs repo, if necessary.
1131
1152
1132 $ hg bundle -R $TESTTMP/repo-del -qr 0 --base null nolfs.hg
1153 $ hg bundle -R $TESTTMP/repo-del -qr 0 --base null nolfs.hg
1133 $ hg bundle -R convert_lfs2 -qr tip --base null lfs.hg
1154 $ hg bundle -R convert_lfs2 -qr tip --base null lfs.hg
1134 $ hg init unbundle
1155 $ hg init unbundle
1135 $ hg pull -R unbundle -q nolfs.hg
1156 $ hg pull -R unbundle -q nolfs.hg
1136 $ grep lfs unbundle/.hg/requires
1157 $ grep lfs unbundle/.hg/requires
1137 [1]
1158 [1]
1138 $ hg pull -R unbundle -q lfs.hg
1159 $ hg pull -R unbundle -q lfs.hg
1139 $ grep lfs unbundle/.hg/requires
1160 $ grep lfs unbundle/.hg/requires
1140 lfs
1161 lfs
1141
1162
1142 $ hg init no_lfs
1163 $ hg init no_lfs
1143 $ cat >> no_lfs/.hg/hgrc <<EOF
1164 $ cat >> no_lfs/.hg/hgrc <<EOF
1144 > [experimental]
1165 > [experimental]
1145 > changegroup3 = True
1166 > changegroup3 = True
1146 > [extensions]
1167 > [extensions]
1147 > lfs=!
1168 > lfs=!
1148 > EOF
1169 > EOF
1149 $ cp -R no_lfs no_lfs2
1170 $ cp -R no_lfs no_lfs2
1150
1171
1151 Pushing from a local lfs repo to a local repo without an lfs requirement and
1172 Pushing from a local lfs repo to a local repo without an lfs requirement and
1152 with lfs disabled, fails.
1173 with lfs disabled, fails.
1153
1174
1154 $ hg push -R convert_lfs2 no_lfs
1175 $ hg push -R convert_lfs2 no_lfs
1155 pushing to no_lfs
1176 pushing to no_lfs
1156 abort: required features are not supported in the destination: lfs
1177 abort: required features are not supported in the destination: lfs
1157 [255]
1178 [255]
1158 $ grep lfs no_lfs/.hg/requires
1179 $ grep lfs no_lfs/.hg/requires
1159 [1]
1180 [1]
1160
1181
1161 Pulling from a local lfs repo to a local repo without an lfs requirement and
1182 Pulling from a local lfs repo to a local repo without an lfs requirement and
1162 with lfs disabled, fails.
1183 with lfs disabled, fails.
1163
1184
1164 $ hg pull -R no_lfs2 convert_lfs2
1185 $ hg pull -R no_lfs2 convert_lfs2
1165 pulling from convert_lfs2
1186 pulling from convert_lfs2
1166 abort: required features are not supported in the destination: lfs
1187 abort: required features are not supported in the destination: lfs
1167 [255]
1188 [255]
1168 $ grep lfs no_lfs2/.hg/requires
1189 $ grep lfs no_lfs2/.hg/requires
1169 [1]
1190 [1]
General Comments 0
You need to be logged in to leave comments. Login now