##// END OF EJS Templates
lfs: register the flag processors per repository...
Matt Harbison -
r40304:9c4cbbb0 default
parent child Browse files
Show More
@@ -1,401 +1,416
1 1 # lfs - hash-preserving large file support using Git-LFS protocol
2 2 #
3 3 # Copyright 2017 Facebook, Inc.
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 """lfs - large file support (EXPERIMENTAL)
9 9
10 10 This extension allows large files to be tracked outside of the normal
11 11 repository storage and stored on a centralized server, similar to the
12 12 ``largefiles`` extension. The ``git-lfs`` protocol is used when
13 13 communicating with the server, so existing git infrastructure can be
14 14 harnessed. Even though the files are stored outside of the repository,
15 15 they are still integrity checked in the same manner as normal files.
16 16
17 17 The files stored outside of the repository are downloaded on demand,
18 18 which reduces the time to clone, and possibly the local disk usage.
19 19 This changes fundamental workflows in a DVCS, so careful thought
20 20 should be given before deploying it. :hg:`convert` can be used to
21 21 convert LFS repositories to normal repositories that no longer
22 22 require this extension, and do so without changing the commit hashes.
23 23 This allows the extension to be disabled if the centralized workflow
24 24 becomes burdensome. However, the pre and post convert clones will
25 25 not be able to communicate with each other unless the extension is
26 26 enabled on both.
27 27
28 28 To start a new repository, or to add LFS files to an existing one, just
29 29 create an ``.hglfs`` file as described below in the root directory of
30 30 the repository. Typically, this file should be put under version
31 31 control, so that the settings will propagate to other repositories with
32 32 push and pull. During any commit, Mercurial will consult this file to
33 33 determine if an added or modified file should be stored externally. The
34 34 type of storage depends on the characteristics of the file at each
35 35 commit. A file that is near a size threshold may switch back and forth
36 36 between LFS and normal storage, as needed.
37 37
38 38 Alternately, both normal repositories and largefile controlled
39 39 repositories can be converted to LFS by using :hg:`convert` and the
40 40 ``lfs.track`` config option described below. The ``.hglfs`` file
41 41 should then be created and added, to control subsequent LFS selection.
42 42 The hashes are also unchanged in this case. The LFS and non-LFS
43 43 repositories can be distinguished because the LFS repository will
44 44 abort any command if this extension is disabled.
45 45
46 46 Committed LFS files are held locally, until the repository is pushed.
47 47 Prior to pushing the normal repository data, the LFS files that are
48 48 tracked by the outgoing commits are automatically uploaded to the
49 49 configured central server. No LFS files are transferred on
50 50 :hg:`pull` or :hg:`clone`. Instead, the files are downloaded on
51 51 demand as they need to be read, if a cached copy cannot be found
52 52 locally. Both committing and downloading an LFS file will link the
53 53 file to a usercache, to speed up future access. See the `usercache`
54 54 config setting described below.
55 55
56 56 .hglfs::
57 57
58 58 The extension reads its configuration from a versioned ``.hglfs``
59 59 configuration file found in the root of the working directory. The
60 60 ``.hglfs`` file uses the same syntax as all other Mercurial
61 61 configuration files. It uses a single section, ``[track]``.
62 62
63 63 The ``[track]`` section specifies which files are stored as LFS (or
64 64 not). Each line is keyed by a file pattern, with a predicate value.
65 65 The first file pattern match is used, so put more specific patterns
66 66 first. The available predicates are ``all()``, ``none()``, and
67 67 ``size()``. See "hg help filesets.size" for the latter.
68 68
69 69 Example versioned ``.hglfs`` file::
70 70
71 71 [track]
72 72 # No Makefile or python file, anywhere, will be LFS
73 73 **Makefile = none()
74 74 **.py = none()
75 75
76 76 **.zip = all()
77 77 **.exe = size(">1MB")
78 78
79 79 # Catchall for everything not matched above
80 80 ** = size(">10MB")
81 81
82 82 Configs::
83 83
84 84 [lfs]
85 85 # Remote endpoint. Multiple protocols are supported:
86 86 # - http(s)://user:pass@example.com/path
87 87 # git-lfs endpoint
88 88 # - file:///tmp/path
89 89 # local filesystem, usually for testing
90 90 # if unset, lfs will assume the remote repository also handles blob storage
91 91 # for http(s) URLs. Otherwise, lfs will prompt to set this when it must
92 92 # use this value.
93 93 # (default: unset)
94 94 url = https://example.com/repo.git/info/lfs
95 95
96 96 # Which files to track in LFS. Path tests are "**.extname" for file
97 97 # extensions, and "path:under/some/directory" for path prefix. Both
98 98 # are relative to the repository root.
99 99 # File size can be tested with the "size()" fileset, and tests can be
100 100 # joined with fileset operators. (See "hg help filesets.operators".)
101 101 #
102 102 # Some examples:
103 103 # - all() # everything
104 104 # - none() # nothing
105 105 # - size(">20MB") # larger than 20MB
106 106 # - !**.txt # anything not a *.txt file
107 107 # - **.zip | **.tar.gz | **.7z # some types of compressed files
108 108 # - path:bin # files under "bin" in the project root
109 109 # - (**.php & size(">2MB")) | (**.js & size(">5MB")) | **.tar.gz
110 110 # | (path:bin & !path:/bin/README) | size(">1GB")
111 111 # (default: none())
112 112 #
113 113 # This is ignored if there is a tracked '.hglfs' file, and this setting
114 114 # will eventually be deprecated and removed.
115 115 track = size(">10M")
116 116
117 117 # how many times to retry before giving up on transferring an object
118 118 retry = 5
119 119
120 120 # the local directory to store lfs files for sharing across local clones.
121 121 # If not set, the cache is located in an OS specific cache location.
122 122 usercache = /path/to/global/cache
123 123 """
124 124
125 125 from __future__ import absolute_import
126 126
127 import sys
128
127 129 from mercurial.i18n import _
128 130
129 131 from mercurial import (
130 132 bundle2,
131 133 changegroup,
132 134 cmdutil,
133 135 config,
134 136 context,
135 137 error,
136 138 exchange,
137 139 extensions,
138 140 filelog,
139 141 filesetlang,
140 142 localrepo,
141 143 minifileset,
142 144 node,
143 145 pycompat,
144 146 registrar,
145 147 repository,
146 148 revlog,
147 149 scmutil,
148 150 templateutil,
149 151 upgrade,
150 152 util,
151 153 vfs as vfsmod,
152 154 wireprotoserver,
153 155 wireprotov1server,
154 156 )
155 157
156 158 from . import (
157 159 blobstore,
158 160 wireprotolfsserver,
159 161 wrapper,
160 162 )
161 163
162 164 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
163 165 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
164 166 # be specifying the version(s) of Mercurial they are tested with, or
165 167 # leave the attribute unspecified.
166 168 testedwith = 'ships-with-hg-core'
167 169
168 170 configtable = {}
169 171 configitem = registrar.configitem(configtable)
170 172
171 173 configitem('experimental', 'lfs.serve',
172 174 default=True,
173 175 )
174 176 configitem('experimental', 'lfs.user-agent',
175 177 default=None,
176 178 )
177 179 configitem('experimental', 'lfs.disableusercache',
178 180 default=False,
179 181 )
180 182 configitem('experimental', 'lfs.worker-enable',
181 183 default=False,
182 184 )
183 185
184 186 configitem('lfs', 'url',
185 187 default=None,
186 188 )
187 189 configitem('lfs', 'usercache',
188 190 default=None,
189 191 )
190 192 # Deprecated
191 193 configitem('lfs', 'threshold',
192 194 default=None,
193 195 )
194 196 configitem('lfs', 'track',
195 197 default='none()',
196 198 )
197 199 configitem('lfs', 'retry',
198 200 default=5,
199 201 )
200 202
201 203 cmdtable = {}
202 204 command = registrar.command(cmdtable)
203 205
204 206 templatekeyword = registrar.templatekeyword()
205 207 filesetpredicate = registrar.filesetpredicate()
206 208
209 lfsprocessor = (
210 wrapper.readfromstore,
211 wrapper.writetostore,
212 wrapper.bypasscheckhash,
213 )
214
207 215 def featuresetup(ui, supported):
208 216 # don't die on seeing a repo with the lfs requirement
209 217 supported |= {'lfs'}
210 218
211 219 def uisetup(ui):
212 220 localrepo.featuresetupfuncs.add(featuresetup)
213 221
214 222 def reposetup(ui, repo):
215 223 # Nothing to do with a remote repo
216 224 if not repo.local():
217 225 return
218 226
219 227 repo.svfs.lfslocalblobstore = blobstore.local(repo)
220 228 repo.svfs.lfsremoteblobstore = blobstore.remote(repo)
221 229
222 230 class lfsrepo(repo.__class__):
223 231 @localrepo.unfilteredmethod
224 232 def commitctx(self, ctx, error=False):
225 233 repo.svfs.options['lfstrack'] = _trackedmatcher(self)
226 234 return super(lfsrepo, self).commitctx(ctx, error)
227 235
228 236 repo.__class__ = lfsrepo
229 237
230 238 if 'lfs' not in repo.requirements:
231 239 def checkrequireslfs(ui, repo, **kwargs):
232 240 if 'lfs' not in repo.requirements:
233 241 last = kwargs.get(r'node_last')
234 242 _bin = node.bin
235 243 if last:
236 244 s = repo.set('%n:%n', _bin(kwargs[r'node']), _bin(last))
237 245 else:
238 246 s = repo.set('%n', _bin(kwargs[r'node']))
239 247 match = repo.narrowmatch()
240 248 for ctx in s:
241 249 # TODO: is there a way to just walk the files in the commit?
242 250 if any(ctx[f].islfs() for f in ctx.files()
243 251 if f in ctx and match(f)):
244 252 repo.requirements.add('lfs')
245 253 repo.features.add(repository.REPO_FEATURE_LFS)
246 254 repo._writerequirements()
247 255 repo.prepushoutgoinghooks.add('lfs', wrapper.prepush)
248 256 break
249 257
250 258 ui.setconfig('hooks', 'commit.lfs', checkrequireslfs, 'lfs')
251 259 ui.setconfig('hooks', 'pretxnchangegroup.lfs', checkrequireslfs, 'lfs')
252 260 else:
253 261 repo.prepushoutgoinghooks.add('lfs', wrapper.prepush)
254 262
255 263 def _trackedmatcher(repo):
256 264 """Return a function (path, size) -> bool indicating whether or not to
257 265 track a given file with lfs."""
258 266 if not repo.wvfs.exists('.hglfs'):
259 267 # No '.hglfs' in wdir. Fallback to config for now.
260 268 trackspec = repo.ui.config('lfs', 'track')
261 269
262 270 # deprecated config: lfs.threshold
263 271 threshold = repo.ui.configbytes('lfs', 'threshold')
264 272 if threshold:
265 273 filesetlang.parse(trackspec) # make sure syntax errors are confined
266 274 trackspec = "(%s) | size('>%d')" % (trackspec, threshold)
267 275
268 276 return minifileset.compile(trackspec)
269 277
270 278 data = repo.wvfs.tryread('.hglfs')
271 279 if not data:
272 280 return lambda p, s: False
273 281
274 282 # Parse errors here will abort with a message that points to the .hglfs file
275 283 # and line number.
276 284 cfg = config.config()
277 285 cfg.parse('.hglfs', data)
278 286
279 287 try:
280 288 rules = [(minifileset.compile(pattern), minifileset.compile(rule))
281 289 for pattern, rule in cfg.items('track')]
282 290 except error.ParseError as e:
283 291 # The original exception gives no indicator that the error is in the
284 292 # .hglfs file, so add that.
285 293
286 294 # TODO: See if the line number of the file can be made available.
287 295 raise error.Abort(_('parse error in .hglfs: %s') % e)
288 296
289 297 def _match(path, size):
290 298 for pat, rule in rules:
291 299 if pat(path, size):
292 300 return rule(path, size)
293 301
294 302 return False
295 303
296 304 return _match
297 305
298 306 def wrapfilelog(filelog):
299 307 wrapfunction = extensions.wrapfunction
300 308
301 309 wrapfunction(filelog, 'addrevision', wrapper.filelogaddrevision)
302 310 wrapfunction(filelog, 'renamed', wrapper.filelogrenamed)
303 311 wrapfunction(filelog, 'size', wrapper.filelogsize)
304 312
313 def _resolverevlogstorevfsoptions(orig, ui, requirements, features):
314 opts = orig(ui, requirements, features)
315 for name, module in extensions.extensions(ui):
316 if module is sys.modules[__name__]:
317 if revlog.REVIDX_EXTSTORED in opts[b'flagprocessors']:
318 msg = (_(b"cannot register multiple processors on flag '%#x'.")
319 % revlog.REVIDX_EXTSTORED)
320 raise error.Abort(msg)
321
322 opts[b'flagprocessors'][revlog.REVIDX_EXTSTORED] = lfsprocessor
323 break
324
325 return opts
326
305 327 def extsetup(ui):
306 328 wrapfilelog(filelog.filelog)
307 329
308 330 wrapfunction = extensions.wrapfunction
309 331
310 332 wrapfunction(localrepo, 'makefilestorage', wrapper.localrepomakefilestorage)
333 wrapfunction(localrepo, 'resolverevlogstorevfsoptions',
334 _resolverevlogstorevfsoptions)
311 335
312 336 wrapfunction(cmdutil, '_updatecatformatter', wrapper._updatecatformatter)
313 337 wrapfunction(scmutil, 'wrapconvertsink', wrapper.convertsink)
314 338
315 339 wrapfunction(upgrade, '_finishdatamigration',
316 340 wrapper.upgradefinishdatamigration)
317 341
318 342 wrapfunction(upgrade, 'preservedrequirements',
319 343 wrapper.upgraderequirements)
320 344
321 345 wrapfunction(upgrade, 'supporteddestrequirements',
322 346 wrapper.upgraderequirements)
323 347
324 348 wrapfunction(changegroup,
325 349 'allsupportedversions',
326 350 wrapper.allsupportedversions)
327 351
328 352 wrapfunction(exchange, 'push', wrapper.push)
329 353 wrapfunction(wireprotov1server, '_capabilities', wrapper._capabilities)
330 354 wrapfunction(wireprotoserver, 'handlewsgirequest',
331 355 wireprotolfsserver.handlewsgirequest)
332 356
333 357 wrapfunction(context.basefilectx, 'cmp', wrapper.filectxcmp)
334 358 wrapfunction(context.basefilectx, 'isbinary', wrapper.filectxisbinary)
335 359 context.basefilectx.islfs = wrapper.filectxislfs
336 360
337 revlog.addflagprocessor(
338 revlog.REVIDX_EXTSTORED,
339 (
340 wrapper.readfromstore,
341 wrapper.writetostore,
342 wrapper.bypasscheckhash,
343 ),
344 )
345
346 361 scmutil.fileprefetchhooks.add('lfs', wrapper._prefetchfiles)
347 362
348 363 # Make bundle choose changegroup3 instead of changegroup2. This affects
349 364 # "hg bundle" command. Note: it does not cover all bundle formats like
350 365 # "packed1". Using "packed1" with lfs will likely cause trouble.
351 366 exchange._bundlespeccontentopts["v2"]["cg.version"] = "03"
352 367
353 368 # bundlerepo uses "vfsmod.readonlyvfs(othervfs)", we need to make sure lfs
354 369 # options and blob stores are passed from othervfs to the new readonlyvfs.
355 370 wrapfunction(vfsmod.readonlyvfs, '__init__', wrapper.vfsinit)
356 371
357 372 # when writing a bundle via "hg bundle" command, upload related LFS blobs
358 373 wrapfunction(bundle2, 'writenewbundle', wrapper.writenewbundle)
359 374
360 375 @filesetpredicate('lfs()')
361 376 def lfsfileset(mctx, x):
362 377 """File that uses LFS storage."""
363 378 # i18n: "lfs" is a keyword
364 379 filesetlang.getargs(x, 0, 0, _("lfs takes no arguments"))
365 380 ctx = mctx.ctx
366 381 def lfsfilep(f):
367 382 return wrapper.pointerfromctx(ctx, f, removed=True) is not None
368 383 return mctx.predicate(lfsfilep, predrepr='<lfs>')
369 384
370 385 @templatekeyword('lfs_files', requires={'ctx'})
371 386 def lfsfiles(context, mapping):
372 387 """List of strings. All files modified, added, or removed by this
373 388 changeset."""
374 389 ctx = context.resource(mapping, 'ctx')
375 390
376 391 pointers = wrapper.pointersfromctx(ctx, removed=True) # {path: pointer}
377 392 files = sorted(pointers.keys())
378 393
379 394 def pointer(v):
380 395 # In the file spec, version is first and the other keys are sorted.
381 396 sortkeyfunc = lambda x: (x[0] != 'version', x)
382 397 items = sorted(pointers[v].iteritems(), key=sortkeyfunc)
383 398 return util.sortdict(items)
384 399
385 400 makemap = lambda v: {
386 401 'file': v,
387 402 'lfsoid': pointers[v].oid() if pointers[v] else None,
388 403 'lfspointer': templateutil.hybriddict(pointer(v)),
389 404 }
390 405
391 406 # TODO: make the separator ', '?
392 407 f = templateutil._showcompatlist(context, mapping, 'lfs_file', files)
393 408 return templateutil.hybrid(f, files, makemap, pycompat.identity)
394 409
395 410 @command('debuglfsupload',
396 411 [('r', 'rev', [], _('upload large files introduced by REV'))])
397 412 def debuglfsupload(ui, repo, **opts):
398 413 """upload lfs blobs added by the working copy parent or given revisions"""
399 414 revs = opts.get(r'rev', [])
400 415 pointers = wrapper.extractpointers(repo, scmutil.revrange(repo, revs))
401 416 wrapper.uploadblobs(repo, pointers)
@@ -1,523 +1,644
1 1 #testcases lfsremote-on lfsremote-off
2 2 #require serve no-reposimplestore no-chg
3 3
4 4 This test splits `hg serve` with and without using the extension into separate
5 5 tests cases. The tests are broken down as follows, where "LFS"/"No-LFS"
6 6 indicates whether or not there are commits that use an LFS file, and "D"/"E"
7 7 indicates whether or not the extension is loaded. The "X" cases are not tested
8 8 individually, because the lfs requirement causes the process to bail early if
9 9 the extension is disabled.
10 10
11 11 . Server
12 12 .
13 13 . No-LFS LFS
14 14 . +----------------------------+
15 15 . | || D | E | D | E |
16 16 . |---++=======================|
17 17 . C | D || N/A | #1 | X | #4 |
18 18 . l No +---++-----------------------|
19 19 . i LFS | E || #2 | #2 | X | #5 |
20 20 . e +---++-----------------------|
21 21 . n | D || X | X | X | X |
22 22 . t LFS |---++-----------------------|
23 23 . | E || #3 | #3 | X | #6 |
24 24 . |---++-----------------------+
25 25
26 26 make command server magic visible
27 27
28 28 #if windows
29 29 $ PYTHONPATH="$TESTDIR/../contrib;$PYTHONPATH"
30 30 #else
31 31 $ PYTHONPATH="$TESTDIR/../contrib:$PYTHONPATH"
32 32 #endif
33 33 $ export PYTHONPATH
34 34
35 35 $ hg init server
36 36 $ SERVER_REQUIRES="$TESTTMP/server/.hg/requires"
37 37
38 $ cat > $TESTTMP/debugprocessors.py <<EOF
39 > from mercurial import (
40 > cmdutil,
41 > commands,
42 > pycompat,
43 > registrar,
44 > )
45 > cmdtable = {}
46 > command = registrar.command(cmdtable)
47 > @command(b'debugprocessors', [], b'FILE')
48 > def debugprocessors(ui, repo, file_=None, **opts):
49 > opts = pycompat.byteskwargs(opts)
50 > opts[b'changelog'] = False
51 > opts[b'manifest'] = False
52 > opts[b'dir'] = False
53 > rl = cmdutil.openrevlog(repo, b'debugprocessors', file_, opts)
54 > for flag, proc in rl._flagprocessors.iteritems():
55 > ui.status(b"registered processor '%#x'\n" % (flag))
56 > EOF
57
38 58 Skip the experimental.changegroup3=True config. Failure to agree on this comes
39 59 first, and causes a "ValueError: no common changegroup version" or "abort:
40 60 HTTP Error 500: Internal Server Error", if the extension is only loaded on one
41 61 side. If that *is* enabled, the subsequent failure is "abort: missing processor
42 62 for flag '0x2000'!" if the extension is only loaded on one side (possibly also
43 63 masked by the Internal Server Error message).
44 64 $ cat >> $HGRCPATH <<EOF
65 > [extensions]
66 > debugprocessors = $TESTTMP/debugprocessors.py
45 67 > [experimental]
46 68 > lfs.disableusercache = True
47 69 > [lfs]
48 70 > threshold=10
49 71 > [web]
50 72 > allow_push=*
51 73 > push_ssl=False
52 74 > EOF
53 75
76 $ cp $HGRCPATH $HGRCPATH.orig
77
54 78 #if lfsremote-on
55 79 $ hg --config extensions.lfs= -R server \
56 80 > serve -p $HGPORT -d --pid-file=hg.pid --errorlog=$TESTTMP/errors.log
57 81 #else
58 82 $ hg --config extensions.lfs=! -R server \
59 83 > serve -p $HGPORT -d --pid-file=hg.pid --errorlog=$TESTTMP/errors.log
60 84 #endif
61 85
62 86 $ cat hg.pid >> $DAEMON_PIDS
63 87 $ hg clone -q http://localhost:$HGPORT client
64 88 $ grep 'lfs' client/.hg/requires $SERVER_REQUIRES
65 89 [1]
66 90
67 91 This trivial repo will force commandserver to load the extension, but not call
68 92 reposetup() on another repo actually being operated on. This gives coverage
69 93 that wrapper functions are not assuming reposetup() was called.
70 94
71 95 $ hg init $TESTTMP/cmdservelfs
72 96 $ cat >> $TESTTMP/cmdservelfs/.hg/hgrc << EOF
73 97 > [extensions]
74 98 > lfs =
75 99 > EOF
76 100
77 101 --------------------------------------------------------------------------------
78 102 Case #1: client with non-lfs content and the extension disabled; server with
79 103 non-lfs content, and the extension enabled.
80 104
81 105 $ cd client
82 106 $ echo 'non-lfs' > nonlfs.txt
83 107 >>> from __future__ import absolute_import
84 108 >>> from hgclient import check, readchannel, runcommand
85 109 >>> @check
86 110 ... def diff(server):
87 111 ... readchannel(server)
88 112 ... # run an arbitrary command in the repo with the extension loaded
89 113 ... runcommand(server, ['id', '-R', '../cmdservelfs'])
90 114 ... # now run a command in a repo without the extension to ensure that
91 115 ... # files are added safely..
92 116 ... runcommand(server, ['ci', '-Aqm', 'non-lfs'])
93 117 ... # .. and that scmutil.prefetchfiles() safely no-ops..
94 118 ... runcommand(server, ['diff', '-r', '.~1'])
95 119 ... # .. and that debugupgraderepo safely no-ops.
96 120 ... runcommand(server, ['debugupgraderepo', '-q', '--run'])
97 121 *** runcommand id -R ../cmdservelfs
98 122 000000000000 tip
99 123 *** runcommand ci -Aqm non-lfs
100 124 *** runcommand diff -r .~1
101 125 diff -r 000000000000 nonlfs.txt
102 126 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
103 127 +++ b/nonlfs.txt Thu Jan 01 00:00:00 1970 +0000
104 128 @@ -0,0 +1,1 @@
105 129 +non-lfs
106 130 *** runcommand debugupgraderepo -q --run
107 131 upgrade will perform the following actions:
108 132
109 133 requirements
110 134 preserved: dotencode, fncache, generaldelta, revlogv1, store
111 135
112 136 beginning upgrade...
113 137 repository locked and read-only
114 138 creating temporary repository to stage migrated data: * (glob)
115 139 (it is safe to interrupt this process any time before data migration completes)
116 140 migrating 3 total revisions (1 in filelogs, 1 in manifests, 1 in changelog)
117 141 migrating 324 bytes in store; 129 bytes tracked data
118 142 migrating 1 filelogs containing 1 revisions (73 bytes in store; 8 bytes tracked data)
119 143 finished migrating 1 filelog revisions across 1 filelogs; change in size: 0 bytes
120 144 migrating 1 manifests containing 1 revisions (117 bytes in store; 52 bytes tracked data)
121 145 finished migrating 1 manifest revisions across 1 manifests; change in size: 0 bytes
122 146 migrating changelog containing 1 revisions (134 bytes in store; 69 bytes tracked data)
123 147 finished migrating 1 changelog revisions; change in size: 0 bytes
124 148 finished migrating 3 total revisions; total change in store size: 0 bytes
125 149 copying phaseroots
126 150 data fully migrated to temporary repository
127 151 marking source repository as being upgraded; clients will be unable to read from repository
128 152 starting in-place swap of repository data
129 153 replaced files will be backed up at * (glob)
130 154 replacing store...
131 155 store replacement complete; repository was inconsistent for *s (glob)
132 156 finalizing requirements file and making repository readable again
133 157 removing temporary repository * (glob)
134 158 copy of old repository backed up at * (glob)
135 159 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
136 160
137 161 $ grep 'lfs' .hg/requires $SERVER_REQUIRES
138 162 [1]
139 163
140 164 #if lfsremote-on
141 165
142 166 $ hg push -q
143 167 $ grep 'lfs' .hg/requires $SERVER_REQUIRES
144 168 [1]
145 169
146 170 $ hg clone -q http://localhost:$HGPORT $TESTTMP/client1_clone
147 171 $ grep 'lfs' $TESTTMP/client1_clone/.hg/requires $SERVER_REQUIRES
148 172 [1]
149 173
150 174 $ hg init $TESTTMP/client1_pull
151 175 $ hg -R $TESTTMP/client1_pull pull -q http://localhost:$HGPORT
152 176 $ grep 'lfs' $TESTTMP/client1_pull/.hg/requires $SERVER_REQUIRES
153 177 [1]
154 178
155 179 $ hg identify http://localhost:$HGPORT
156 180 d437e1d24fbd
157 181
158 182 #endif
159 183
160 184 --------------------------------------------------------------------------------
161 185 Case #2: client with non-lfs content and the extension enabled; server with
162 186 non-lfs content, and the extension state controlled by #testcases.
163 187
164 188 $ cat >> $HGRCPATH <<EOF
165 189 > [extensions]
166 190 > lfs =
167 191 > EOF
168 192 $ echo 'non-lfs' > nonlfs2.txt
169 193 $ hg ci -Aqm 'non-lfs file with lfs client'
170 194
171 195 Since no lfs content has been added yet, the push is allowed, even when the
172 196 extension is not enabled remotely.
173 197
174 198 $ hg push -q
175 199 $ grep 'lfs' .hg/requires $SERVER_REQUIRES
176 200 [1]
177 201
178 202 $ hg clone -q http://localhost:$HGPORT $TESTTMP/client2_clone
179 203 $ grep 'lfs' $TESTTMP/client2_clone/.hg/requires $SERVER_REQUIRES
180 204 [1]
181 205
182 206 $ hg init $TESTTMP/client2_pull
183 207 $ hg -R $TESTTMP/client2_pull pull -q http://localhost:$HGPORT
184 208 $ grep 'lfs' $TESTTMP/client2_pull/.hg/requires $SERVER_REQUIRES
185 209 [1]
186 210
187 211 $ hg identify http://localhost:$HGPORT
188 212 1477875038c6
189 213
190 214 --------------------------------------------------------------------------------
191 215 Case #3: client with lfs content and the extension enabled; server with
192 216 non-lfs content, and the extension state controlled by #testcases. The server
193 217 should have an 'lfs' requirement after it picks up its first commit with a blob.
194 218
195 219 $ echo 'this is a big lfs file' > lfs.bin
196 220 $ hg ci -Aqm 'lfs'
197 221 $ grep 'lfs' .hg/requires $SERVER_REQUIRES
198 222 .hg/requires:lfs
199 223
200 224 #if lfsremote-off
201 225 $ hg push -q
202 226 abort: required features are not supported in the destination: lfs
203 227 (enable the lfs extension on the server)
204 228 [255]
205 229 #else
206 230 $ hg push -q
207 231 #endif
208 232 $ grep 'lfs' .hg/requires $SERVER_REQUIRES
209 233 .hg/requires:lfs
210 234 $TESTTMP/server/.hg/requires:lfs (lfsremote-on !)
211 235
212 236 $ hg clone -q http://localhost:$HGPORT $TESTTMP/client3_clone
213 237 $ grep 'lfs' $TESTTMP/client3_clone/.hg/requires $SERVER_REQUIRES || true
214 238 $TESTTMP/client3_clone/.hg/requires:lfs (lfsremote-on !)
215 239 $TESTTMP/server/.hg/requires:lfs (lfsremote-on !)
216 240
217 241 $ hg init $TESTTMP/client3_pull
218 242 $ hg -R $TESTTMP/client3_pull pull -q http://localhost:$HGPORT
219 243 $ grep 'lfs' $TESTTMP/client3_pull/.hg/requires $SERVER_REQUIRES || true
220 244 $TESTTMP/client3_pull/.hg/requires:lfs (lfsremote-on !)
221 245 $TESTTMP/server/.hg/requires:lfs (lfsremote-on !)
222 246
223 247 The difference here is the push failed above when the extension isn't
224 248 enabled on the server.
225 249 $ hg identify http://localhost:$HGPORT
226 250 8374dc4052cb (lfsremote-on !)
227 251 1477875038c6 (lfsremote-off !)
228 252
229 253 Don't bother testing the lfsremote-off cases- the server won't be able
230 254 to launch if there's lfs content and the extension is disabled.
231 255
232 256 #if lfsremote-on
233 257
234 258 --------------------------------------------------------------------------------
235 259 Case #4: client with non-lfs content and the extension disabled; server with
236 260 lfs content, and the extension enabled.
237 261
238 262 $ cat >> $HGRCPATH <<EOF
239 263 > [extensions]
240 264 > lfs = !
241 265 > EOF
242 266
243 267 $ hg init $TESTTMP/client4
244 268 $ cd $TESTTMP/client4
245 269 $ cat >> .hg/hgrc <<EOF
246 270 > [paths]
247 271 > default = http://localhost:$HGPORT
248 272 > EOF
249 273 $ echo 'non-lfs' > nonlfs2.txt
250 274 $ hg ci -Aqm 'non-lfs'
251 275 $ grep 'lfs' .hg/requires $SERVER_REQUIRES
252 276 $TESTTMP/server/.hg/requires:lfs
253 277
254 278 $ hg push -q --force
255 279 warning: repository is unrelated
256 280 $ grep 'lfs' .hg/requires $SERVER_REQUIRES
257 281 $TESTTMP/server/.hg/requires:lfs
258 282
259 283 TODO: fail more gracefully.
260 284
261 285 $ hg clone -q http://localhost:$HGPORT $TESTTMP/client4_clone
262 286 abort: HTTP Error 500: Internal Server Error
263 287 [255]
264 288 $ grep 'lfs' $TESTTMP/client4_clone/.hg/requires $SERVER_REQUIRES
265 289 grep: $TESTTMP/client4_clone/.hg/requires: $ENOENT$
266 290 $TESTTMP/server/.hg/requires:lfs
267 291 [2]
268 292
269 293 TODO: fail more gracefully.
270 294
271 295 $ hg init $TESTTMP/client4_pull
272 296 $ hg -R $TESTTMP/client4_pull pull -q http://localhost:$HGPORT
273 297 abort: HTTP Error 500: Internal Server Error
274 298 [255]
275 299 $ grep 'lfs' $TESTTMP/client4_pull/.hg/requires $SERVER_REQUIRES
276 300 $TESTTMP/server/.hg/requires:lfs
277 301
278 302 $ hg identify http://localhost:$HGPORT
279 303 03b080fa9d93
280 304
281 305 --------------------------------------------------------------------------------
282 306 Case #5: client with non-lfs content and the extension enabled; server with
283 307 lfs content, and the extension enabled.
284 308
285 309 $ cat >> $HGRCPATH <<EOF
286 310 > [extensions]
287 311 > lfs =
288 312 > EOF
289 313 $ echo 'non-lfs' > nonlfs3.txt
290 314 $ hg ci -Aqm 'non-lfs file with lfs client'
291 315
292 316 $ hg push -q
293 317 $ grep 'lfs' .hg/requires $SERVER_REQUIRES
294 318 $TESTTMP/server/.hg/requires:lfs
295 319
296 320 $ hg clone -q http://localhost:$HGPORT $TESTTMP/client5_clone
297 321 $ grep 'lfs' $TESTTMP/client5_clone/.hg/requires $SERVER_REQUIRES
298 322 $TESTTMP/client5_clone/.hg/requires:lfs
299 323 $TESTTMP/server/.hg/requires:lfs
300 324
301 325 $ hg init $TESTTMP/client5_pull
302 326 $ hg -R $TESTTMP/client5_pull pull -q http://localhost:$HGPORT
303 327 $ grep 'lfs' $TESTTMP/client5_pull/.hg/requires $SERVER_REQUIRES
304 328 $TESTTMP/client5_pull/.hg/requires:lfs
305 329 $TESTTMP/server/.hg/requires:lfs
306 330
307 331 $ hg identify http://localhost:$HGPORT
308 332 c729025cc5e3
309 333
334 $ mv $HGRCPATH $HGRCPATH.tmp
335 $ cp $HGRCPATH.orig $HGRCPATH
336
337 >>> from __future__ import absolute_import
338 >>> from hgclient import check, readchannel, runcommand
339 >>> @check
340 ... def checkflags(server):
341 ... readchannel(server)
342 ... print('')
343 ... print('# LFS required- both lfs and non-lfs revlogs have 0x2000 flag')
344 ... runcommand(server, ['debugprocessors', 'lfs.bin', '-R',
345 ... '../server'])
346 ... runcommand(server, ['debugprocessors', 'nonlfs2.txt', '-R',
347 ... '../server'])
348 ... runcommand(server, ['config', 'extensions', '--cwd',
349 ... '../server'])
350 ...
351 ... print("\n# LFS not enabled- revlogs don't have 0x2000 flag")
352 ... runcommand(server, ['debugprocessors', 'nonlfs3.txt'])
353 ... runcommand(server, ['config', 'extensions'])
354
355 # LFS required- both lfs and non-lfs revlogs have 0x2000 flag
356 *** runcommand debugprocessors lfs.bin -R ../server
357 registered processor '0x8000'
358 registered processor '0x2000'
359 *** runcommand debugprocessors nonlfs2.txt -R ../server
360 registered processor '0x8000'
361 registered processor '0x2000'
362 *** runcommand config extensions --cwd ../server
363 extensions.debugprocessors=$TESTTMP/debugprocessors.py
364 extensions.lfs=
365
366 # LFS not enabled- revlogs don't have 0x2000 flag
367 *** runcommand debugprocessors nonlfs3.txt
368 registered processor '0x8000'
369 *** runcommand config extensions
370 extensions.debugprocessors=$TESTTMP/debugprocessors.py
371
372 $ rm $HGRCPATH
373 $ mv $HGRCPATH.tmp $HGRCPATH
374
375 $ hg clone $TESTTMP/client $TESTTMP/nonlfs -qr 0 --config extensions.lfs=
376 $ cat >> $TESTTMP/nonlfs/.hg/hgrc <<EOF
377 > [extensions]
378 > lfs = !
379 > EOF
380
381 >>> from __future__ import absolute_import, print_function
382 >>> from hgclient import check, readchannel, runcommand
383 >>> @check
384 ... def checkflags2(server):
385 ... readchannel(server)
386 ... print('')
387 ... print('# LFS enabled- both lfs and non-lfs revlogs have 0x2000 flag')
388 ... runcommand(server, ['debugprocessors', 'lfs.bin', '-R',
389 ... '../server'])
390 ... runcommand(server, ['debugprocessors', 'nonlfs2.txt', '-R',
391 ... '../server'])
392 ... runcommand(server, ['config', 'extensions', '--cwd',
393 ... '../server'])
394 ...
395 ... print('\n# LFS enabled without requirement- revlogs have 0x2000 flag')
396 ... runcommand(server, ['debugprocessors', 'nonlfs3.txt'])
397 ... runcommand(server, ['config', 'extensions'])
398 ...
399 ... print("\n# LFS disabled locally- revlogs don't have 0x2000 flag")
400 ... runcommand(server, ['debugprocessors', 'nonlfs.txt', '-R',
401 ... '../nonlfs'])
402 ... runcommand(server, ['config', 'extensions', '--cwd',
403 ... '../nonlfs'])
404
405 # LFS enabled- both lfs and non-lfs revlogs have 0x2000 flag
406 *** runcommand debugprocessors lfs.bin -R ../server
407 registered processor '0x8000'
408 registered processor '0x2000'
409 *** runcommand debugprocessors nonlfs2.txt -R ../server
410 registered processor '0x8000'
411 registered processor '0x2000'
412 *** runcommand config extensions --cwd ../server
413 extensions.debugprocessors=$TESTTMP/debugprocessors.py
414 extensions.lfs=
415
416 # LFS enabled without requirement- revlogs have 0x2000 flag
417 *** runcommand debugprocessors nonlfs3.txt
418 registered processor '0x8000'
419 registered processor '0x2000'
420 *** runcommand config extensions
421 extensions.debugprocessors=$TESTTMP/debugprocessors.py
422 extensions.lfs=
423
424 # LFS disabled locally- revlogs don't have 0x2000 flag
425 *** runcommand debugprocessors nonlfs.txt -R ../nonlfs
426 registered processor '0x8000'
427 *** runcommand config extensions --cwd ../nonlfs
428 extensions.debugprocessors=$TESTTMP/debugprocessors.py
429 extensions.lfs=!
430
310 431 --------------------------------------------------------------------------------
311 432 Case #6: client with lfs content and the extension enabled; server with
312 433 lfs content, and the extension enabled.
313 434
314 435 $ echo 'this is another lfs file' > lfs2.txt
315 436 $ hg ci -Aqm 'lfs file with lfs client'
316 437
317 438 $ hg --config paths.default= push -v http://localhost:$HGPORT
318 439 pushing to http://localhost:$HGPORT/
319 440 lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs
320 441 searching for changes
321 442 remote has heads on branch 'default' that are not known locally: 8374dc4052cb
322 443 lfs: uploading a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de (25 bytes)
323 444 lfs: processed: a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de
324 445 lfs: uploaded 1 files (25 bytes)
325 446 1 changesets found
326 447 uncompressed size of bundle content:
327 448 206 (changelog)
328 449 172 (manifests)
329 450 275 lfs2.txt
330 451 remote: adding changesets
331 452 remote: adding manifests
332 453 remote: adding file changes
333 454 remote: added 1 changesets with 1 changes to 1 files
334 455 $ grep 'lfs' .hg/requires $SERVER_REQUIRES
335 456 .hg/requires:lfs
336 457 $TESTTMP/server/.hg/requires:lfs
337 458
338 459 $ hg clone -q http://localhost:$HGPORT $TESTTMP/client6_clone
339 460 $ grep 'lfs' $TESTTMP/client6_clone/.hg/requires $SERVER_REQUIRES
340 461 $TESTTMP/client6_clone/.hg/requires:lfs
341 462 $TESTTMP/server/.hg/requires:lfs
342 463
343 464 $ hg init $TESTTMP/client6_pull
344 465 $ hg -R $TESTTMP/client6_pull pull -u -v http://localhost:$HGPORT
345 466 pulling from http://localhost:$HGPORT/
346 467 requesting all changes
347 468 adding changesets
348 469 adding manifests
349 470 adding file changes
350 471 added 6 changesets with 5 changes to 5 files (+1 heads)
351 472 calling hook pretxnchangegroup.lfs: hgext.lfs.checkrequireslfs
352 473 new changesets d437e1d24fbd:d3b84d50eacb
353 474 resolving manifests
354 475 lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs
355 476 lfs: downloading a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de (25 bytes)
356 477 lfs: processed: a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de
357 478 lfs: downloaded 1 files (25 bytes)
358 479 getting lfs2.txt
359 480 lfs: found a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de in the local lfs store
360 481 getting nonlfs2.txt
361 482 getting nonlfs3.txt
362 483 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
363 484 updated to "d3b84d50eacb: lfs file with lfs client"
364 485 1 other heads for branch "default"
365 486 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
366 487 $ grep 'lfs' $TESTTMP/client6_pull/.hg/requires $SERVER_REQUIRES
367 488 $TESTTMP/client6_pull/.hg/requires:lfs
368 489 $TESTTMP/server/.hg/requires:lfs
369 490
370 491 $ hg identify http://localhost:$HGPORT
371 492 d3b84d50eacb
372 493
373 494 --------------------------------------------------------------------------------
374 495 Misc: process dies early if a requirement exists and the extension is disabled
375 496
376 497 $ hg --config extensions.lfs=! summary
377 498 abort: repository requires features unknown to this Mercurial: lfs!
378 499 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
379 500 [255]
380 501
381 502 $ echo 'this is an lfs file' > $TESTTMP/client6_clone/lfspair1.bin
382 503 $ echo 'this is an lfs file too' > $TESTTMP/client6_clone/lfspair2.bin
383 504 $ hg -R $TESTTMP/client6_clone ci -Aqm 'add lfs pair'
384 505 $ hg -R $TESTTMP/client6_clone push -q
385 506
386 507 $ hg clone -qU http://localhost:$HGPORT $TESTTMP/bulkfetch
387 508
388 509 Export will prefetch all needed files across all needed revisions
389 510
390 511 $ hg -R $TESTTMP/bulkfetch -v export -r 0:tip -o all.export
391 512 lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs
392 513 exporting patches:
393 514 lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs
394 515 lfs: need to transfer 4 objects (92 bytes)
395 516 lfs: downloading a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de (25 bytes)
396 517 lfs: processed: a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de
397 518 lfs: downloading bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc (23 bytes)
398 519 lfs: processed: bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc
399 520 lfs: downloading cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782 (20 bytes)
400 521 lfs: processed: cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782
401 522 lfs: downloading d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e (24 bytes)
402 523 lfs: processed: d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e
403 524 lfs: downloaded 4 files (92 bytes)
404 525 all.export
405 526 lfs: found bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc in the local lfs store
406 527 lfs: found a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de in the local lfs store
407 528 lfs: found cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782 in the local lfs store
408 529 lfs: found d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e in the local lfs store
409 530
410 531 Export with selected files is used with `extdiff --patch`
411 532
412 533 $ rm -r $TESTTMP/bulkfetch/.hg/store/lfs
413 534 $ hg --config extensions.extdiff= \
414 535 > -R $TESTTMP/bulkfetch -v extdiff -r 2:tip --patch $TESTTMP/bulkfetch/lfs.bin
415 536 lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs
416 537 lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs
417 538 lfs: downloading bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc (23 bytes)
418 539 lfs: processed: bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc
419 540 lfs: downloaded 1 files (23 bytes)
420 541 */hg-8374dc4052cb.patch (glob)
421 542 lfs: found bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc in the local lfs store
422 543 */hg-9640b57e77b1.patch (glob)
423 544 --- */hg-8374dc4052cb.patch * (glob)
424 545 +++ */hg-9640b57e77b1.patch * (glob)
425 546 @@ -2,12 +2,7 @@
426 547 # User test
427 548 # Date 0 0
428 549 # Thu Jan 01 00:00:00 1970 +0000
429 550 -# Node ID 8374dc4052cbd388e79d9dc4ddb29784097aa354
430 551 -# Parent 1477875038c60152e391238920a16381c627b487
431 552 -lfs
432 553 +# Node ID 9640b57e77b14c3a0144fb4478b6cc13e13ea0d1
433 554 +# Parent d3b84d50eacbd56638e11abce6b8616aaba54420
434 555 +add lfs pair
435 556
436 557 -diff -r 1477875038c6 -r 8374dc4052cb lfs.bin
437 558 ---- /dev/null Thu Jan 01 00:00:00 1970 +0000
438 559 -+++ b/lfs.bin Thu Jan 01 00:00:00 1970 +0000
439 560 -@@ -0,0 +1,1 @@
440 561 -+this is a big lfs file
441 562 cleaning up temp directory
442 563 [1]
443 564
444 565 Diff will prefetch files
445 566
446 567 $ rm -r $TESTTMP/bulkfetch/.hg/store/lfs
447 568 $ hg -R $TESTTMP/bulkfetch -v diff -r 2:tip
448 569 lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs
449 570 lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs
450 571 lfs: need to transfer 4 objects (92 bytes)
451 572 lfs: downloading a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de (25 bytes)
452 573 lfs: processed: a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de
453 574 lfs: downloading bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc (23 bytes)
454 575 lfs: processed: bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc
455 576 lfs: downloading cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782 (20 bytes)
456 577 lfs: processed: cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782
457 578 lfs: downloading d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e (24 bytes)
458 579 lfs: processed: d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e
459 580 lfs: downloaded 4 files (92 bytes)
460 581 lfs: found bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc in the local lfs store
461 582 lfs: found a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de in the local lfs store
462 583 lfs: found cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782 in the local lfs store
463 584 lfs: found d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e in the local lfs store
464 585 diff -r 8374dc4052cb -r 9640b57e77b1 lfs.bin
465 586 --- a/lfs.bin Thu Jan 01 00:00:00 1970 +0000
466 587 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
467 588 @@ -1,1 +0,0 @@
468 589 -this is a big lfs file
469 590 diff -r 8374dc4052cb -r 9640b57e77b1 lfs2.txt
470 591 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
471 592 +++ b/lfs2.txt Thu Jan 01 00:00:00 1970 +0000
472 593 @@ -0,0 +1,1 @@
473 594 +this is another lfs file
474 595 diff -r 8374dc4052cb -r 9640b57e77b1 lfspair1.bin
475 596 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
476 597 +++ b/lfspair1.bin Thu Jan 01 00:00:00 1970 +0000
477 598 @@ -0,0 +1,1 @@
478 599 +this is an lfs file
479 600 diff -r 8374dc4052cb -r 9640b57e77b1 lfspair2.bin
480 601 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
481 602 +++ b/lfspair2.bin Thu Jan 01 00:00:00 1970 +0000
482 603 @@ -0,0 +1,1 @@
483 604 +this is an lfs file too
484 605 diff -r 8374dc4052cb -r 9640b57e77b1 nonlfs.txt
485 606 --- a/nonlfs.txt Thu Jan 01 00:00:00 1970 +0000
486 607 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
487 608 @@ -1,1 +0,0 @@
488 609 -non-lfs
489 610 diff -r 8374dc4052cb -r 9640b57e77b1 nonlfs3.txt
490 611 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
491 612 +++ b/nonlfs3.txt Thu Jan 01 00:00:00 1970 +0000
492 613 @@ -0,0 +1,1 @@
493 614 +non-lfs
494 615
495 616 Only the files required by diff are prefetched
496 617
497 618 $ rm -r $TESTTMP/bulkfetch/.hg/store/lfs
498 619 $ hg -R $TESTTMP/bulkfetch -v diff -r 2:tip $TESTTMP/bulkfetch/lfspair2.bin
499 620 lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs
500 621 lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs
501 622 lfs: downloading d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e (24 bytes)
502 623 lfs: processed: d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e
503 624 lfs: downloaded 1 files (24 bytes)
504 625 lfs: found d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e in the local lfs store
505 626 diff -r 8374dc4052cb -r 9640b57e77b1 lfspair2.bin
506 627 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
507 628 +++ b/lfspair2.bin Thu Jan 01 00:00:00 1970 +0000
508 629 @@ -0,0 +1,1 @@
509 630 +this is an lfs file too
510 631
511 632 #endif
512 633
513 634 $ "$PYTHON" $TESTDIR/killdaemons.py $DAEMON_PIDS
514 635
515 636 #if lfsremote-on
516 637 $ cat $TESTTMP/errors.log | grep '^[A-Z]'
517 638 Traceback (most recent call last):
518 639 ValueError: no common changegroup version
519 640 Traceback (most recent call last):
520 641 ValueError: no common changegroup version
521 642 #else
522 643 $ cat $TESTTMP/errors.log
523 644 #endif
General Comments 0
You need to be logged in to leave comments. Login now