##// END OF EJS Templates
merge with stable
Matt Mackall -
r15909:8435fa20 merge default
parent child Browse files
Show More
@@ -1,500 +1,500 b''
1 1 # Copyright 2009-2010 Gregory P. Ward
2 2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
3 3 # Copyright 2010-2011 Fog Creek Software
4 4 # Copyright 2010-2011 Unity Technologies
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 '''High-level command function for lfconvert, plus the cmdtable.'''
10 10
11 11 import os
12 12 import shutil
13 13
14 14 from mercurial import util, match as match_, hg, node, context, error
15 15 from mercurial.i18n import _
16 16
17 17 import lfutil
18 18 import basestore
19 19
20 20 # -- Commands ----------------------------------------------------------
21 21
22 22 def lfconvert(ui, src, dest, *pats, **opts):
23 23 '''convert a normal repository to a largefiles repository
24 24
25 25 Convert repository SOURCE to a new repository DEST, identical to
26 26 SOURCE except that certain files will be converted as largefiles:
27 27 specifically, any file that matches any PATTERN *or* whose size is
28 28 above the minimum size threshold is converted as a largefile. The
29 29 size used to determine whether or not to track a file as a
30 30 largefile is the size of the first version of the file. The
31 31 minimum size can be specified either with --size or in
32 32 configuration as ``largefiles.size``.
33 33
34 34 After running this command you will need to make sure that
35 35 largefiles is enabled anywhere you intend to push the new
36 36 repository.
37 37
38 38 Use --to-normal to convert largefiles back to normal files; after
39 39 this, the DEST repository can be used without largefiles at all.'''
40 40
41 41 if opts['to_normal']:
42 42 tolfile = False
43 43 else:
44 44 tolfile = True
45 45 size = lfutil.getminsize(ui, True, opts.get('size'), default=None)
46 46
47 47 if not hg.islocal(src):
48 48 raise util.Abort(_('%s is not a local Mercurial repo') % src)
49 49 if not hg.islocal(dest):
50 50 raise util.Abort(_('%s is not a local Mercurial repo') % dest)
51 51
52 52 rsrc = hg.repository(ui, src)
53 53 ui.status(_('initializing destination %s\n') % dest)
54 54 rdst = hg.repository(ui, dest, create=True)
55 55
56 56 success = False
57 57 try:
58 58 # Lock destination to prevent modification while it is converted to.
59 59 # Don't need to lock src because we are just reading from its history
60 60 # which can't change.
61 61 dst_lock = rdst.lock()
62 62
63 63 # Get a list of all changesets in the source. The easy way to do this
64 64 # is to simply walk the changelog, using changelog.nodesbewteen().
65 65 # Take a look at mercurial/revlog.py:639 for more details.
66 66 # Use a generator instead of a list to decrease memory usage
67 67 ctxs = (rsrc[ctx] for ctx in rsrc.changelog.nodesbetween(None,
68 68 rsrc.heads())[0])
69 69 revmap = {node.nullid: node.nullid}
70 70 if tolfile:
71 71 lfiles = set()
72 72 normalfiles = set()
73 73 if not pats:
74 74 pats = ui.configlist(lfutil.longname, 'patterns', default=[])
75 75 if pats:
76 76 matcher = match_.match(rsrc.root, '', list(pats))
77 77 else:
78 78 matcher = None
79 79
80 80 lfiletohash = {}
81 81 for ctx in ctxs:
82 82 ui.progress(_('converting revisions'), ctx.rev(),
83 83 unit=_('revision'), total=rsrc['tip'].rev())
84 84 _lfconvert_addchangeset(rsrc, rdst, ctx, revmap,
85 85 lfiles, normalfiles, matcher, size, lfiletohash)
86 86 ui.progress(_('converting revisions'), None)
87 87
88 88 if os.path.exists(rdst.wjoin(lfutil.shortname)):
89 89 shutil.rmtree(rdst.wjoin(lfutil.shortname))
90 90
91 91 for f in lfiletohash.keys():
92 92 if os.path.isfile(rdst.wjoin(f)):
93 93 os.unlink(rdst.wjoin(f))
94 94 try:
95 95 os.removedirs(os.path.dirname(rdst.wjoin(f)))
96 96 except OSError:
97 97 pass
98 98
99 99 # If there were any files converted to largefiles, add largefiles
100 100 # to the destination repository's requirements.
101 101 if lfiles:
102 102 rdst.requirements.add('largefiles')
103 103 rdst._writerequirements()
104 104 else:
105 105 for ctx in ctxs:
106 106 ui.progress(_('converting revisions'), ctx.rev(),
107 107 unit=_('revision'), total=rsrc['tip'].rev())
108 108 _addchangeset(ui, rsrc, rdst, ctx, revmap)
109 109
110 110 ui.progress(_('converting revisions'), None)
111 111 success = True
112 112 finally:
113 113 if not success:
114 114 # we failed, remove the new directory
115 115 shutil.rmtree(rdst.root)
116 116 dst_lock.release()
117 117
118 118 def _addchangeset(ui, rsrc, rdst, ctx, revmap):
119 119 # Convert src parents to dst parents
120 120 parents = _convertparents(ctx, revmap)
121 121
122 122 # Generate list of changed files
123 123 files = _getchangedfiles(ctx, parents)
124 124
125 125 def getfilectx(repo, memctx, f):
126 126 if lfutil.standin(f) in files:
127 127 # if the file isn't in the manifest then it was removed
128 128 # or renamed, raise IOError to indicate this
129 129 try:
130 130 fctx = ctx.filectx(lfutil.standin(f))
131 131 except error.LookupError:
132 132 raise IOError()
133 133 renamed = fctx.renamed()
134 134 if renamed:
135 135 renamed = lfutil.splitstandin(renamed[0])
136 136
137 137 hash = fctx.data().strip()
138 138 path = lfutil.findfile(rsrc, hash)
139 139 ### TODO: What if the file is not cached?
140 140 data = ''
141 141 fd = None
142 142 try:
143 143 fd = open(path, 'rb')
144 144 data = fd.read()
145 145 finally:
146 146 if fd:
147 147 fd.close()
148 148 return context.memfilectx(f, data, 'l' in fctx.flags(),
149 149 'x' in fctx.flags(), renamed)
150 150 else:
151 151 return _getnormalcontext(repo.ui, ctx, f, revmap)
152 152
153 153 dstfiles = []
154 154 for file in files:
155 155 if lfutil.isstandin(file):
156 156 dstfiles.append(lfutil.splitstandin(file))
157 157 else:
158 158 dstfiles.append(file)
159 159 # Commit
160 160 _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap)
161 161
162 162 def _lfconvert_addchangeset(rsrc, rdst, ctx, revmap, lfiles, normalfiles,
163 163 matcher, size, lfiletohash):
164 164 # Convert src parents to dst parents
165 165 parents = _convertparents(ctx, revmap)
166 166
167 167 # Generate list of changed files
168 168 files = _getchangedfiles(ctx, parents)
169 169
170 170 dstfiles = []
171 171 for f in files:
172 172 if f not in lfiles and f not in normalfiles:
173 173 islfile = _islfile(f, ctx, matcher, size)
174 174 # If this file was renamed or copied then copy
175 175 # the lfileness of its predecessor
176 176 if f in ctx.manifest():
177 177 fctx = ctx.filectx(f)
178 178 renamed = fctx.renamed()
179 179 renamedlfile = renamed and renamed[0] in lfiles
180 180 islfile |= renamedlfile
181 181 if 'l' in fctx.flags():
182 182 if renamedlfile:
183 183 raise util.Abort(
184 184 _('renamed/copied largefile %s becomes symlink')
185 185 % f)
186 186 islfile = False
187 187 if islfile:
188 188 lfiles.add(f)
189 189 else:
190 190 normalfiles.add(f)
191 191
192 192 if f in lfiles:
193 193 dstfiles.append(lfutil.standin(f))
194 194 # largefile in manifest if it has not been removed/renamed
195 195 if f in ctx.manifest():
196 196 fctx = ctx.filectx(f)
197 197 if 'l' in fctx.flags():
198 198 renamed = fctx.renamed()
199 199 if renamed and renamed[0] in lfiles:
200 200 raise util.Abort(_('largefile %s becomes symlink') % f)
201 201
202 202 # largefile was modified, update standins
203 203 fullpath = rdst.wjoin(f)
204 204 util.makedirs(os.path.dirname(fullpath))
205 205 m = util.sha1('')
206 206 m.update(ctx[f].data())
207 207 hash = m.hexdigest()
208 208 if f not in lfiletohash or lfiletohash[f] != hash:
209 209 try:
210 210 fd = open(fullpath, 'wb')
211 211 fd.write(ctx[f].data())
212 212 finally:
213 213 if fd:
214 214 fd.close()
215 215 executable = 'x' in ctx[f].flags()
216 216 os.chmod(fullpath, lfutil.getmode(executable))
217 217 lfutil.writestandin(rdst, lfutil.standin(f), hash,
218 218 executable)
219 219 lfiletohash[f] = hash
220 220 else:
221 221 # normal file
222 222 dstfiles.append(f)
223 223
224 224 def getfilectx(repo, memctx, f):
225 225 if lfutil.isstandin(f):
226 226 # if the file isn't in the manifest then it was removed
227 227 # or renamed, raise IOError to indicate this
228 228 srcfname = lfutil.splitstandin(f)
229 229 try:
230 230 fctx = ctx.filectx(srcfname)
231 231 except error.LookupError:
232 232 raise IOError()
233 233 renamed = fctx.renamed()
234 234 if renamed:
235 235 # standin is always a largefile because largefile-ness
236 236 # doesn't change after rename or copy
237 237 renamed = lfutil.standin(renamed[0])
238 238
239 239 return context.memfilectx(f, lfiletohash[srcfname] + '\n', 'l' in
240 240 fctx.flags(), 'x' in fctx.flags(), renamed)
241 241 else:
242 242 return _getnormalcontext(repo.ui, ctx, f, revmap)
243 243
244 244 # Commit
245 245 _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap)
246 246
247 247 def _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap):
248 248 mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
249 249 getfilectx, ctx.user(), ctx.date(), ctx.extra())
250 250 ret = rdst.commitctx(mctx)
251 251 rdst.dirstate.setparents(ret)
252 252 revmap[ctx.node()] = rdst.changelog.tip()
253 253
254 254 # Generate list of changed files
255 255 def _getchangedfiles(ctx, parents):
256 256 files = set(ctx.files())
257 257 if node.nullid not in parents:
258 258 mc = ctx.manifest()
259 259 mp1 = ctx.parents()[0].manifest()
260 260 mp2 = ctx.parents()[1].manifest()
261 261 files |= (set(mp1) | set(mp2)) - set(mc)
262 262 for f in mc:
263 263 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
264 264 files.add(f)
265 265 return files
266 266
267 267 # Convert src parents to dst parents
268 268 def _convertparents(ctx, revmap):
269 269 parents = []
270 270 for p in ctx.parents():
271 271 parents.append(revmap[p.node()])
272 272 while len(parents) < 2:
273 273 parents.append(node.nullid)
274 274 return parents
275 275
276 276 # Get memfilectx for a normal file
277 277 def _getnormalcontext(ui, ctx, f, revmap):
278 278 try:
279 279 fctx = ctx.filectx(f)
280 280 except error.LookupError:
281 281 raise IOError()
282 282 renamed = fctx.renamed()
283 283 if renamed:
284 284 renamed = renamed[0]
285 285
286 286 data = fctx.data()
287 287 if f == '.hgtags':
288 288 data = _converttags (ui, revmap, data)
289 289 return context.memfilectx(f, data, 'l' in fctx.flags(),
290 290 'x' in fctx.flags(), renamed)
291 291
292 292 # Remap tag data using a revision map
293 293 def _converttags(ui, revmap, data):
294 294 newdata = []
295 295 for line in data.splitlines():
296 296 try:
297 297 id, name = line.split(' ', 1)
298 298 except ValueError:
299 299 ui.warn(_('skipping incorrectly formatted tag %s\n'
300 300 % line))
301 301 continue
302 302 try:
303 303 newid = node.bin(id)
304 304 except TypeError:
305 305 ui.warn(_('skipping incorrectly formatted id %s\n'
306 306 % id))
307 307 continue
308 308 try:
309 309 newdata.append('%s %s\n' % (node.hex(revmap[newid]),
310 310 name))
311 311 except KeyError:
312 312 ui.warn(_('no mapping for id %s\n' % id))
313 313 continue
314 314 return ''.join(newdata)
315 315
316 316 def _islfile(file, ctx, matcher, size):
317 317 '''Return true if file should be considered a largefile, i.e.
318 318 matcher matches it or it is larger than size.'''
319 319 # never store special .hg* files as largefiles
320 320 if file == '.hgtags' or file == '.hgignore' or file == '.hgsigs':
321 321 return False
322 322 if matcher and matcher(file):
323 323 return True
324 324 try:
325 325 return ctx.filectx(file).size() >= size * 1024 * 1024
326 326 except error.LookupError:
327 327 return False
328 328
329 329 def uploadlfiles(ui, rsrc, rdst, files):
330 330 '''upload largefiles to the central store'''
331 331
332 332 if not files:
333 333 return
334 334
335 335 store = basestore._openstore(rsrc, rdst, put=True)
336 336
337 337 at = 0
338 338 files = filter(lambda h: not store.exists(h), files)
339 339 for hash in files:
340 340 ui.progress(_('uploading largefiles'), at, unit='largefile',
341 341 total=len(files))
342 342 source = lfutil.findfile(rsrc, hash)
343 343 if not source:
344 344 raise util.Abort(_('largefile %s missing from store'
345 345 ' (needs to be uploaded)') % hash)
346 346 # XXX check for errors here
347 347 store.put(source, hash)
348 348 at += 1
349 349 ui.progress(_('uploading largefiles'), None)
350 350
351 351 def verifylfiles(ui, repo, all=False, contents=False):
352 352 '''Verify that every big file revision in the current changeset
353 353 exists in the central store. With --contents, also verify that
354 354 the contents of each big file revision are correct (SHA-1 hash
355 355 matches the revision ID). With --all, check every changeset in
356 356 this repository.'''
357 357 if all:
358 358 # Pass a list to the function rather than an iterator because we know a
359 359 # list will work.
360 360 revs = range(len(repo))
361 361 else:
362 362 revs = ['.']
363 363
364 364 store = basestore._openstore(repo)
365 365 return store.verify(revs, contents=contents)
366 366
367 367 def cachelfiles(ui, repo, node):
368 368 '''cachelfiles ensures that all largefiles needed by the specified revision
369 369 are present in the repository's largefile cache.
370 370
371 371 returns a tuple (cached, missing). cached is the list of files downloaded
372 372 by this operation; missing is the list of files that were needed but could
373 373 not be found.'''
374 374 lfiles = lfutil.listlfiles(repo, node)
375 375 toget = []
376 376
377 377 for lfile in lfiles:
378 378 # If we are mid-merge, then we have to trust the standin that is in the
379 379 # working copy to have the correct hashvalue. This is because the
380 380 # original hg.merge() already updated the standin as part of the normal
381 381 # merge process -- we just have to udpate the largefile to match.
382 382 if (getattr(repo, "_ismerging", False) and
383 383 os.path.exists(repo.wjoin(lfutil.standin(lfile)))):
384 384 expectedhash = lfutil.readstandin(repo, lfile)
385 385 else:
386 386 expectedhash = repo[node][lfutil.standin(lfile)].data().strip()
387 387
388 388 # if it exists and its hash matches, it might have been locally
389 389 # modified before updating and the user chose 'local'. in this case,
390 390 # it will not be in any store, so don't look for it.
391 391 if ((not os.path.exists(repo.wjoin(lfile)) or
392 392 expectedhash != lfutil.hashfile(repo.wjoin(lfile))) and
393 393 not lfutil.findfile(repo, expectedhash)):
394 394 toget.append((lfile, expectedhash))
395 395
396 396 if toget:
397 397 store = basestore._openstore(repo)
398 398 ret = store.get(toget)
399 399 return ret
400 400
401 401 return ([], [])
402 402
403 403 def updatelfiles(ui, repo, filelist=None, printmessage=True):
404 404 wlock = repo.wlock()
405 405 try:
406 406 lfdirstate = lfutil.openlfdirstate(ui, repo)
407 407 lfiles = set(lfutil.listlfiles(repo)) | set(lfdirstate)
408 408
409 409 if filelist is not None:
410 410 lfiles = [f for f in lfiles if f in filelist]
411 411
412 412 printed = False
413 413 if printmessage and lfiles:
414 414 ui.status(_('getting changed largefiles\n'))
415 415 printed = True
416 416 cachelfiles(ui, repo, '.')
417 417
418 418 updated, removed = 0, 0
419 419 for i in map(lambda f: _updatelfile(repo, lfdirstate, f), lfiles):
420 420 # increment the appropriate counter according to _updatelfile's
421 421 # return value
422 422 updated += i > 0 and i or 0
423 423 removed -= i < 0 and i or 0
424 424 if printmessage and (removed or updated) and not printed:
425 425 ui.status(_('getting changed largefiles\n'))
426 426 printed = True
427 427
428 428 lfdirstate.write()
429 429 if printed and printmessage:
430 430 ui.status(_('%d largefiles updated, %d removed\n') % (updated,
431 431 removed))
432 432 finally:
433 433 wlock.release()
434 434
435 435 def _updatelfile(repo, lfdirstate, lfile):
436 436 '''updates a single largefile and copies the state of its standin from
437 437 the repository's dirstate to its state in the lfdirstate.
438 438
439 439 returns 1 if the file was modified, -1 if the file was removed, 0 if the
440 440 file was unchanged, and None if the needed largefile was missing from the
441 441 cache.'''
442 442 ret = 0
443 443 abslfile = repo.wjoin(lfile)
444 444 absstandin = repo.wjoin(lfutil.standin(lfile))
445 445 if os.path.exists(absstandin):
446 446 if os.path.exists(absstandin+'.orig'):
447 447 shutil.copyfile(abslfile, abslfile+'.orig')
448 448 expecthash = lfutil.readstandin(repo, lfile)
449 449 if (expecthash != '' and
450 450 (not os.path.exists(abslfile) or
451 451 expecthash != lfutil.hashfile(abslfile))):
452 452 if not lfutil.copyfromcache(repo, expecthash, lfile):
453 453 # use normallookup() to allocate entry in largefiles dirstate,
454 454 # because lack of it misleads lfiles_repo.status() into
455 455 # recognition that such cache missing files are REMOVED.
456 456 lfdirstate.normallookup(lfile)
457 457 return None # don't try to set the mode
458 458 ret = 1
459 459 mode = os.stat(absstandin).st_mode
460 460 if mode != os.stat(abslfile).st_mode:
461 461 os.chmod(abslfile, mode)
462 462 ret = 1
463 463 else:
464 464 # Remove lfiles for which the standin is deleted, unless the
465 465 # lfile is added to the repository again. This happens when a
466 466 # largefile is converted back to a normal file: the standin
467 467 # disappears, but a new (normal) file appears as the lfile.
468 468 if os.path.exists(abslfile) and lfile not in repo[None]:
469 os.unlink(abslfile)
469 util.unlinkpath(abslfile)
470 470 ret = -1
471 471 state = repo.dirstate[lfutil.standin(lfile)]
472 472 if state == 'n':
473 473 # When rebasing, we need to synchronize the standin and the largefile,
474 474 # because otherwise the largefile will get reverted. But for commit's
475 475 # sake, we have to mark the file as unclean.
476 476 if getattr(repo, "_isrebasing", False):
477 477 lfdirstate.normallookup(lfile)
478 478 else:
479 479 lfdirstate.normal(lfile)
480 480 elif state == 'r':
481 481 lfdirstate.remove(lfile)
482 482 elif state == 'a':
483 483 lfdirstate.add(lfile)
484 484 elif state == '?':
485 485 lfdirstate.drop(lfile)
486 486 return ret
487 487
488 488 # -- hg commands declarations ------------------------------------------------
489 489
490 490 cmdtable = {
491 491 'lfconvert': (lfconvert,
492 492 [('s', 'size', '',
493 493 _('minimum size (MB) for files to be converted '
494 494 'as largefiles'),
495 495 'SIZE'),
496 496 ('', 'to-normal', False,
497 497 _('convert from a largefiles repo to a normal repo')),
498 498 ],
499 499 _('hg lfconvert SOURCE DEST [FILE ...]')),
500 500 }
@@ -1,915 +1,923 b''
1 1 $ "$TESTDIR/hghave" symlink unix-permissions serve || exit 80
2 2 $ USERCACHE=`pwd`/cache; export USERCACHE
3 3 $ mkdir -p ${USERCACHE}
4 4 $ cat >> $HGRCPATH <<EOF
5 5 > [extensions]
6 6 > largefiles=
7 7 > purge=
8 8 > rebase=
9 9 > transplant=
10 10 > [phases]
11 11 > publish=False
12 12 > [largefiles]
13 13 > minsize=2
14 14 > patterns=glob:**.dat
15 15 > usercache=${USERCACHE}
16 16 > [hooks]
17 17 > precommit=echo "Invoking status precommit hook"; hg status
18 18 > EOF
19 19
20 20 Create the repo with a couple of revisions of both large and normal
21 21 files, testing that status correctly shows largefiles and that summary output
22 22 is correct.
23 23
24 24 $ hg init a
25 25 $ cd a
26 26 $ mkdir sub
27 27 $ echo normal1 > normal1
28 28 $ echo normal2 > sub/normal2
29 29 $ echo large1 > large1
30 30 $ echo large2 > sub/large2
31 31 $ hg add normal1 sub/normal2
32 32 $ hg add --large large1 sub/large2
33 33 $ hg commit -m "add files"
34 34 Invoking status precommit hook
35 35 A large1
36 36 A normal1
37 37 A sub/large2
38 38 A sub/normal2
39 39 $ echo normal11 > normal1
40 40 $ echo normal22 > sub/normal2
41 41 $ echo large11 > large1
42 42 $ echo large22 > sub/large2
43 43 $ hg commit -m "edit files"
44 44 Invoking status precommit hook
45 45 M large1
46 46 M normal1
47 47 M sub/large2
48 48 M sub/normal2
49 49 $ hg sum --large
50 50 parent: 1:ce8896473775 tip
51 51 edit files
52 52 branch: default
53 53 commit: (clean)
54 54 update: (current)
55 55 largefiles: No remote repo
56 56
57 57 Commit preserved largefile contents.
58 58
59 59 $ cat normal1
60 60 normal11
61 61 $ cat large1
62 62 large11
63 63 $ cat sub/normal2
64 64 normal22
65 65 $ cat sub/large2
66 66 large22
67 67
68 68 Remove both largefiles and normal files.
69 69
70 70 $ hg remove normal1 large1
71 71 $ hg commit -m "remove files"
72 72 Invoking status precommit hook
73 73 R large1
74 74 R normal1
75 75 $ ls
76 76 sub
77 77 $ echo "testlargefile" > large1-test
78 78 $ hg add --large large1-test
79 79 $ hg st
80 80 A large1-test
81 81 $ hg rm large1-test
82 82 not removing large1-test: file has been marked for add (use forget to undo)
83 83 $ hg st
84 84 A large1-test
85 85 $ hg forget large1-test
86 86 $ hg st
87 87 ? large1-test
88 88 $ rm large1-test
89 89
90 90 Copy both largefiles and normal files (testing that status output is correct).
91 91
92 92 $ hg cp sub/normal2 normal1
93 93 $ hg cp sub/large2 large1
94 94 $ hg commit -m "copy files"
95 95 Invoking status precommit hook
96 96 A large1
97 97 A normal1
98 98 $ cat normal1
99 99 normal22
100 100 $ cat large1
101 101 large22
102 102
103 103 Test moving largefiles and verify that normal files are also unaffected.
104 104
105 105 $ hg mv normal1 normal3
106 106 $ hg mv large1 large3
107 107 $ hg mv sub/normal2 sub/normal4
108 108 $ hg mv sub/large2 sub/large4
109 109 $ hg commit -m "move files"
110 110 Invoking status precommit hook
111 111 A large3
112 112 A normal3
113 113 A sub/large4
114 114 A sub/normal4
115 115 R large1
116 116 R normal1
117 117 R sub/large2
118 118 R sub/normal2
119 119 $ cat normal3
120 120 normal22
121 121 $ cat large3
122 122 large22
123 123 $ cat sub/normal4
124 124 normal22
125 125 $ cat sub/large4
126 126 large22
127 127
128 128 Test archiving the various revisions. These hit corner cases known with
129 129 archiving.
130 130
131 131 $ hg archive -r 0 ../archive0
132 132 $ hg archive -r 1 ../archive1
133 133 $ hg archive -r 2 ../archive2
134 134 $ hg archive -r 3 ../archive3
135 135 $ hg archive -r 4 ../archive4
136 136 $ cd ../archive0
137 137 $ cat normal1
138 138 normal1
139 139 $ cat large1
140 140 large1
141 141 $ cat sub/normal2
142 142 normal2
143 143 $ cat sub/large2
144 144 large2
145 145 $ cd ../archive1
146 146 $ cat normal1
147 147 normal11
148 148 $ cat large1
149 149 large11
150 150 $ cat sub/normal2
151 151 normal22
152 152 $ cat sub/large2
153 153 large22
154 154 $ cd ../archive2
155 155 $ ls
156 156 sub
157 157 $ cat sub/normal2
158 158 normal22
159 159 $ cat sub/large2
160 160 large22
161 161 $ cd ../archive3
162 162 $ cat normal1
163 163 normal22
164 164 $ cat large1
165 165 large22
166 166 $ cat sub/normal2
167 167 normal22
168 168 $ cat sub/large2
169 169 large22
170 170 $ cd ../archive4
171 171 $ cat normal3
172 172 normal22
173 173 $ cat large3
174 174 large22
175 175 $ cat sub/normal4
176 176 normal22
177 177 $ cat sub/large4
178 178 large22
179 179
180 180 Commit corner case: specify files to commit.
181 181
182 182 $ cd ../a
183 183 $ echo normal3 > normal3
184 184 $ echo large3 > large3
185 185 $ echo normal4 > sub/normal4
186 186 $ echo large4 > sub/large4
187 187 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
188 188 Invoking status precommit hook
189 189 M large3
190 190 M normal3
191 191 M sub/large4
192 192 M sub/normal4
193 193 $ cat normal3
194 194 normal3
195 195 $ cat large3
196 196 large3
197 197 $ cat sub/normal4
198 198 normal4
199 199 $ cat sub/large4
200 200 large4
201 201
202 202 One more commit corner case: commit from a subdirectory.
203 203
204 204 $ cd ../a
205 205 $ echo normal33 > normal3
206 206 $ echo large33 > large3
207 207 $ echo normal44 > sub/normal4
208 208 $ echo large44 > sub/large4
209 209 $ cd sub
210 210 $ hg commit -m "edit files yet again"
211 211 Invoking status precommit hook
212 212 M large3
213 213 M normal3
214 214 M sub/large4
215 215 M sub/normal4
216 216 $ cat ../normal3
217 217 normal33
218 218 $ cat ../large3
219 219 large33
220 220 $ cat normal4
221 221 normal44
222 222 $ cat large4
223 223 large44
224 224
225 225 Committing standins is not allowed.
226 226
227 227 $ cd ..
228 228 $ echo large3 > large3
229 229 $ hg commit .hglf/large3 -m "try to commit standin"
230 230 abort: file ".hglf/large3" is a largefile standin
231 231 (commit the largefile itself instead)
232 232 [255]
233 233
234 234 Corner cases for adding largefiles.
235 235
236 236 $ echo large5 > large5
237 237 $ hg add --large large5
238 238 $ hg add --large large5
239 239 large5 already a largefile
240 240 $ mkdir sub2
241 241 $ echo large6 > sub2/large6
242 242 $ echo large7 > sub2/large7
243 243 $ hg add --large sub2
244 244 adding sub2/large6 as a largefile (glob)
245 245 adding sub2/large7 as a largefile (glob)
246 246 $ hg st
247 247 M large3
248 248 A large5
249 249 A sub2/large6
250 250 A sub2/large7
251 251
252 252 Config settings (pattern **.dat, minsize 2 MB) are respected.
253 253
254 254 $ echo testdata > test.dat
255 255 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
256 256 $ hg add
257 257 adding reallylarge as a largefile
258 258 adding test.dat as a largefile
259 259
260 260 Test that minsize and --lfsize handle float values;
261 261 also tests that --lfsize overrides largefiles.minsize.
262 262 (0.250 MB = 256 kB = 262144 B)
263 263
264 264 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
265 265 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
266 266 $ hg --config largefiles.minsize=.25 add
267 267 adding ratherlarge as a largefile
268 268 adding medium
269 269 $ hg forget medium
270 270 $ hg --config largefiles.minsize=.25 add --lfsize=.125
271 271 adding medium as a largefile
272 272 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
273 273 $ hg --config largefiles.minsize=.25 add --lfsize=.125
274 274 adding notlarge
275 275 $ hg forget notlarge
276 276
277 277 Test forget on largefiles.
278 278
279 279 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
280 280 $ hg commit -m "add/edit more largefiles"
281 281 Invoking status precommit hook
282 282 A sub2/large6
283 283 A sub2/large7
284 284 R large3
285 285 ? large5
286 286 ? medium
287 287 ? notlarge
288 288 ? ratherlarge
289 289 ? reallylarge
290 290 ? test.dat
291 291 $ hg st
292 292 ? large3
293 293 ? large5
294 294 ? medium
295 295 ? notlarge
296 296 ? ratherlarge
297 297 ? reallylarge
298 298 ? test.dat
299 299
300 300 Purge with largefiles: verify that largefiles are still in the working
301 301 dir after a purge.
302 302
303 303 $ hg purge --all
304 304 $ cat sub/large4
305 305 large44
306 306 $ cat sub2/large6
307 307 large6
308 308 $ cat sub2/large7
309 309 large7
310 310
311 311 Test addremove: verify that files that should be added as largfiles are added as
312 312 such and that already-existing largfiles are not added as normal files by
313 313 accident.
314 314
315 315 $ rm normal3
316 316 $ rm sub/large4
317 317 $ echo "testing addremove with patterns" > testaddremove.dat
318 318 $ echo "normaladdremove" > normaladdremove
319 319 $ hg addremove
320 320 removing sub/large4
321 321 adding testaddremove.dat as a largefile
322 322 removing normal3
323 323 adding normaladdremove
324 324
325 325 Clone a largefiles repo.
326 326
327 327 $ hg clone . ../b
328 328 updating to branch default
329 329 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
330 330 getting changed largefiles
331 331 3 largefiles updated, 0 removed
332 332 $ cd ../b
333 333 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
334 334 7:daea875e9014 add/edit more largefiles
335 335 6:4355d653f84f edit files yet again
336 336 5:9d5af5072dbd edit files again
337 337 4:74c02385b94c move files
338 338 3:9e8fbc4bce62 copy files
339 339 2:51a0ae4d5864 remove files
340 340 1:ce8896473775 edit files
341 341 0:30d30fe6a5be add files
342 342 $ cat normal3
343 343 normal33
344 344 $ cat sub/normal4
345 345 normal44
346 346 $ cat sub/large4
347 347 large44
348 348 $ cat sub2/large6
349 349 large6
350 350 $ cat sub2/large7
351 351 large7
352 352 $ cd ..
353 353 $ hg clone a -r 3 c
354 354 adding changesets
355 355 adding manifests
356 356 adding file changes
357 357 added 4 changesets with 10 changes to 4 files
358 358 updating to branch default
359 359 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
360 360 getting changed largefiles
361 361 2 largefiles updated, 0 removed
362 362 $ cd c
363 363 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
364 364 3:9e8fbc4bce62 copy files
365 365 2:51a0ae4d5864 remove files
366 366 1:ce8896473775 edit files
367 367 0:30d30fe6a5be add files
368 368 $ cat normal1
369 369 normal22
370 370 $ cat large1
371 371 large22
372 372 $ cat sub/normal2
373 373 normal22
374 374 $ cat sub/large2
375 375 large22
376 376
377 377 Old revisions of a clone have correct largefiles content (this also
378 378 tests update).
379 379
380 380 $ hg update -r 1
381 381 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
382 382 getting changed largefiles
383 383 1 largefiles updated, 0 removed
384 384 $ cat large1
385 385 large11
386 386 $ cat sub/large2
387 387 large22
388 388
389 389 Rebasing between two repositories does not revert largefiles to old
390 390 revisions (this was a very bad bug that took a lot of work to fix).
391 391
392 392 $ cd ..
393 393 $ hg clone a d
394 394 updating to branch default
395 395 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
396 396 getting changed largefiles
397 397 3 largefiles updated, 0 removed
398 398 $ cd b
399 399 $ echo large4-modified > sub/large4
400 400 $ echo normal3-modified > normal3
401 401 $ hg commit -m "modify normal file and largefile in repo b"
402 402 Invoking status precommit hook
403 403 M normal3
404 404 M sub/large4
405 405 $ cd ../d
406 406 $ echo large6-modified > sub2/large6
407 407 $ echo normal4-modified > sub/normal4
408 408 $ hg commit -m "modify normal file largefile in repo d"
409 409 Invoking status precommit hook
410 410 M sub/normal4
411 411 M sub2/large6
412 412 $ cd ..
413 413 $ hg clone d e
414 414 updating to branch default
415 415 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
416 416 getting changed largefiles
417 417 3 largefiles updated, 0 removed
418 418 $ cd d
419 419 $ hg pull --rebase ../b
420 420 pulling from ../b
421 421 searching for changes
422 422 adding changesets
423 423 adding manifests
424 424 adding file changes
425 425 added 1 changesets with 2 changes to 2 files (+1 heads)
426 426 getting changed largefiles
427 427 1 largefiles updated, 0 removed
428 428 Invoking status precommit hook
429 429 M sub/normal4
430 430 M sub2/large6
431 431 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg
432 432 nothing to rebase
433 433 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
434 434 9:598410d3eb9a modify normal file largefile in repo d
435 435 8:a381d2c8c80e modify normal file and largefile in repo b
436 436 7:daea875e9014 add/edit more largefiles
437 437 6:4355d653f84f edit files yet again
438 438 5:9d5af5072dbd edit files again
439 439 4:74c02385b94c move files
440 440 3:9e8fbc4bce62 copy files
441 441 2:51a0ae4d5864 remove files
442 442 1:ce8896473775 edit files
443 443 0:30d30fe6a5be add files
444 444 $ cat normal3
445 445 normal3-modified
446 446 $ cat sub/normal4
447 447 normal4-modified
448 448 $ cat sub/large4
449 449 large4-modified
450 450 $ cat sub2/large6
451 451 large6-modified
452 452 $ cat sub2/large7
453 453 large7
454 454 $ cd ../e
455 455 $ hg pull ../b
456 456 pulling from ../b
457 457 searching for changes
458 458 adding changesets
459 459 adding manifests
460 460 adding file changes
461 461 added 1 changesets with 2 changes to 2 files (+1 heads)
462 462 (run 'hg heads' to see heads, 'hg merge' to merge)
463 463 $ hg rebase
464 464 getting changed largefiles
465 465 1 largefiles updated, 0 removed
466 466 Invoking status precommit hook
467 467 M sub/normal4
468 468 M sub2/large6
469 469 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg
470 470 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
471 471 9:598410d3eb9a modify normal file largefile in repo d
472 472 8:a381d2c8c80e modify normal file and largefile in repo b
473 473 7:daea875e9014 add/edit more largefiles
474 474 6:4355d653f84f edit files yet again
475 475 5:9d5af5072dbd edit files again
476 476 4:74c02385b94c move files
477 477 3:9e8fbc4bce62 copy files
478 478 2:51a0ae4d5864 remove files
479 479 1:ce8896473775 edit files
480 480 0:30d30fe6a5be add files
481 481 $ cat normal3
482 482 normal3-modified
483 483 $ cat sub/normal4
484 484 normal4-modified
485 485 $ cat sub/large4
486 486 large4-modified
487 487 $ cat sub2/large6
488 488 large6-modified
489 489 $ cat sub2/large7
490 490 large7
491 491
492 492 Rollback on largefiles.
493 493
494 494 $ echo large4-modified-again > sub/large4
495 495 $ hg commit -m "Modify large4 again"
496 496 Invoking status precommit hook
497 497 M sub/large4
498 498 $ hg rollback
499 499 repository tip rolled back to revision 9 (undo commit)
500 500 working directory now based on revision 9
501 501 $ hg st
502 502 M sub/large4
503 503 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
504 504 9:598410d3eb9a modify normal file largefile in repo d
505 505 8:a381d2c8c80e modify normal file and largefile in repo b
506 506 7:daea875e9014 add/edit more largefiles
507 507 6:4355d653f84f edit files yet again
508 508 5:9d5af5072dbd edit files again
509 509 4:74c02385b94c move files
510 510 3:9e8fbc4bce62 copy files
511 511 2:51a0ae4d5864 remove files
512 512 1:ce8896473775 edit files
513 513 0:30d30fe6a5be add files
514 514 $ cat sub/large4
515 515 large4-modified-again
516 516
517 517 "update --check" refuses to update with uncommitted changes.
518 518 $ hg update --check 8
519 519 abort: uncommitted local changes
520 520 [255]
521 521
522 522 "update --clean" leaves correct largefiles in working copy.
523 523
524 524 $ hg update --clean
525 525 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
526 526 getting changed largefiles
527 527 1 largefiles updated, 0 removed
528 528 $ cat normal3
529 529 normal3-modified
530 530 $ cat sub/normal4
531 531 normal4-modified
532 532 $ cat sub/large4
533 533 large4-modified
534 534 $ cat sub2/large6
535 535 large6-modified
536 536 $ cat sub2/large7
537 537 large7
538 538
539 539 Now "update check" is happy.
540 540 $ hg update --check 8
541 541 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
542 542 getting changed largefiles
543 543 1 largefiles updated, 0 removed
544 544 $ hg update --check
545 545 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
546 546 getting changed largefiles
547 547 1 largefiles updated, 0 removed
548 548
549 Test removing empty largefiles directories on update
550 $ test -d sub2 && echo "sub2 exists"
551 sub2 exists
552 $ hg update -q null
553 $ test -d sub2 && echo "error: sub2 should not exist anymore"
554 [1]
555 $ hg update -q
556
549 557 "revert" works on largefiles (and normal files too).
550 558 $ echo hack3 >> normal3
551 559 $ echo hack4 >> sub/normal4
552 560 $ echo hack4 >> sub/large4
553 561 $ hg rm sub2/large6
554 562 $ echo new >> sub2/large8
555 563 $ hg add --large sub2/large8
556 564 # XXX we don't really want to report that we're reverting the standin;
557 565 # that's just an implementation detail. But I don't see an obvious fix. ;-(
558 566 $ hg revert sub
559 567 reverting .hglf/sub/large4 (glob)
560 568 reverting sub/normal4 (glob)
561 569 $ hg status
562 570 M normal3
563 571 A sub2/large8
564 572 R sub2/large6
565 573 ? sub/large4.orig
566 574 ? sub/normal4.orig
567 575 $ cat sub/normal4
568 576 normal4-modified
569 577 $ cat sub/large4
570 578 large4-modified
571 579 $ hg revert -a --no-backup
572 580 undeleting .hglf/sub2/large6 (glob)
573 581 forgetting .hglf/sub2/large8 (glob)
574 582 reverting normal3
575 583 $ hg status
576 584 ? sub/large4.orig
577 585 ? sub/normal4.orig
578 586 ? sub2/large8
579 587 $ cat normal3
580 588 normal3-modified
581 589 $ cat sub2/large6
582 590 large6-modified
583 591 $ rm sub/*.orig sub2/large8
584 592
585 593 revert some files to an older revision
586 594 $ hg revert --no-backup -r 8 sub2
587 595 reverting .hglf/sub2/large6 (glob)
588 596 $ cat sub2/large6
589 597 large6
590 598 $ hg revert --no-backup sub2
591 599 reverting .hglf/sub2/large6 (glob)
592 600 $ hg status
593 601
594 602 "verify --large" actually verifies largefiles
595 603
596 604 $ hg verify --large
597 605 checking changesets
598 606 checking manifests
599 607 crosschecking files in changesets and manifests
600 608 checking files
601 609 10 files, 10 changesets, 28 total revisions
602 610 searching 1 changesets for largefiles
603 611 verified existence of 3 revisions of 3 largefiles
604 612
605 613 Merging does not revert to old versions of largefiles (this has also
606 614 been very problematic).
607 615
608 616 $ cd ..
609 617 $ hg clone -r 7 e f
610 618 adding changesets
611 619 adding manifests
612 620 adding file changes
613 621 added 8 changesets with 24 changes to 10 files
614 622 updating to branch default
615 623 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
616 624 getting changed largefiles
617 625 3 largefiles updated, 0 removed
618 626 $ cd f
619 627 $ echo "large4-merge-test" > sub/large4
620 628 $ hg commit -m "Modify large4 to test merge"
621 629 Invoking status precommit hook
622 630 M sub/large4
623 631 $ hg pull ../e
624 632 pulling from ../e
625 633 searching for changes
626 634 adding changesets
627 635 adding manifests
628 636 adding file changes
629 637 added 2 changesets with 4 changes to 4 files (+1 heads)
630 638 (run 'hg heads' to see heads, 'hg merge' to merge)
631 639 $ hg merge
632 640 merging sub/large4
633 641 largefile sub/large4 has a merge conflict
634 642 keep (l)ocal or take (o)ther? l
635 643 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
636 644 (branch merge, don't forget to commit)
637 645 getting changed largefiles
638 646 1 largefiles updated, 0 removed
639 647 $ hg commit -m "Merge repos e and f"
640 648 Invoking status precommit hook
641 649 M normal3
642 650 M sub/normal4
643 651 M sub2/large6
644 652 $ cat normal3
645 653 normal3-modified
646 654 $ cat sub/normal4
647 655 normal4-modified
648 656 $ cat sub/large4
649 657 large4-merge-test
650 658 $ cat sub2/large6
651 659 large6-modified
652 660 $ cat sub2/large7
653 661 large7
654 662
655 663 Test status after merging with a branch that introduces a new largefile:
656 664
657 665 $ echo large > large
658 666 $ hg add --large large
659 667 $ hg commit -m 'add largefile'
660 668 Invoking status precommit hook
661 669 A large
662 670 $ hg update -q ".^"
663 671 $ echo change >> normal3
664 672 $ hg commit -m 'some change'
665 673 Invoking status precommit hook
666 674 M normal3
667 675 created new head
668 676 $ hg merge
669 677 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
670 678 (branch merge, don't forget to commit)
671 679 getting changed largefiles
672 680 1 largefiles updated, 0 removed
673 681 $ hg status
674 682 M large
675 683
676 684 Test that a normal file and a largefile with the same name and path cannot
677 685 coexist.
678 686
679 687 $ rm sub2/large7
680 688 $ echo "largeasnormal" > sub2/large7
681 689 $ hg add sub2/large7
682 690 sub2/large7 already a largefile
683 691
684 692 Test that transplanting a largefile change works correctly.
685 693
686 694 $ cd ..
687 695 $ hg clone -r 8 d g
688 696 adding changesets
689 697 adding manifests
690 698 adding file changes
691 699 added 9 changesets with 26 changes to 10 files
692 700 updating to branch default
693 701 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
694 702 getting changed largefiles
695 703 3 largefiles updated, 0 removed
696 704 $ cd g
697 705 $ hg transplant -s ../d 598410d3eb9a
698 706 searching for changes
699 707 searching for changes
700 708 adding changesets
701 709 adding manifests
702 710 adding file changes
703 711 added 1 changesets with 2 changes to 2 files
704 712 getting changed largefiles
705 713 1 largefiles updated, 0 removed
706 714 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
707 715 9:598410d3eb9a modify normal file largefile in repo d
708 716 8:a381d2c8c80e modify normal file and largefile in repo b
709 717 7:daea875e9014 add/edit more largefiles
710 718 6:4355d653f84f edit files yet again
711 719 5:9d5af5072dbd edit files again
712 720 4:74c02385b94c move files
713 721 3:9e8fbc4bce62 copy files
714 722 2:51a0ae4d5864 remove files
715 723 1:ce8896473775 edit files
716 724 0:30d30fe6a5be add files
717 725 $ cat normal3
718 726 normal3-modified
719 727 $ cat sub/normal4
720 728 normal4-modified
721 729 $ cat sub/large4
722 730 large4-modified
723 731 $ cat sub2/large6
724 732 large6-modified
725 733 $ cat sub2/large7
726 734 large7
727 735
728 736 Test that renaming a largefile results in correct output for status
729 737
730 738 $ hg rename sub/large4 large4-renamed
731 739 $ hg commit -m "test rename output"
732 740 Invoking status precommit hook
733 741 A large4-renamed
734 742 R sub/large4
735 743 $ cat large4-renamed
736 744 large4-modified
737 745 $ cd sub2
738 746 $ hg rename large6 large6-renamed
739 747 $ hg st
740 748 A sub2/large6-renamed
741 749 R sub2/large6
742 750 $ cd ../..
743 751
744 752 vanilla clients not locked out from largefiles servers on vanilla repos
745 753 $ mkdir r1
746 754 $ cd r1
747 755 $ hg init
748 756 $ echo c1 > f1
749 757 $ hg add f1
750 758 $ hg commit -m "m1"
751 759 Invoking status precommit hook
752 760 A f1
753 761 $ cd ..
754 762 $ hg serve -R r1 -d -p $HGPORT --pid-file hg.pid
755 763 $ cat hg.pid >> $DAEMON_PIDS
756 764 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT r2
757 765 requesting all changes
758 766 adding changesets
759 767 adding manifests
760 768 adding file changes
761 769 added 1 changesets with 1 changes to 1 files
762 770 updating to branch default
763 771 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
764 772
765 773 largefiles clients still work with vanilla servers
766 774 $ hg --config extensions.largefiles=! serve -R r1 -d -p $HGPORT1 --pid-file hg.pid
767 775 $ cat hg.pid >> $DAEMON_PIDS
768 776 $ hg clone http://localhost:$HGPORT1 r3
769 777 requesting all changes
770 778 adding changesets
771 779 adding manifests
772 780 adding file changes
773 781 added 1 changesets with 1 changes to 1 files
774 782 updating to branch default
775 783 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
776 784
777 785 vanilla clients locked out from largefiles http repos
778 786 $ mkdir r4
779 787 $ cd r4
780 788 $ hg init
781 789 $ echo c1 > f1
782 790 $ hg add --large f1
783 791 $ hg commit -m "m1"
784 792 Invoking status precommit hook
785 793 A f1
786 794 $ cd ..
787 795 $ hg serve -R r4 -d -p $HGPORT2 --pid-file hg.pid
788 796 $ cat hg.pid >> $DAEMON_PIDS
789 797 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT2 r5
790 798 abort: remote error:
791 799
792 800 This repository uses the largefiles extension.
793 801
794 802 Please enable it in your Mercurial config file.
795 803 [255]
796 804
797 805 used all HGPORTs, kill all daemons
798 806 $ "$TESTDIR/killdaemons.py"
799 807
800 808 vanilla clients locked out from largefiles ssh repos
801 809 $ hg --config extensions.largefiles=! clone -e "python $TESTDIR/dummyssh" ssh://user@dummy/r4 r5
802 810 abort: remote error:
803 811
804 812 This repository uses the largefiles extension.
805 813
806 814 Please enable it in your Mercurial config file.
807 815 [255]
808 816
809 817 largefiles clients refuse to push largefiles repos to vanilla servers
810 818 $ mkdir r6
811 819 $ cd r6
812 820 $ hg init
813 821 $ echo c1 > f1
814 822 $ hg add f1
815 823 $ hg commit -m "m1"
816 824 Invoking status precommit hook
817 825 A f1
818 826 $ cat >> .hg/hgrc <<!
819 827 > [web]
820 828 > push_ssl = false
821 829 > allow_push = *
822 830 > !
823 831 $ cd ..
824 832 $ hg clone r6 r7
825 833 updating to branch default
826 834 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
827 835 $ cd r7
828 836 $ echo c2 > f2
829 837 $ hg add --large f2
830 838 $ hg commit -m "m2"
831 839 Invoking status precommit hook
832 840 A f2
833 841 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p $HGPORT --pid-file ../hg.pid
834 842 $ cat ../hg.pid >> $DAEMON_PIDS
835 843 $ hg push http://localhost:$HGPORT
836 844 pushing to http://localhost:$HGPORT/
837 845 searching for changes
838 846 abort: http://localhost:$HGPORT/ does not appear to be a largefile store
839 847 [255]
840 848 $ cd ..
841 849
842 850 putlfile errors are shown (issue3123)
843 851 Corrupt the cached largefile in r7
844 852 $ echo corruption > $USERCACHE/4cdac4d8b084d0b599525cf732437fb337d422a8
845 853 $ hg init empty
846 854 $ hg serve -R empty -d -p $HGPORT1 --pid-file hg.pid \
847 855 > --config 'web.allow_push=*' --config web.push_ssl=False
848 856 $ cat hg.pid >> $DAEMON_PIDS
849 857 $ hg push -R r7 http://localhost:$HGPORT1
850 858 pushing to http://localhost:$HGPORT1/
851 859 searching for changes
852 860 remote: largefiles: failed to put 4cdac4d8b084d0b599525cf732437fb337d422a8 into store: largefile contents do not match hash
853 861 abort: remotestore: could not put $TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 to remote store http://localhost:$HGPORT1/
854 862 [255]
855 863 $ rm -rf empty
856 864
857 865 Clone a local repository owned by another user
858 866 We have to simulate that here by setting $HOME and removing write permissions
859 867 $ ORIGHOME="$HOME"
860 868 $ mkdir alice
861 869 $ HOME="`pwd`/alice"
862 870 $ cd alice
863 871 $ hg init pubrepo
864 872 $ cd pubrepo
865 873 $ dd if=/dev/urandom bs=1k count=11k > a-large-file 2> /dev/null
866 874 $ hg add --large a-large-file
867 875 $ hg commit -m "Add a large file"
868 876 Invoking status precommit hook
869 877 A a-large-file
870 878 $ cd ..
871 879 $ chmod -R a-w pubrepo
872 880 $ cd ..
873 881 $ mkdir bob
874 882 $ HOME="`pwd`/bob"
875 883 $ cd bob
876 884 $ hg clone --pull ../alice/pubrepo pubrepo
877 885 requesting all changes
878 886 adding changesets
879 887 adding manifests
880 888 adding file changes
881 889 added 1 changesets with 1 changes to 1 files
882 890 updating to branch default
883 891 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
884 892 getting changed largefiles
885 893 1 largefiles updated, 0 removed
886 894 $ cd ..
887 895 $ chmod -R u+w alice/pubrepo
888 896 $ HOME="$ORIGHOME"
889 897
890 898 Symlink to a large largefile should behave the same as a symlink to a normal file
891 899 $ hg init largesymlink
892 900 $ cd largesymlink
893 901 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
894 902 $ hg add --large largefile
895 903 $ hg commit -m "commit a large file"
896 904 Invoking status precommit hook
897 905 A largefile
898 906 $ ln -s largefile largelink
899 907 $ hg add largelink
900 908 $ hg commit -m "commit a large symlink"
901 909 Invoking status precommit hook
902 910 A largelink
903 911 $ rm -f largelink
904 912 $ hg up >/dev/null
905 913 $ test -f largelink
906 914 [1]
907 915 $ test -L largelink
908 916 [1]
909 917 $ rm -f largelink # make next part of the test independent of the previous
910 918 $ hg up -C >/dev/null
911 919 $ test -f largelink
912 920 $ test -L largelink
913 921 $ cd ..
914 922
915 923
General Comments 0
You need to be logged in to leave comments. Login now