##// END OF EJS Templates
largefiles: set the extension as enabled locally after a clone requiring it...
Matt Harbison -
r24029:e1dbe0b2 default
parent child Browse files
Show More
@@ -1,1347 +1,1355
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 '''Overridden Mercurial commands and functions for the largefiles extension'''
10 10
11 11 import os
12 12 import copy
13 13
14 14 from mercurial import hg, util, cmdutil, scmutil, match as match_, \
15 15 archival, pathutil, revset
16 16 from mercurial.i18n import _
17 17 from mercurial.node import hex
18 18
19 19 import lfutil
20 20 import lfcommands
21 21 import basestore
22 22
23 23 # -- Utility functions: commonly/repeatedly needed functionality ---------------
24 24
25 25 def composelargefilematcher(match, manifest):
26 26 '''create a matcher that matches only the largefiles in the original
27 27 matcher'''
28 28 m = copy.copy(match)
29 29 lfile = lambda f: lfutil.standin(f) in manifest
30 30 m._files = filter(lfile, m._files)
31 31 m._fmap = set(m._files)
32 32 m._always = False
33 33 origmatchfn = m.matchfn
34 34 m.matchfn = lambda f: lfile(f) and origmatchfn(f)
35 35 return m
36 36
37 37 def composenormalfilematcher(match, manifest, exclude=None):
38 38 excluded = set()
39 39 if exclude is not None:
40 40 excluded.update(exclude)
41 41
42 42 m = copy.copy(match)
43 43 notlfile = lambda f: not (lfutil.isstandin(f) or lfutil.standin(f) in
44 44 manifest or f in excluded)
45 45 m._files = filter(notlfile, m._files)
46 46 m._fmap = set(m._files)
47 47 m._always = False
48 48 origmatchfn = m.matchfn
49 49 m.matchfn = lambda f: notlfile(f) and origmatchfn(f)
50 50 return m
51 51
52 52 def installnormalfilesmatchfn(manifest):
53 53 '''installmatchfn with a matchfn that ignores all largefiles'''
54 54 def overridematch(ctx, pats=[], opts={}, globbed=False,
55 55 default='relpath'):
56 56 match = oldmatch(ctx, pats, opts, globbed, default)
57 57 return composenormalfilematcher(match, manifest)
58 58 oldmatch = installmatchfn(overridematch)
59 59
60 60 def installmatchfn(f):
61 61 '''monkey patch the scmutil module with a custom match function.
62 62 Warning: it is monkey patching the _module_ on runtime! Not thread safe!'''
63 63 oldmatch = scmutil.match
64 64 setattr(f, 'oldmatch', oldmatch)
65 65 scmutil.match = f
66 66 return oldmatch
67 67
68 68 def restorematchfn():
69 69 '''restores scmutil.match to what it was before installmatchfn
70 70 was called. no-op if scmutil.match is its original function.
71 71
72 72 Note that n calls to installmatchfn will require n calls to
73 73 restore the original matchfn.'''
74 74 scmutil.match = getattr(scmutil.match, 'oldmatch')
75 75
76 76 def installmatchandpatsfn(f):
77 77 oldmatchandpats = scmutil.matchandpats
78 78 setattr(f, 'oldmatchandpats', oldmatchandpats)
79 79 scmutil.matchandpats = f
80 80 return oldmatchandpats
81 81
82 82 def restorematchandpatsfn():
83 83 '''restores scmutil.matchandpats to what it was before
84 84 installmatchandpatsfn was called. No-op if scmutil.matchandpats
85 85 is its original function.
86 86
87 87 Note that n calls to installmatchandpatsfn will require n calls
88 88 to restore the original matchfn.'''
89 89 scmutil.matchandpats = getattr(scmutil.matchandpats, 'oldmatchandpats',
90 90 scmutil.matchandpats)
91 91
92 92 def addlargefiles(ui, repo, isaddremove, matcher, **opts):
93 93 large = opts.get('large')
94 94 lfsize = lfutil.getminsize(
95 95 ui, lfutil.islfilesrepo(repo), opts.get('lfsize'))
96 96
97 97 lfmatcher = None
98 98 if lfutil.islfilesrepo(repo):
99 99 lfpats = ui.configlist(lfutil.longname, 'patterns', default=[])
100 100 if lfpats:
101 101 lfmatcher = match_.match(repo.root, '', list(lfpats))
102 102
103 103 lfnames = []
104 104 m = copy.copy(matcher)
105 105 m.bad = lambda x, y: None
106 106 wctx = repo[None]
107 107 for f in repo.walk(m):
108 108 exact = m.exact(f)
109 109 lfile = lfutil.standin(f) in wctx
110 110 nfile = f in wctx
111 111 exists = lfile or nfile
112 112
113 113 # addremove in core gets fancy with the name, add doesn't
114 114 if isaddremove:
115 115 name = m.uipath(f)
116 116 else:
117 117 name = m.rel(f)
118 118
119 119 # Don't warn the user when they attempt to add a normal tracked file.
120 120 # The normal add code will do that for us.
121 121 if exact and exists:
122 122 if lfile:
123 123 ui.warn(_('%s already a largefile\n') % name)
124 124 continue
125 125
126 126 if (exact or not exists) and not lfutil.isstandin(f):
127 127 # In case the file was removed previously, but not committed
128 128 # (issue3507)
129 129 if not repo.wvfs.exists(f):
130 130 continue
131 131
132 132 abovemin = (lfsize and
133 133 repo.wvfs.lstat(f).st_size >= lfsize * 1024 * 1024)
134 134 if large or abovemin or (lfmatcher and lfmatcher(f)):
135 135 lfnames.append(f)
136 136 if ui.verbose or not exact:
137 137 ui.status(_('adding %s as a largefile\n') % name)
138 138
139 139 bad = []
140 140
141 141 # Need to lock, otherwise there could be a race condition between
142 142 # when standins are created and added to the repo.
143 143 wlock = repo.wlock()
144 144 try:
145 145 if not opts.get('dry_run'):
146 146 standins = []
147 147 lfdirstate = lfutil.openlfdirstate(ui, repo)
148 148 for f in lfnames:
149 149 standinname = lfutil.standin(f)
150 150 lfutil.writestandin(repo, standinname, hash='',
151 151 executable=lfutil.getexecutable(repo.wjoin(f)))
152 152 standins.append(standinname)
153 153 if lfdirstate[f] == 'r':
154 154 lfdirstate.normallookup(f)
155 155 else:
156 156 lfdirstate.add(f)
157 157 lfdirstate.write()
158 158 bad += [lfutil.splitstandin(f)
159 159 for f in repo[None].add(standins)
160 160 if f in m.files()]
161 161
162 162 added = [f for f in lfnames if f not in bad]
163 163 finally:
164 164 wlock.release()
165 165 return added, bad
166 166
167 167 def removelargefiles(ui, repo, isaddremove, matcher, **opts):
168 168 after = opts.get('after')
169 169 m = composelargefilematcher(matcher, repo[None].manifest())
170 170 try:
171 171 repo.lfstatus = True
172 172 s = repo.status(match=m, clean=not isaddremove)
173 173 finally:
174 174 repo.lfstatus = False
175 175 manifest = repo[None].manifest()
176 176 modified, added, deleted, clean = [[f for f in list
177 177 if lfutil.standin(f) in manifest]
178 178 for list in (s.modified, s.added,
179 179 s.deleted, s.clean)]
180 180
181 181 def warn(files, msg):
182 182 for f in files:
183 183 ui.warn(msg % m.rel(f))
184 184 return int(len(files) > 0)
185 185
186 186 result = 0
187 187
188 188 if after:
189 189 remove = deleted
190 190 result = warn(modified + added + clean,
191 191 _('not removing %s: file still exists\n'))
192 192 else:
193 193 remove = deleted + clean
194 194 result = warn(modified, _('not removing %s: file is modified (use -f'
195 195 ' to force removal)\n'))
196 196 result = warn(added, _('not removing %s: file has been marked for add'
197 197 ' (use forget to undo)\n')) or result
198 198
199 199 # Need to lock because standin files are deleted then removed from the
200 200 # repository and we could race in-between.
201 201 wlock = repo.wlock()
202 202 try:
203 203 lfdirstate = lfutil.openlfdirstate(ui, repo)
204 204 for f in sorted(remove):
205 205 if ui.verbose or not m.exact(f):
206 206 # addremove in core gets fancy with the name, remove doesn't
207 207 if isaddremove:
208 208 name = m.uipath(f)
209 209 else:
210 210 name = m.rel(f)
211 211 ui.status(_('removing %s\n') % name)
212 212
213 213 if not opts.get('dry_run'):
214 214 if not after:
215 215 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
216 216
217 217 if opts.get('dry_run'):
218 218 return result
219 219
220 220 remove = [lfutil.standin(f) for f in remove]
221 221 # If this is being called by addremove, let the original addremove
222 222 # function handle this.
223 223 if not isaddremove:
224 224 for f in remove:
225 225 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
226 226 repo[None].forget(remove)
227 227
228 228 for f in remove:
229 229 lfutil.synclfdirstate(repo, lfdirstate, lfutil.splitstandin(f),
230 230 False)
231 231
232 232 lfdirstate.write()
233 233 finally:
234 234 wlock.release()
235 235
236 236 return result
237 237
238 238 # For overriding mercurial.hgweb.webcommands so that largefiles will
239 239 # appear at their right place in the manifests.
240 240 def decodepath(orig, path):
241 241 return lfutil.splitstandin(path) or path
242 242
243 243 # -- Wrappers: modify existing commands --------------------------------
244 244
245 245 def overrideadd(orig, ui, repo, *pats, **opts):
246 246 if opts.get('normal') and opts.get('large'):
247 247 raise util.Abort(_('--normal cannot be used with --large'))
248 248 return orig(ui, repo, *pats, **opts)
249 249
250 250 def cmdutiladd(orig, ui, repo, matcher, prefix, explicitonly, **opts):
251 251 # The --normal flag short circuits this override
252 252 if opts.get('normal'):
253 253 return orig(ui, repo, matcher, prefix, explicitonly, **opts)
254 254
255 255 ladded, lbad = addlargefiles(ui, repo, False, matcher, **opts)
256 256 normalmatcher = composenormalfilematcher(matcher, repo[None].manifest(),
257 257 ladded)
258 258 bad = orig(ui, repo, normalmatcher, prefix, explicitonly, **opts)
259 259
260 260 bad.extend(f for f in lbad)
261 261 return bad
262 262
263 263 def cmdutilremove(orig, ui, repo, matcher, prefix, after, force, subrepos):
264 264 normalmatcher = composenormalfilematcher(matcher, repo[None].manifest())
265 265 result = orig(ui, repo, normalmatcher, prefix, after, force, subrepos)
266 266 return removelargefiles(ui, repo, False, matcher, after=after,
267 267 force=force) or result
268 268
269 269 def overridestatusfn(orig, repo, rev2, **opts):
270 270 try:
271 271 repo._repo.lfstatus = True
272 272 return orig(repo, rev2, **opts)
273 273 finally:
274 274 repo._repo.lfstatus = False
275 275
276 276 def overridestatus(orig, ui, repo, *pats, **opts):
277 277 try:
278 278 repo.lfstatus = True
279 279 return orig(ui, repo, *pats, **opts)
280 280 finally:
281 281 repo.lfstatus = False
282 282
283 283 def overridedirty(orig, repo, ignoreupdate=False):
284 284 try:
285 285 repo._repo.lfstatus = True
286 286 return orig(repo, ignoreupdate)
287 287 finally:
288 288 repo._repo.lfstatus = False
289 289
290 290 def overridelog(orig, ui, repo, *pats, **opts):
291 291 def overridematchandpats(ctx, pats=[], opts={}, globbed=False,
292 292 default='relpath'):
293 293 """Matcher that merges root directory with .hglf, suitable for log.
294 294 It is still possible to match .hglf directly.
295 295 For any listed files run log on the standin too.
296 296 matchfn tries both the given filename and with .hglf stripped.
297 297 """
298 298 matchandpats = oldmatchandpats(ctx, pats, opts, globbed, default)
299 299 m, p = copy.copy(matchandpats)
300 300
301 301 if m.always():
302 302 # We want to match everything anyway, so there's no benefit trying
303 303 # to add standins.
304 304 return matchandpats
305 305
306 306 pats = set(p)
307 307 # TODO: handling of patterns in both cases below
308 308 if m._cwd:
309 309 if os.path.isabs(m._cwd):
310 310 # TODO: handle largefile magic when invoked from other cwd
311 311 return matchandpats
312 312 back = (m._cwd.count('/') + 1) * '../'
313 313 pats.update(back + lfutil.standin(m._cwd + '/' + f) for f in p)
314 314 else:
315 315 pats.update(lfutil.standin(f) for f in p)
316 316
317 317 for i in range(0, len(m._files)):
318 318 standin = lfutil.standin(m._files[i])
319 319 # If the "standin" is a directory, append instead of replace to
320 320 # support naming a directory on the command line with only
321 321 # largefiles. The original directory is kept to support normal
322 322 # files.
323 323 if standin in repo[ctx.node()]:
324 324 m._files[i] = standin
325 325 elif m._files[i] not in repo[ctx.node()] \
326 326 and repo.wvfs.isdir(standin):
327 327 m._files.append(standin)
328 328 pats.add(standin)
329 329
330 330 m._fmap = set(m._files)
331 331 m._always = False
332 332 origmatchfn = m.matchfn
333 333 def lfmatchfn(f):
334 334 lf = lfutil.splitstandin(f)
335 335 if lf is not None and origmatchfn(lf):
336 336 return True
337 337 r = origmatchfn(f)
338 338 return r
339 339 m.matchfn = lfmatchfn
340 340
341 341 return m, pats
342 342
343 343 # For hg log --patch, the match object is used in two different senses:
344 344 # (1) to determine what revisions should be printed out, and
345 345 # (2) to determine what files to print out diffs for.
346 346 # The magic matchandpats override should be used for case (1) but not for
347 347 # case (2).
348 348 def overridemakelogfilematcher(repo, pats, opts):
349 349 pctx = repo[None]
350 350 match, pats = oldmatchandpats(pctx, pats, opts)
351 351 return lambda rev: match
352 352
353 353 oldmatchandpats = installmatchandpatsfn(overridematchandpats)
354 354 oldmakelogfilematcher = cmdutil._makenofollowlogfilematcher
355 355 setattr(cmdutil, '_makenofollowlogfilematcher', overridemakelogfilematcher)
356 356
357 357 try:
358 358 return orig(ui, repo, *pats, **opts)
359 359 finally:
360 360 restorematchandpatsfn()
361 361 setattr(cmdutil, '_makenofollowlogfilematcher', oldmakelogfilematcher)
362 362
363 363 def overrideverify(orig, ui, repo, *pats, **opts):
364 364 large = opts.pop('large', False)
365 365 all = opts.pop('lfa', False)
366 366 contents = opts.pop('lfc', False)
367 367
368 368 result = orig(ui, repo, *pats, **opts)
369 369 if large or all or contents:
370 370 result = result or lfcommands.verifylfiles(ui, repo, all, contents)
371 371 return result
372 372
373 373 def overridedebugstate(orig, ui, repo, *pats, **opts):
374 374 large = opts.pop('large', False)
375 375 if large:
376 376 class fakerepo(object):
377 377 dirstate = lfutil.openlfdirstate(ui, repo)
378 378 orig(ui, fakerepo, *pats, **opts)
379 379 else:
380 380 orig(ui, repo, *pats, **opts)
381 381
382 382 # Override needs to refresh standins so that update's normal merge
383 383 # will go through properly. Then the other update hook (overriding repo.update)
384 384 # will get the new files. Filemerge is also overridden so that the merge
385 385 # will merge standins correctly.
386 386 def overrideupdate(orig, ui, repo, *pats, **opts):
387 387 # Need to lock between the standins getting updated and their
388 388 # largefiles getting updated
389 389 wlock = repo.wlock()
390 390 try:
391 391 if opts['check']:
392 392 lfdirstate = lfutil.openlfdirstate(ui, repo)
393 393 unsure, s = lfdirstate.status(
394 394 match_.always(repo.root, repo.getcwd()),
395 395 [], False, False, False)
396 396
397 397 mod = len(s.modified) > 0
398 398 for lfile in unsure:
399 399 standin = lfutil.standin(lfile)
400 400 if repo['.'][standin].data().strip() != \
401 401 lfutil.hashfile(repo.wjoin(lfile)):
402 402 mod = True
403 403 else:
404 404 lfdirstate.normal(lfile)
405 405 lfdirstate.write()
406 406 if mod:
407 407 raise util.Abort(_('uncommitted changes'))
408 408 return orig(ui, repo, *pats, **opts)
409 409 finally:
410 410 wlock.release()
411 411
412 412 # Before starting the manifest merge, merge.updates will call
413 413 # _checkunknownfile to check if there are any files in the merged-in
414 414 # changeset that collide with unknown files in the working copy.
415 415 #
416 416 # The largefiles are seen as unknown, so this prevents us from merging
417 417 # in a file 'foo' if we already have a largefile with the same name.
418 418 #
419 419 # The overridden function filters the unknown files by removing any
420 420 # largefiles. This makes the merge proceed and we can then handle this
421 421 # case further in the overridden calculateupdates function below.
422 422 def overridecheckunknownfile(origfn, repo, wctx, mctx, f, f2=None):
423 423 if lfutil.standin(repo.dirstate.normalize(f)) in wctx:
424 424 return False
425 425 return origfn(repo, wctx, mctx, f, f2)
426 426
427 427 # The manifest merge handles conflicts on the manifest level. We want
428 428 # to handle changes in largefile-ness of files at this level too.
429 429 #
430 430 # The strategy is to run the original calculateupdates and then process
431 431 # the action list it outputs. There are two cases we need to deal with:
432 432 #
433 433 # 1. Normal file in p1, largefile in p2. Here the largefile is
434 434 # detected via its standin file, which will enter the working copy
435 435 # with a "get" action. It is not "merge" since the standin is all
436 436 # Mercurial is concerned with at this level -- the link to the
437 437 # existing normal file is not relevant here.
438 438 #
439 439 # 2. Largefile in p1, normal file in p2. Here we get a "merge" action
440 440 # since the largefile will be present in the working copy and
441 441 # different from the normal file in p2. Mercurial therefore
442 442 # triggers a merge action.
443 443 #
444 444 # In both cases, we prompt the user and emit new actions to either
445 445 # remove the standin (if the normal file was kept) or to remove the
446 446 # normal file and get the standin (if the largefile was kept). The
447 447 # default prompt answer is to use the largefile version since it was
448 448 # presumably changed on purpose.
449 449 #
450 450 # Finally, the merge.applyupdates function will then take care of
451 451 # writing the files into the working copy and lfcommands.updatelfiles
452 452 # will update the largefiles.
453 453 def overridecalculateupdates(origfn, repo, p1, p2, pas, branchmerge, force,
454 454 partial, acceptremote, followcopies):
455 455 overwrite = force and not branchmerge
456 456 actions, diverge, renamedelete = origfn(
457 457 repo, p1, p2, pas, branchmerge, force, partial, acceptremote,
458 458 followcopies)
459 459
460 460 if overwrite:
461 461 return actions, diverge, renamedelete
462 462
463 463 # Convert to dictionary with filename as key and action as value.
464 464 lfiles = set()
465 465 for f in actions:
466 466 splitstandin = f and lfutil.splitstandin(f)
467 467 if splitstandin in p1:
468 468 lfiles.add(splitstandin)
469 469 elif lfutil.standin(f) in p1:
470 470 lfiles.add(f)
471 471
472 472 for lfile in lfiles:
473 473 standin = lfutil.standin(lfile)
474 474 (lm, largs, lmsg) = actions.get(lfile, (None, None, None))
475 475 (sm, sargs, smsg) = actions.get(standin, (None, None, None))
476 476 if sm in ('g', 'dc') and lm != 'r':
477 477 # Case 1: normal file in the working copy, largefile in
478 478 # the second parent
479 479 usermsg = _('remote turned local normal file %s into a largefile\n'
480 480 'use (l)argefile or keep (n)ormal file?'
481 481 '$$ &Largefile $$ &Normal file') % lfile
482 482 if repo.ui.promptchoice(usermsg, 0) == 0: # pick remote largefile
483 483 actions[lfile] = ('r', None, 'replaced by standin')
484 484 actions[standin] = ('g', sargs, 'replaces standin')
485 485 else: # keep local normal file
486 486 actions[lfile] = ('k', None, 'replaces standin')
487 487 if branchmerge:
488 488 actions[standin] = ('k', None, 'replaced by non-standin')
489 489 else:
490 490 actions[standin] = ('r', None, 'replaced by non-standin')
491 491 elif lm in ('g', 'dc') and sm != 'r':
492 492 # Case 2: largefile in the working copy, normal file in
493 493 # the second parent
494 494 usermsg = _('remote turned local largefile %s into a normal file\n'
495 495 'keep (l)argefile or use (n)ormal file?'
496 496 '$$ &Largefile $$ &Normal file') % lfile
497 497 if repo.ui.promptchoice(usermsg, 0) == 0: # keep local largefile
498 498 if branchmerge:
499 499 # largefile can be restored from standin safely
500 500 actions[lfile] = ('k', None, 'replaced by standin')
501 501 actions[standin] = ('k', None, 'replaces standin')
502 502 else:
503 503 # "lfile" should be marked as "removed" without
504 504 # removal of itself
505 505 actions[lfile] = ('lfmr', None,
506 506 'forget non-standin largefile')
507 507
508 508 # linear-merge should treat this largefile as 're-added'
509 509 actions[standin] = ('a', None, 'keep standin')
510 510 else: # pick remote normal file
511 511 actions[lfile] = ('g', largs, 'replaces standin')
512 512 actions[standin] = ('r', None, 'replaced by non-standin')
513 513
514 514 return actions, diverge, renamedelete
515 515
516 516 def mergerecordupdates(orig, repo, actions, branchmerge):
517 517 if 'lfmr' in actions:
518 518 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
519 519 for lfile, args, msg in actions['lfmr']:
520 520 # this should be executed before 'orig', to execute 'remove'
521 521 # before all other actions
522 522 repo.dirstate.remove(lfile)
523 523 # make sure lfile doesn't get synclfdirstate'd as normal
524 524 lfdirstate.add(lfile)
525 525 lfdirstate.write()
526 526
527 527 return orig(repo, actions, branchmerge)
528 528
529 529
530 530 # Override filemerge to prompt the user about how they wish to merge
531 531 # largefiles. This will handle identical edits without prompting the user.
532 532 def overridefilemerge(origfn, repo, mynode, orig, fcd, fco, fca, labels=None):
533 533 if not lfutil.isstandin(orig):
534 534 return origfn(repo, mynode, orig, fcd, fco, fca, labels=labels)
535 535
536 536 ahash = fca.data().strip().lower()
537 537 dhash = fcd.data().strip().lower()
538 538 ohash = fco.data().strip().lower()
539 539 if (ohash != ahash and
540 540 ohash != dhash and
541 541 (dhash == ahash or
542 542 repo.ui.promptchoice(
543 543 _('largefile %s has a merge conflict\nancestor was %s\n'
544 544 'keep (l)ocal %s or\ntake (o)ther %s?'
545 545 '$$ &Local $$ &Other') %
546 546 (lfutil.splitstandin(orig), ahash, dhash, ohash),
547 547 0) == 1)):
548 548 repo.wwrite(fcd.path(), fco.data(), fco.flags())
549 549 return 0
550 550
551 551 # Copy first changes the matchers to match standins instead of
552 552 # largefiles. Then it overrides util.copyfile in that function it
553 553 # checks if the destination largefile already exists. It also keeps a
554 554 # list of copied files so that the largefiles can be copied and the
555 555 # dirstate updated.
556 556 def overridecopy(orig, ui, repo, pats, opts, rename=False):
557 557 # doesn't remove largefile on rename
558 558 if len(pats) < 2:
559 559 # this isn't legal, let the original function deal with it
560 560 return orig(ui, repo, pats, opts, rename)
561 561
562 562 # This could copy both lfiles and normal files in one command,
563 563 # but we don't want to do that. First replace their matcher to
564 564 # only match normal files and run it, then replace it to just
565 565 # match largefiles and run it again.
566 566 nonormalfiles = False
567 567 nolfiles = False
568 568 installnormalfilesmatchfn(repo[None].manifest())
569 569 try:
570 570 try:
571 571 result = orig(ui, repo, pats, opts, rename)
572 572 except util.Abort, e:
573 573 if str(e) != _('no files to copy'):
574 574 raise e
575 575 else:
576 576 nonormalfiles = True
577 577 result = 0
578 578 finally:
579 579 restorematchfn()
580 580
581 581 # The first rename can cause our current working directory to be removed.
582 582 # In that case there is nothing left to copy/rename so just quit.
583 583 try:
584 584 repo.getcwd()
585 585 except OSError:
586 586 return result
587 587
588 588 def makestandin(relpath):
589 589 path = pathutil.canonpath(repo.root, repo.getcwd(), relpath)
590 590 return os.path.join(repo.wjoin(lfutil.standin(path)))
591 591
592 592 fullpats = scmutil.expandpats(pats)
593 593 dest = fullpats[-1]
594 594
595 595 if os.path.isdir(dest):
596 596 if not os.path.isdir(makestandin(dest)):
597 597 os.makedirs(makestandin(dest))
598 598
599 599 try:
600 600 try:
601 601 # When we call orig below it creates the standins but we don't add
602 602 # them to the dir state until later so lock during that time.
603 603 wlock = repo.wlock()
604 604
605 605 manifest = repo[None].manifest()
606 606 def overridematch(ctx, pats=[], opts={}, globbed=False,
607 607 default='relpath'):
608 608 newpats = []
609 609 # The patterns were previously mangled to add the standin
610 610 # directory; we need to remove that now
611 611 for pat in pats:
612 612 if match_.patkind(pat) is None and lfutil.shortname in pat:
613 613 newpats.append(pat.replace(lfutil.shortname, ''))
614 614 else:
615 615 newpats.append(pat)
616 616 match = oldmatch(ctx, newpats, opts, globbed, default)
617 617 m = copy.copy(match)
618 618 lfile = lambda f: lfutil.standin(f) in manifest
619 619 m._files = [lfutil.standin(f) for f in m._files if lfile(f)]
620 620 m._fmap = set(m._files)
621 621 origmatchfn = m.matchfn
622 622 m.matchfn = lambda f: (lfutil.isstandin(f) and
623 623 (f in manifest) and
624 624 origmatchfn(lfutil.splitstandin(f)) or
625 625 None)
626 626 return m
627 627 oldmatch = installmatchfn(overridematch)
628 628 listpats = []
629 629 for pat in pats:
630 630 if match_.patkind(pat) is not None:
631 631 listpats.append(pat)
632 632 else:
633 633 listpats.append(makestandin(pat))
634 634
635 635 try:
636 636 origcopyfile = util.copyfile
637 637 copiedfiles = []
638 638 def overridecopyfile(src, dest):
639 639 if (lfutil.shortname in src and
640 640 dest.startswith(repo.wjoin(lfutil.shortname))):
641 641 destlfile = dest.replace(lfutil.shortname, '')
642 642 if not opts['force'] and os.path.exists(destlfile):
643 643 raise IOError('',
644 644 _('destination largefile already exists'))
645 645 copiedfiles.append((src, dest))
646 646 origcopyfile(src, dest)
647 647
648 648 util.copyfile = overridecopyfile
649 649 result += orig(ui, repo, listpats, opts, rename)
650 650 finally:
651 651 util.copyfile = origcopyfile
652 652
653 653 lfdirstate = lfutil.openlfdirstate(ui, repo)
654 654 for (src, dest) in copiedfiles:
655 655 if (lfutil.shortname in src and
656 656 dest.startswith(repo.wjoin(lfutil.shortname))):
657 657 srclfile = src.replace(repo.wjoin(lfutil.standin('')), '')
658 658 destlfile = dest.replace(repo.wjoin(lfutil.standin('')), '')
659 659 destlfiledir = os.path.dirname(repo.wjoin(destlfile)) or '.'
660 660 if not os.path.isdir(destlfiledir):
661 661 os.makedirs(destlfiledir)
662 662 if rename:
663 663 os.rename(repo.wjoin(srclfile), repo.wjoin(destlfile))
664 664
665 665 # The file is gone, but this deletes any empty parent
666 666 # directories as a side-effect.
667 667 util.unlinkpath(repo.wjoin(srclfile), True)
668 668 lfdirstate.remove(srclfile)
669 669 else:
670 670 util.copyfile(repo.wjoin(srclfile),
671 671 repo.wjoin(destlfile))
672 672
673 673 lfdirstate.add(destlfile)
674 674 lfdirstate.write()
675 675 except util.Abort, e:
676 676 if str(e) != _('no files to copy'):
677 677 raise e
678 678 else:
679 679 nolfiles = True
680 680 finally:
681 681 restorematchfn()
682 682 wlock.release()
683 683
684 684 if nolfiles and nonormalfiles:
685 685 raise util.Abort(_('no files to copy'))
686 686
687 687 return result
688 688
689 689 # When the user calls revert, we have to be careful to not revert any
690 690 # changes to other largefiles accidentally. This means we have to keep
691 691 # track of the largefiles that are being reverted so we only pull down
692 692 # the necessary largefiles.
693 693 #
694 694 # Standins are only updated (to match the hash of largefiles) before
695 695 # commits. Update the standins then run the original revert, changing
696 696 # the matcher to hit standins instead of largefiles. Based on the
697 697 # resulting standins update the largefiles.
698 698 def overriderevert(orig, ui, repo, *pats, **opts):
699 699 # Because we put the standins in a bad state (by updating them)
700 700 # and then return them to a correct state we need to lock to
701 701 # prevent others from changing them in their incorrect state.
702 702 wlock = repo.wlock()
703 703 try:
704 704 lfdirstate = lfutil.openlfdirstate(ui, repo)
705 705 s = lfutil.lfdirstatestatus(lfdirstate, repo)
706 706 lfdirstate.write()
707 707 for lfile in s.modified:
708 708 lfutil.updatestandin(repo, lfutil.standin(lfile))
709 709 for lfile in s.deleted:
710 710 if (os.path.exists(repo.wjoin(lfutil.standin(lfile)))):
711 711 os.unlink(repo.wjoin(lfutil.standin(lfile)))
712 712
713 713 oldstandins = lfutil.getstandinsstate(repo)
714 714
715 715 def overridematch(ctx, pats=[], opts={}, globbed=False,
716 716 default='relpath'):
717 717 match = oldmatch(ctx, pats, opts, globbed, default)
718 718 m = copy.copy(match)
719 719 def tostandin(f):
720 720 if lfutil.standin(f) in ctx:
721 721 return lfutil.standin(f)
722 722 elif lfutil.standin(f) in repo[None]:
723 723 return None
724 724 return f
725 725 m._files = [tostandin(f) for f in m._files]
726 726 m._files = [f for f in m._files if f is not None]
727 727 m._fmap = set(m._files)
728 728 origmatchfn = m.matchfn
729 729 def matchfn(f):
730 730 if lfutil.isstandin(f):
731 731 return (origmatchfn(lfutil.splitstandin(f)) and
732 732 (f in repo[None] or f in ctx))
733 733 return origmatchfn(f)
734 734 m.matchfn = matchfn
735 735 return m
736 736 oldmatch = installmatchfn(overridematch)
737 737 try:
738 738 orig(ui, repo, *pats, **opts)
739 739 finally:
740 740 restorematchfn()
741 741
742 742 newstandins = lfutil.getstandinsstate(repo)
743 743 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
744 744 # lfdirstate should be 'normallookup'-ed for updated files,
745 745 # because reverting doesn't touch dirstate for 'normal' files
746 746 # when target revision is explicitly specified: in such case,
747 747 # 'n' and valid timestamp in dirstate doesn't ensure 'clean'
748 748 # of target (standin) file.
749 749 lfcommands.updatelfiles(ui, repo, filelist, printmessage=False,
750 750 normallookup=True)
751 751
752 752 finally:
753 753 wlock.release()
754 754
755 755 # after pulling changesets, we need to take some extra care to get
756 756 # largefiles updated remotely
757 757 def overridepull(orig, ui, repo, source=None, **opts):
758 758 revsprepull = len(repo)
759 759 if not source:
760 760 source = 'default'
761 761 repo.lfpullsource = source
762 762 result = orig(ui, repo, source, **opts)
763 763 revspostpull = len(repo)
764 764 lfrevs = opts.get('lfrev', [])
765 765 if opts.get('all_largefiles'):
766 766 lfrevs.append('pulled()')
767 767 if lfrevs and revspostpull > revsprepull:
768 768 numcached = 0
769 769 repo.firstpulled = revsprepull # for pulled() revset expression
770 770 try:
771 771 for rev in scmutil.revrange(repo, lfrevs):
772 772 ui.note(_('pulling largefiles for revision %s\n') % rev)
773 773 (cached, missing) = lfcommands.cachelfiles(ui, repo, rev)
774 774 numcached += len(cached)
775 775 finally:
776 776 del repo.firstpulled
777 777 ui.status(_("%d largefiles cached\n") % numcached)
778 778 return result
779 779
780 780 def pulledrevsetsymbol(repo, subset, x):
781 781 """``pulled()``
782 782 Changesets that just has been pulled.
783 783
784 784 Only available with largefiles from pull --lfrev expressions.
785 785
786 786 .. container:: verbose
787 787
788 788 Some examples:
789 789
790 790 - pull largefiles for all new changesets::
791 791
792 792 hg pull -lfrev "pulled()"
793 793
794 794 - pull largefiles for all new branch heads::
795 795
796 796 hg pull -lfrev "head(pulled()) and not closed()"
797 797
798 798 """
799 799
800 800 try:
801 801 firstpulled = repo.firstpulled
802 802 except AttributeError:
803 803 raise util.Abort(_("pulled() only available in --lfrev"))
804 804 return revset.baseset([r for r in subset if r >= firstpulled])
805 805
806 806 def overrideclone(orig, ui, source, dest=None, **opts):
807 807 d = dest
808 808 if d is None:
809 809 d = hg.defaultdest(source)
810 810 if opts.get('all_largefiles') and not hg.islocal(d):
811 811 raise util.Abort(_(
812 812 '--all-largefiles is incompatible with non-local destination %s') %
813 813 d)
814 814
815 815 return orig(ui, source, dest, **opts)
816 816
817 817 def hgclone(orig, ui, opts, *args, **kwargs):
818 818 result = orig(ui, opts, *args, **kwargs)
819 819
820 820 if result is not None:
821 821 sourcerepo, destrepo = result
822 822 repo = destrepo.local()
823 823
824 # If largefiles is required for this repo, permanently enable it locally
825 if 'largefiles' in repo.requirements:
826 fp = repo.vfs('hgrc', 'a', text=True)
827 try:
828 fp.write('\n[extensions]\nlargefiles=\n')
829 finally:
830 fp.close()
831
824 832 # Caching is implicitly limited to 'rev' option, since the dest repo was
825 833 # truncated at that point. The user may expect a download count with
826 834 # this option, so attempt whether or not this is a largefile repo.
827 835 if opts.get('all_largefiles'):
828 836 success, missing = lfcommands.downloadlfiles(ui, repo, None)
829 837
830 838 if missing != 0:
831 839 return None
832 840
833 841 return result
834 842
835 843 def overriderebase(orig, ui, repo, **opts):
836 844 resuming = opts.get('continue')
837 845 repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
838 846 repo._lfstatuswriters.append(lambda *msg, **opts: None)
839 847 try:
840 848 return orig(ui, repo, **opts)
841 849 finally:
842 850 repo._lfstatuswriters.pop()
843 851 repo._lfcommithooks.pop()
844 852
845 853 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
846 854 prefix=None, mtime=None, subrepos=None):
847 855 # No need to lock because we are only reading history and
848 856 # largefile caches, neither of which are modified.
849 857 lfcommands.cachelfiles(repo.ui, repo, node)
850 858
851 859 if kind not in archival.archivers:
852 860 raise util.Abort(_("unknown archive type '%s'") % kind)
853 861
854 862 ctx = repo[node]
855 863
856 864 if kind == 'files':
857 865 if prefix:
858 866 raise util.Abort(
859 867 _('cannot give prefix when archiving to files'))
860 868 else:
861 869 prefix = archival.tidyprefix(dest, kind, prefix)
862 870
863 871 def write(name, mode, islink, getdata):
864 872 if matchfn and not matchfn(name):
865 873 return
866 874 data = getdata()
867 875 if decode:
868 876 data = repo.wwritedata(name, data)
869 877 archiver.addfile(prefix + name, mode, islink, data)
870 878
871 879 archiver = archival.archivers[kind](dest, mtime or ctx.date()[0])
872 880
873 881 if repo.ui.configbool("ui", "archivemeta", True):
874 882 def metadata():
875 883 base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
876 884 hex(repo.changelog.node(0)), hex(node), ctx.branch())
877 885
878 886 tags = ''.join('tag: %s\n' % t for t in ctx.tags()
879 887 if repo.tagtype(t) == 'global')
880 888 if not tags:
881 889 repo.ui.pushbuffer()
882 890 opts = {'template': '{latesttag}\n{latesttagdistance}',
883 891 'style': '', 'patch': None, 'git': None}
884 892 cmdutil.show_changeset(repo.ui, repo, opts).show(ctx)
885 893 ltags, dist = repo.ui.popbuffer().split('\n')
886 894 tags = ''.join('latesttag: %s\n' % t for t in ltags.split(':'))
887 895 tags += 'latesttagdistance: %s\n' % dist
888 896
889 897 return base + tags
890 898
891 899 write('.hg_archival.txt', 0644, False, metadata)
892 900
893 901 for f in ctx:
894 902 ff = ctx.flags(f)
895 903 getdata = ctx[f].data
896 904 if lfutil.isstandin(f):
897 905 path = lfutil.findfile(repo, getdata().strip())
898 906 if path is None:
899 907 raise util.Abort(
900 908 _('largefile %s not found in repo store or system cache')
901 909 % lfutil.splitstandin(f))
902 910 f = lfutil.splitstandin(f)
903 911
904 912 def getdatafn():
905 913 fd = None
906 914 try:
907 915 fd = open(path, 'rb')
908 916 return fd.read()
909 917 finally:
910 918 if fd:
911 919 fd.close()
912 920
913 921 getdata = getdatafn
914 922 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
915 923
916 924 if subrepos:
917 925 for subpath in sorted(ctx.substate):
918 926 sub = ctx.sub(subpath)
919 927 submatch = match_.narrowmatcher(subpath, matchfn)
920 928 sub.archive(archiver, prefix, submatch)
921 929
922 930 archiver.done()
923 931
924 932 def hgsubrepoarchive(orig, repo, archiver, prefix, match=None):
925 933 repo._get(repo._state + ('hg',))
926 934 rev = repo._state[1]
927 935 ctx = repo._repo[rev]
928 936
929 937 lfcommands.cachelfiles(repo.ui, repo._repo, ctx.node())
930 938
931 939 def write(name, mode, islink, getdata):
932 940 # At this point, the standin has been replaced with the largefile name,
933 941 # so the normal matcher works here without the lfutil variants.
934 942 if match and not match(f):
935 943 return
936 944 data = getdata()
937 945
938 946 archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
939 947
940 948 for f in ctx:
941 949 ff = ctx.flags(f)
942 950 getdata = ctx[f].data
943 951 if lfutil.isstandin(f):
944 952 path = lfutil.findfile(repo._repo, getdata().strip())
945 953 if path is None:
946 954 raise util.Abort(
947 955 _('largefile %s not found in repo store or system cache')
948 956 % lfutil.splitstandin(f))
949 957 f = lfutil.splitstandin(f)
950 958
951 959 def getdatafn():
952 960 fd = None
953 961 try:
954 962 fd = open(os.path.join(prefix, path), 'rb')
955 963 return fd.read()
956 964 finally:
957 965 if fd:
958 966 fd.close()
959 967
960 968 getdata = getdatafn
961 969
962 970 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
963 971
964 972 for subpath in sorted(ctx.substate):
965 973 sub = ctx.sub(subpath)
966 974 submatch = match_.narrowmatcher(subpath, match)
967 975 sub.archive(archiver, os.path.join(prefix, repo._path) + '/', submatch)
968 976
969 977 # If a largefile is modified, the change is not reflected in its
970 978 # standin until a commit. cmdutil.bailifchanged() raises an exception
971 979 # if the repo has uncommitted changes. Wrap it to also check if
972 980 # largefiles were changed. This is used by bisect, backout and fetch.
973 981 def overridebailifchanged(orig, repo):
974 982 orig(repo)
975 983 repo.lfstatus = True
976 984 s = repo.status()
977 985 repo.lfstatus = False
978 986 if s.modified or s.added or s.removed or s.deleted:
979 987 raise util.Abort(_('uncommitted changes'))
980 988
981 989 def cmdutilforget(orig, ui, repo, match, prefix, explicitonly):
982 990 normalmatcher = composenormalfilematcher(match, repo[None].manifest())
983 991 bad, forgot = orig(ui, repo, normalmatcher, prefix, explicitonly)
984 992 m = composelargefilematcher(match, repo[None].manifest())
985 993
986 994 try:
987 995 repo.lfstatus = True
988 996 s = repo.status(match=m, clean=True)
989 997 finally:
990 998 repo.lfstatus = False
991 999 forget = sorted(s.modified + s.added + s.deleted + s.clean)
992 1000 forget = [f for f in forget if lfutil.standin(f) in repo[None].manifest()]
993 1001
994 1002 for f in forget:
995 1003 if lfutil.standin(f) not in repo.dirstate and not \
996 1004 repo.wvfs.isdir(lfutil.standin(f)):
997 1005 ui.warn(_('not removing %s: file is already untracked\n')
998 1006 % m.rel(f))
999 1007 bad.append(f)
1000 1008
1001 1009 for f in forget:
1002 1010 if ui.verbose or not m.exact(f):
1003 1011 ui.status(_('removing %s\n') % m.rel(f))
1004 1012
1005 1013 # Need to lock because standin files are deleted then removed from the
1006 1014 # repository and we could race in-between.
1007 1015 wlock = repo.wlock()
1008 1016 try:
1009 1017 lfdirstate = lfutil.openlfdirstate(ui, repo)
1010 1018 for f in forget:
1011 1019 if lfdirstate[f] == 'a':
1012 1020 lfdirstate.drop(f)
1013 1021 else:
1014 1022 lfdirstate.remove(f)
1015 1023 lfdirstate.write()
1016 1024 standins = [lfutil.standin(f) for f in forget]
1017 1025 for f in standins:
1018 1026 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
1019 1027 rejected = repo[None].forget(standins)
1020 1028 finally:
1021 1029 wlock.release()
1022 1030
1023 1031 bad.extend(f for f in rejected if f in m.files())
1024 1032 forgot.extend(f for f in forget if f not in rejected)
1025 1033 return bad, forgot
1026 1034
1027 1035 def _getoutgoings(repo, other, missing, addfunc):
1028 1036 """get pairs of filename and largefile hash in outgoing revisions
1029 1037 in 'missing'.
1030 1038
1031 1039 largefiles already existing on 'other' repository are ignored.
1032 1040
1033 1041 'addfunc' is invoked with each unique pairs of filename and
1034 1042 largefile hash value.
1035 1043 """
1036 1044 knowns = set()
1037 1045 lfhashes = set()
1038 1046 def dedup(fn, lfhash):
1039 1047 k = (fn, lfhash)
1040 1048 if k not in knowns:
1041 1049 knowns.add(k)
1042 1050 lfhashes.add(lfhash)
1043 1051 lfutil.getlfilestoupload(repo, missing, dedup)
1044 1052 if lfhashes:
1045 1053 lfexists = basestore._openstore(repo, other).exists(lfhashes)
1046 1054 for fn, lfhash in knowns:
1047 1055 if not lfexists[lfhash]: # lfhash doesn't exist on "other"
1048 1056 addfunc(fn, lfhash)
1049 1057
1050 1058 def outgoinghook(ui, repo, other, opts, missing):
1051 1059 if opts.pop('large', None):
1052 1060 lfhashes = set()
1053 1061 if ui.debugflag:
1054 1062 toupload = {}
1055 1063 def addfunc(fn, lfhash):
1056 1064 if fn not in toupload:
1057 1065 toupload[fn] = []
1058 1066 toupload[fn].append(lfhash)
1059 1067 lfhashes.add(lfhash)
1060 1068 def showhashes(fn):
1061 1069 for lfhash in sorted(toupload[fn]):
1062 1070 ui.debug(' %s\n' % (lfhash))
1063 1071 else:
1064 1072 toupload = set()
1065 1073 def addfunc(fn, lfhash):
1066 1074 toupload.add(fn)
1067 1075 lfhashes.add(lfhash)
1068 1076 def showhashes(fn):
1069 1077 pass
1070 1078 _getoutgoings(repo, other, missing, addfunc)
1071 1079
1072 1080 if not toupload:
1073 1081 ui.status(_('largefiles: no files to upload\n'))
1074 1082 else:
1075 1083 ui.status(_('largefiles to upload (%d entities):\n')
1076 1084 % (len(lfhashes)))
1077 1085 for file in sorted(toupload):
1078 1086 ui.status(lfutil.splitstandin(file) + '\n')
1079 1087 showhashes(file)
1080 1088 ui.status('\n')
1081 1089
1082 1090 def summaryremotehook(ui, repo, opts, changes):
1083 1091 largeopt = opts.get('large', False)
1084 1092 if changes is None:
1085 1093 if largeopt:
1086 1094 return (False, True) # only outgoing check is needed
1087 1095 else:
1088 1096 return (False, False)
1089 1097 elif largeopt:
1090 1098 url, branch, peer, outgoing = changes[1]
1091 1099 if peer is None:
1092 1100 # i18n: column positioning for "hg summary"
1093 1101 ui.status(_('largefiles: (no remote repo)\n'))
1094 1102 return
1095 1103
1096 1104 toupload = set()
1097 1105 lfhashes = set()
1098 1106 def addfunc(fn, lfhash):
1099 1107 toupload.add(fn)
1100 1108 lfhashes.add(lfhash)
1101 1109 _getoutgoings(repo, peer, outgoing.missing, addfunc)
1102 1110
1103 1111 if not toupload:
1104 1112 # i18n: column positioning for "hg summary"
1105 1113 ui.status(_('largefiles: (no files to upload)\n'))
1106 1114 else:
1107 1115 # i18n: column positioning for "hg summary"
1108 1116 ui.status(_('largefiles: %d entities for %d files to upload\n')
1109 1117 % (len(lfhashes), len(toupload)))
1110 1118
1111 1119 def overridesummary(orig, ui, repo, *pats, **opts):
1112 1120 try:
1113 1121 repo.lfstatus = True
1114 1122 orig(ui, repo, *pats, **opts)
1115 1123 finally:
1116 1124 repo.lfstatus = False
1117 1125
1118 1126 def scmutiladdremove(orig, repo, matcher, prefix, opts={}, dry_run=None,
1119 1127 similarity=None):
1120 1128 if not lfutil.islfilesrepo(repo):
1121 1129 return orig(repo, matcher, prefix, opts, dry_run, similarity)
1122 1130 # Get the list of missing largefiles so we can remove them
1123 1131 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1124 1132 unsure, s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [],
1125 1133 False, False, False)
1126 1134
1127 1135 # Call into the normal remove code, but the removing of the standin, we want
1128 1136 # to have handled by original addremove. Monkey patching here makes sure
1129 1137 # we don't remove the standin in the largefiles code, preventing a very
1130 1138 # confused state later.
1131 1139 if s.deleted:
1132 1140 m = copy.copy(matcher)
1133 1141
1134 1142 # The m._files and m._map attributes are not changed to the deleted list
1135 1143 # because that affects the m.exact() test, which in turn governs whether
1136 1144 # or not the file name is printed, and how. Simply limit the original
1137 1145 # matches to those in the deleted status list.
1138 1146 matchfn = m.matchfn
1139 1147 m.matchfn = lambda f: f in s.deleted and matchfn(f)
1140 1148
1141 1149 removelargefiles(repo.ui, repo, True, m, **opts)
1142 1150 # Call into the normal add code, and any files that *should* be added as
1143 1151 # largefiles will be
1144 1152 added, bad = addlargefiles(repo.ui, repo, True, matcher, **opts)
1145 1153 # Now that we've handled largefiles, hand off to the original addremove
1146 1154 # function to take care of the rest. Make sure it doesn't do anything with
1147 1155 # largefiles by passing a matcher that will ignore them.
1148 1156 matcher = composenormalfilematcher(matcher, repo[None].manifest(), added)
1149 1157 return orig(repo, matcher, prefix, opts, dry_run, similarity)
1150 1158
1151 1159 # Calling purge with --all will cause the largefiles to be deleted.
1152 1160 # Override repo.status to prevent this from happening.
1153 1161 def overridepurge(orig, ui, repo, *dirs, **opts):
1154 1162 # XXX Monkey patching a repoview will not work. The assigned attribute will
1155 1163 # be set on the unfiltered repo, but we will only lookup attributes in the
1156 1164 # unfiltered repo if the lookup in the repoview object itself fails. As the
1157 1165 # monkey patched method exists on the repoview class the lookup will not
1158 1166 # fail. As a result, the original version will shadow the monkey patched
1159 1167 # one, defeating the monkey patch.
1160 1168 #
1161 1169 # As a work around we use an unfiltered repo here. We should do something
1162 1170 # cleaner instead.
1163 1171 repo = repo.unfiltered()
1164 1172 oldstatus = repo.status
1165 1173 def overridestatus(node1='.', node2=None, match=None, ignored=False,
1166 1174 clean=False, unknown=False, listsubrepos=False):
1167 1175 r = oldstatus(node1, node2, match, ignored, clean, unknown,
1168 1176 listsubrepos)
1169 1177 lfdirstate = lfutil.openlfdirstate(ui, repo)
1170 1178 unknown = [f for f in r.unknown if lfdirstate[f] == '?']
1171 1179 ignored = [f for f in r.ignored if lfdirstate[f] == '?']
1172 1180 return scmutil.status(r.modified, r.added, r.removed, r.deleted,
1173 1181 unknown, ignored, r.clean)
1174 1182 repo.status = overridestatus
1175 1183 orig(ui, repo, *dirs, **opts)
1176 1184 repo.status = oldstatus
1177 1185 def overriderollback(orig, ui, repo, **opts):
1178 1186 wlock = repo.wlock()
1179 1187 try:
1180 1188 before = repo.dirstate.parents()
1181 1189 orphans = set(f for f in repo.dirstate
1182 1190 if lfutil.isstandin(f) and repo.dirstate[f] != 'r')
1183 1191 result = orig(ui, repo, **opts)
1184 1192 after = repo.dirstate.parents()
1185 1193 if before == after:
1186 1194 return result # no need to restore standins
1187 1195
1188 1196 pctx = repo['.']
1189 1197 for f in repo.dirstate:
1190 1198 if lfutil.isstandin(f):
1191 1199 orphans.discard(f)
1192 1200 if repo.dirstate[f] == 'r':
1193 1201 repo.wvfs.unlinkpath(f, ignoremissing=True)
1194 1202 elif f in pctx:
1195 1203 fctx = pctx[f]
1196 1204 repo.wwrite(f, fctx.data(), fctx.flags())
1197 1205 else:
1198 1206 # content of standin is not so important in 'a',
1199 1207 # 'm' or 'n' (coming from the 2nd parent) cases
1200 1208 lfutil.writestandin(repo, f, '', False)
1201 1209 for standin in orphans:
1202 1210 repo.wvfs.unlinkpath(standin, ignoremissing=True)
1203 1211
1204 1212 lfdirstate = lfutil.openlfdirstate(ui, repo)
1205 1213 orphans = set(lfdirstate)
1206 1214 lfiles = lfutil.listlfiles(repo)
1207 1215 for file in lfiles:
1208 1216 lfutil.synclfdirstate(repo, lfdirstate, file, True)
1209 1217 orphans.discard(file)
1210 1218 for lfile in orphans:
1211 1219 lfdirstate.drop(lfile)
1212 1220 lfdirstate.write()
1213 1221 finally:
1214 1222 wlock.release()
1215 1223 return result
1216 1224
1217 1225 def overridetransplant(orig, ui, repo, *revs, **opts):
1218 1226 resuming = opts.get('continue')
1219 1227 repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
1220 1228 repo._lfstatuswriters.append(lambda *msg, **opts: None)
1221 1229 try:
1222 1230 result = orig(ui, repo, *revs, **opts)
1223 1231 finally:
1224 1232 repo._lfstatuswriters.pop()
1225 1233 repo._lfcommithooks.pop()
1226 1234 return result
1227 1235
1228 1236 def overridecat(orig, ui, repo, file1, *pats, **opts):
1229 1237 ctx = scmutil.revsingle(repo, opts.get('rev'))
1230 1238 err = 1
1231 1239 notbad = set()
1232 1240 m = scmutil.match(ctx, (file1,) + pats, opts)
1233 1241 origmatchfn = m.matchfn
1234 1242 def lfmatchfn(f):
1235 1243 if origmatchfn(f):
1236 1244 return True
1237 1245 lf = lfutil.splitstandin(f)
1238 1246 if lf is None:
1239 1247 return False
1240 1248 notbad.add(lf)
1241 1249 return origmatchfn(lf)
1242 1250 m.matchfn = lfmatchfn
1243 1251 origbadfn = m.bad
1244 1252 def lfbadfn(f, msg):
1245 1253 if not f in notbad:
1246 1254 origbadfn(f, msg)
1247 1255 m.bad = lfbadfn
1248 1256 for f in ctx.walk(m):
1249 1257 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1250 1258 pathname=f)
1251 1259 lf = lfutil.splitstandin(f)
1252 1260 if lf is None or origmatchfn(f):
1253 1261 # duplicating unreachable code from commands.cat
1254 1262 data = ctx[f].data()
1255 1263 if opts.get('decode'):
1256 1264 data = repo.wwritedata(f, data)
1257 1265 fp.write(data)
1258 1266 else:
1259 1267 hash = lfutil.readstandin(repo, lf, ctx.rev())
1260 1268 if not lfutil.inusercache(repo.ui, hash):
1261 1269 store = basestore._openstore(repo)
1262 1270 success, missing = store.get([(lf, hash)])
1263 1271 if len(success) != 1:
1264 1272 raise util.Abort(
1265 1273 _('largefile %s is not in cache and could not be '
1266 1274 'downloaded') % lf)
1267 1275 path = lfutil.usercachepath(repo.ui, hash)
1268 1276 fpin = open(path, "rb")
1269 1277 for chunk in util.filechunkiter(fpin, 128 * 1024):
1270 1278 fp.write(chunk)
1271 1279 fpin.close()
1272 1280 fp.close()
1273 1281 err = 0
1274 1282 return err
1275 1283
1276 1284 def mergeupdate(orig, repo, node, branchmerge, force, partial,
1277 1285 *args, **kwargs):
1278 1286 wlock = repo.wlock()
1279 1287 try:
1280 1288 # branch | | |
1281 1289 # merge | force | partial | action
1282 1290 # -------+-------+---------+--------------
1283 1291 # x | x | x | linear-merge
1284 1292 # o | x | x | branch-merge
1285 1293 # x | o | x | overwrite (as clean update)
1286 1294 # o | o | x | force-branch-merge (*1)
1287 1295 # x | x | o | (*)
1288 1296 # o | x | o | (*)
1289 1297 # x | o | o | overwrite (as revert)
1290 1298 # o | o | o | (*)
1291 1299 #
1292 1300 # (*) don't care
1293 1301 # (*1) deprecated, but used internally (e.g: "rebase --collapse")
1294 1302
1295 1303 linearmerge = not branchmerge and not force and not partial
1296 1304
1297 1305 if linearmerge or (branchmerge and force and not partial):
1298 1306 # update standins for linear-merge or force-branch-merge,
1299 1307 # because largefiles in the working directory may be modified
1300 1308 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1301 1309 unsure, s = lfdirstate.status(match_.always(repo.root,
1302 1310 repo.getcwd()),
1303 1311 [], False, False, False)
1304 1312 pctx = repo['.']
1305 1313 for lfile in unsure + s.modified:
1306 1314 lfileabs = repo.wvfs.join(lfile)
1307 1315 if not os.path.exists(lfileabs):
1308 1316 continue
1309 1317 lfhash = lfutil.hashrepofile(repo, lfile)
1310 1318 standin = lfutil.standin(lfile)
1311 1319 lfutil.writestandin(repo, standin, lfhash,
1312 1320 lfutil.getexecutable(lfileabs))
1313 1321 if (standin in pctx and
1314 1322 lfhash == lfutil.readstandin(repo, lfile, '.')):
1315 1323 lfdirstate.normal(lfile)
1316 1324 for lfile in s.added:
1317 1325 lfutil.updatestandin(repo, lfutil.standin(lfile))
1318 1326 lfdirstate.write()
1319 1327
1320 1328 if linearmerge:
1321 1329 # Only call updatelfiles on the standins that have changed
1322 1330 # to save time
1323 1331 oldstandins = lfutil.getstandinsstate(repo)
1324 1332
1325 1333 result = orig(repo, node, branchmerge, force, partial, *args, **kwargs)
1326 1334
1327 1335 filelist = None
1328 1336 if linearmerge:
1329 1337 newstandins = lfutil.getstandinsstate(repo)
1330 1338 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
1331 1339
1332 1340 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1333 1341 normallookup=partial, checked=linearmerge)
1334 1342
1335 1343 return result
1336 1344 finally:
1337 1345 wlock.release()
1338 1346
1339 1347 def scmutilmarktouched(orig, repo, files, *args, **kwargs):
1340 1348 result = orig(repo, files, *args, **kwargs)
1341 1349
1342 1350 filelist = [lfutil.splitstandin(f) for f in files if lfutil.isstandin(f)]
1343 1351 if filelist:
1344 1352 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1345 1353 printmessage=False, normallookup=True)
1346 1354
1347 1355 return result
@@ -1,1834 +1,1834
1 1 This file used to contains all largefile tests.
2 2 Do not add any new tests in this file as it his already far too long to run.
3 3
4 4 It contains all the testing of the basic concepts of large file in a single block.
5 5
6 6 $ USERCACHE="$TESTTMP/cache"; export USERCACHE
7 7 $ mkdir "${USERCACHE}"
8 8 $ cat >> $HGRCPATH <<EOF
9 9 > [extensions]
10 10 > largefiles=
11 11 > purge=
12 12 > rebase=
13 13 > transplant=
14 14 > [phases]
15 15 > publish=False
16 16 > [largefiles]
17 17 > minsize=2
18 18 > patterns=glob:**.dat
19 19 > usercache=${USERCACHE}
20 20 > [hooks]
21 21 > precommit=sh -c "echo \\"Invoking status precommit hook\\"; hg status"
22 22 > EOF
23 23
24 24 Create the repo with a couple of revisions of both large and normal
25 25 files.
26 26 Test status and dirstate of largefiles and that summary output is correct.
27 27
28 28 $ hg init a
29 29 $ cd a
30 30 $ mkdir sub
31 31 $ echo normal1 > normal1
32 32 $ echo normal2 > sub/normal2
33 33 $ echo large1 > large1
34 34 $ echo large2 > sub/large2
35 35 $ hg add normal1 sub/normal2
36 36 $ hg add --large large1 sub/large2
37 37 $ hg commit -m "add files"
38 38 Invoking status precommit hook
39 39 A large1
40 40 A normal1
41 41 A sub/large2
42 42 A sub/normal2
43 43 $ touch large1 sub/large2
44 44 $ sleep 1
45 45 $ hg st
46 46 $ hg debugstate --nodates
47 47 n 644 41 set .hglf/large1
48 48 n 644 41 set .hglf/sub/large2
49 49 n 644 8 set normal1
50 50 n 644 8 set sub/normal2
51 51 $ hg debugstate --large --nodates
52 52 n 644 7 set large1
53 53 n 644 7 set sub/large2
54 54 $ echo normal11 > normal1
55 55 $ echo normal22 > sub/normal2
56 56 $ echo large11 > large1
57 57 $ echo large22 > sub/large2
58 58 $ hg commit -m "edit files"
59 59 Invoking status precommit hook
60 60 M large1
61 61 M normal1
62 62 M sub/large2
63 63 M sub/normal2
64 64 $ hg sum --large
65 65 parent: 1:ce8896473775 tip
66 66 edit files
67 67 branch: default
68 68 commit: (clean)
69 69 update: (current)
70 70 largefiles: (no remote repo)
71 71
72 72 Commit preserved largefile contents.
73 73
74 74 $ cat normal1
75 75 normal11
76 76 $ cat large1
77 77 large11
78 78 $ cat sub/normal2
79 79 normal22
80 80 $ cat sub/large2
81 81 large22
82 82
83 83 Test status, subdir and unknown files
84 84
85 85 $ echo unknown > sub/unknown
86 86 $ hg st --all
87 87 ? sub/unknown
88 88 C large1
89 89 C normal1
90 90 C sub/large2
91 91 C sub/normal2
92 92 $ hg st --all sub
93 93 ? sub/unknown
94 94 C sub/large2
95 95 C sub/normal2
96 96 $ rm sub/unknown
97 97
98 98 Test messages and exit codes for remove warning cases
99 99
100 100 $ hg remove -A large1
101 101 not removing large1: file still exists
102 102 [1]
103 103 $ echo 'modified' > large1
104 104 $ hg remove large1
105 105 not removing large1: file is modified (use -f to force removal)
106 106 [1]
107 107 $ echo 'new' > normalnew
108 108 $ hg add normalnew
109 109 $ echo 'new' > largenew
110 110 $ hg add --large normalnew
111 111 normalnew already tracked!
112 112 $ hg remove normalnew largenew
113 113 not removing largenew: file is untracked
114 114 not removing normalnew: file has been marked for add (use forget to undo)
115 115 [1]
116 116 $ rm normalnew largenew
117 117 $ hg up -Cq
118 118
119 119 Remove both largefiles and normal files.
120 120
121 121 $ hg remove normal1 large1
122 122 $ hg status large1
123 123 R large1
124 124 $ hg commit -m "remove files"
125 125 Invoking status precommit hook
126 126 R large1
127 127 R normal1
128 128 $ ls
129 129 sub
130 130 $ echo "testlargefile" > large1-test
131 131 $ hg add --large large1-test
132 132 $ hg st
133 133 A large1-test
134 134 $ hg rm large1-test
135 135 not removing large1-test: file has been marked for add (use forget to undo)
136 136 [1]
137 137 $ hg st
138 138 A large1-test
139 139 $ hg forget large1-test
140 140 $ hg st
141 141 ? large1-test
142 142 $ hg remove large1-test
143 143 not removing large1-test: file is untracked
144 144 [1]
145 145 $ hg forget large1-test
146 146 not removing large1-test: file is already untracked
147 147 [1]
148 148 $ rm large1-test
149 149
150 150 Copy both largefiles and normal files (testing that status output is correct).
151 151
152 152 $ hg cp sub/normal2 normal1
153 153 $ hg cp sub/large2 large1
154 154 $ hg commit -m "copy files"
155 155 Invoking status precommit hook
156 156 A large1
157 157 A normal1
158 158 $ cat normal1
159 159 normal22
160 160 $ cat large1
161 161 large22
162 162
163 163 Test moving largefiles and verify that normal files are also unaffected.
164 164
165 165 $ hg mv normal1 normal3
166 166 $ hg mv large1 large3
167 167 $ hg mv sub/normal2 sub/normal4
168 168 $ hg mv sub/large2 sub/large4
169 169 $ hg commit -m "move files"
170 170 Invoking status precommit hook
171 171 A large3
172 172 A normal3
173 173 A sub/large4
174 174 A sub/normal4
175 175 R large1
176 176 R normal1
177 177 R sub/large2
178 178 R sub/normal2
179 179 $ cat normal3
180 180 normal22
181 181 $ cat large3
182 182 large22
183 183 $ cat sub/normal4
184 184 normal22
185 185 $ cat sub/large4
186 186 large22
187 187
188 188
189 189 #if serve
190 190 Test display of largefiles in hgweb
191 191
192 192 $ hg serve -d -p $HGPORT --pid-file ../hg.pid
193 193 $ cat ../hg.pid >> $DAEMON_PIDS
194 194 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/?style=raw'
195 195 200 Script output follows
196 196
197 197
198 198 drwxr-xr-x sub
199 199 -rw-r--r-- 41 large3
200 200 -rw-r--r-- 9 normal3
201 201
202 202
203 203 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/sub/?style=raw'
204 204 200 Script output follows
205 205
206 206
207 207 -rw-r--r-- 41 large4
208 208 -rw-r--r-- 9 normal4
209 209
210 210
211 211 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
212 212 #endif
213 213
214 214 Test archiving the various revisions. These hit corner cases known with
215 215 archiving.
216 216
217 217 $ hg archive -r 0 ../archive0
218 218 $ hg archive -r 1 ../archive1
219 219 $ hg archive -r 2 ../archive2
220 220 $ hg archive -r 3 ../archive3
221 221 $ hg archive -r 4 ../archive4
222 222 $ cd ../archive0
223 223 $ cat normal1
224 224 normal1
225 225 $ cat large1
226 226 large1
227 227 $ cat sub/normal2
228 228 normal2
229 229 $ cat sub/large2
230 230 large2
231 231 $ cd ../archive1
232 232 $ cat normal1
233 233 normal11
234 234 $ cat large1
235 235 large11
236 236 $ cat sub/normal2
237 237 normal22
238 238 $ cat sub/large2
239 239 large22
240 240 $ cd ../archive2
241 241 $ ls
242 242 sub
243 243 $ cat sub/normal2
244 244 normal22
245 245 $ cat sub/large2
246 246 large22
247 247 $ cd ../archive3
248 248 $ cat normal1
249 249 normal22
250 250 $ cat large1
251 251 large22
252 252 $ cat sub/normal2
253 253 normal22
254 254 $ cat sub/large2
255 255 large22
256 256 $ cd ../archive4
257 257 $ cat normal3
258 258 normal22
259 259 $ cat large3
260 260 large22
261 261 $ cat sub/normal4
262 262 normal22
263 263 $ cat sub/large4
264 264 large22
265 265
266 266 Commit corner case: specify files to commit.
267 267
268 268 $ cd ../a
269 269 $ echo normal3 > normal3
270 270 $ echo large3 > large3
271 271 $ echo normal4 > sub/normal4
272 272 $ echo large4 > sub/large4
273 273 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
274 274 Invoking status precommit hook
275 275 M large3
276 276 M normal3
277 277 M sub/large4
278 278 M sub/normal4
279 279 $ cat normal3
280 280 normal3
281 281 $ cat large3
282 282 large3
283 283 $ cat sub/normal4
284 284 normal4
285 285 $ cat sub/large4
286 286 large4
287 287
288 288 One more commit corner case: commit from a subdirectory.
289 289
290 290 $ cd ../a
291 291 $ echo normal33 > normal3
292 292 $ echo large33 > large3
293 293 $ echo normal44 > sub/normal4
294 294 $ echo large44 > sub/large4
295 295 $ cd sub
296 296 $ hg commit -m "edit files yet again"
297 297 Invoking status precommit hook
298 298 M large3
299 299 M normal3
300 300 M sub/large4
301 301 M sub/normal4
302 302 $ cat ../normal3
303 303 normal33
304 304 $ cat ../large3
305 305 large33
306 306 $ cat normal4
307 307 normal44
308 308 $ cat large4
309 309 large44
310 310
311 311 Committing standins is not allowed.
312 312
313 313 $ cd ..
314 314 $ echo large3 > large3
315 315 $ hg commit .hglf/large3 -m "try to commit standin"
316 316 abort: file ".hglf/large3" is a largefile standin
317 317 (commit the largefile itself instead)
318 318 [255]
319 319
320 320 Corner cases for adding largefiles.
321 321
322 322 $ echo large5 > large5
323 323 $ hg add --large large5
324 324 $ hg add --large large5
325 325 large5 already a largefile
326 326 $ mkdir sub2
327 327 $ echo large6 > sub2/large6
328 328 $ echo large7 > sub2/large7
329 329 $ hg add --large sub2
330 330 adding sub2/large6 as a largefile (glob)
331 331 adding sub2/large7 as a largefile (glob)
332 332 $ hg st
333 333 M large3
334 334 A large5
335 335 A sub2/large6
336 336 A sub2/large7
337 337
338 338 Committing directories containing only largefiles.
339 339
340 340 $ mkdir -p z/y/x/m
341 341 $ touch z/y/x/m/large1
342 342 $ touch z/y/x/large2
343 343 $ hg add --large z/y/x/m/large1 z/y/x/large2
344 344 $ hg commit -m "Subdir with directory only containing largefiles" z
345 345 Invoking status precommit hook
346 346 M large3
347 347 A large5
348 348 A sub2/large6
349 349 A sub2/large7
350 350 A z/y/x/large2
351 351 A z/y/x/m/large1
352 352
353 353 (and a bit of log testing)
354 354
355 355 $ hg log -T '{rev}\n' z/y/x/m/large1
356 356 7
357 357 $ hg log -T '{rev}\n' z/y/x/m # with only a largefile
358 358 7
359 359
360 360 $ hg rollback --quiet
361 361 $ touch z/y/x/m/normal
362 362 $ hg add z/y/x/m/normal
363 363 $ hg commit -m "Subdir with mixed contents" z
364 364 Invoking status precommit hook
365 365 M large3
366 366 A large5
367 367 A sub2/large6
368 368 A sub2/large7
369 369 A z/y/x/large2
370 370 A z/y/x/m/large1
371 371 A z/y/x/m/normal
372 372 $ hg st
373 373 M large3
374 374 A large5
375 375 A sub2/large6
376 376 A sub2/large7
377 377 $ hg rollback --quiet
378 378 $ hg revert z/y/x/large2 z/y/x/m/large1
379 379 $ rm z/y/x/large2 z/y/x/m/large1
380 380 $ hg commit -m "Subdir with normal contents" z
381 381 Invoking status precommit hook
382 382 M large3
383 383 A large5
384 384 A sub2/large6
385 385 A sub2/large7
386 386 A z/y/x/m/normal
387 387 $ hg st
388 388 M large3
389 389 A large5
390 390 A sub2/large6
391 391 A sub2/large7
392 392 $ hg rollback --quiet
393 393 $ hg revert --quiet z
394 394 $ hg commit -m "Empty subdir" z
395 395 abort: z: no match under directory!
396 396 [255]
397 397 $ rm -rf z
398 398 $ hg ci -m "standin" .hglf
399 399 abort: file ".hglf" is a largefile standin
400 400 (commit the largefile itself instead)
401 401 [255]
402 402
403 403 Test "hg status" with combination of 'file pattern' and 'directory
404 404 pattern' for largefiles:
405 405
406 406 $ hg status sub2/large6 sub2
407 407 A sub2/large6
408 408 A sub2/large7
409 409
410 410 Config settings (pattern **.dat, minsize 2 MB) are respected.
411 411
412 412 $ echo testdata > test.dat
413 413 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
414 414 $ hg add
415 415 adding reallylarge as a largefile
416 416 adding test.dat as a largefile
417 417
418 418 Test that minsize and --lfsize handle float values;
419 419 also tests that --lfsize overrides largefiles.minsize.
420 420 (0.250 MB = 256 kB = 262144 B)
421 421
422 422 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
423 423 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
424 424 $ hg --config largefiles.minsize=.25 add
425 425 adding ratherlarge as a largefile
426 426 adding medium
427 427 $ hg forget medium
428 428 $ hg --config largefiles.minsize=.25 add --lfsize=.125
429 429 adding medium as a largefile
430 430 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
431 431 $ hg --config largefiles.minsize=.25 add --lfsize=.125
432 432 adding notlarge
433 433 $ hg forget notlarge
434 434
435 435 Test forget on largefiles.
436 436
437 437 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
438 438 $ hg commit -m "add/edit more largefiles"
439 439 Invoking status precommit hook
440 440 A sub2/large6
441 441 A sub2/large7
442 442 R large3
443 443 ? large5
444 444 ? medium
445 445 ? notlarge
446 446 ? ratherlarge
447 447 ? reallylarge
448 448 ? test.dat
449 449 $ hg st
450 450 ? large3
451 451 ? large5
452 452 ? medium
453 453 ? notlarge
454 454 ? ratherlarge
455 455 ? reallylarge
456 456 ? test.dat
457 457
458 458 Purge with largefiles: verify that largefiles are still in the working
459 459 dir after a purge.
460 460
461 461 $ hg purge --all
462 462 $ cat sub/large4
463 463 large44
464 464 $ cat sub2/large6
465 465 large6
466 466 $ cat sub2/large7
467 467 large7
468 468
469 469 Test addremove: verify that files that should be added as largefiles are added as
470 470 such and that already-existing largefiles are not added as normal files by
471 471 accident.
472 472
473 473 $ rm normal3
474 474 $ rm sub/large4
475 475 $ echo "testing addremove with patterns" > testaddremove.dat
476 476 $ echo "normaladdremove" > normaladdremove
477 477 $ hg addremove
478 478 removing sub/large4
479 479 adding testaddremove.dat as a largefile
480 480 removing normal3
481 481 adding normaladdremove
482 482
483 483 Test addremove with -R
484 484
485 485 $ hg up -C
486 486 getting changed largefiles
487 487 1 largefiles updated, 0 removed
488 488 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
489 489 $ rm normal3
490 490 $ rm sub/large4
491 491 $ echo "testing addremove with patterns" > testaddremove.dat
492 492 $ echo "normaladdremove" > normaladdremove
493 493 $ cd ..
494 494 $ hg -R a -v addremove
495 495 removing sub/large4
496 496 adding testaddremove.dat as a largefile
497 497 removing normal3
498 498 adding normaladdremove
499 499 $ cd a
500 500
501 501 Test 3364
502 502 $ hg clone . ../addrm
503 503 updating to branch default
504 504 getting changed largefiles
505 505 3 largefiles updated, 0 removed
506 506 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
507 507 $ cd ../addrm
508 508 $ cat >> .hg/hgrc <<EOF
509 509 > [hooks]
510 510 > post-commit.stat=sh -c "echo \\"Invoking status postcommit hook\\"; hg status -A"
511 511 > EOF
512 512 $ touch foo
513 513 $ hg add --large foo
514 514 $ hg ci -m "add foo"
515 515 Invoking status precommit hook
516 516 A foo
517 517 Invoking status postcommit hook
518 518 C foo
519 519 C normal3
520 520 C sub/large4
521 521 C sub/normal4
522 522 C sub2/large6
523 523 C sub2/large7
524 524 $ rm foo
525 525 $ hg st
526 526 ! foo
527 527 hmm.. no precommit invoked, but there is a postcommit??
528 528 $ hg ci -m "will not checkin"
529 529 nothing changed
530 530 Invoking status postcommit hook
531 531 ! foo
532 532 C normal3
533 533 C sub/large4
534 534 C sub/normal4
535 535 C sub2/large6
536 536 C sub2/large7
537 537 [1]
538 538 $ hg addremove
539 539 removing foo
540 540 $ hg st
541 541 R foo
542 542 $ hg ci -m "used to say nothing changed"
543 543 Invoking status precommit hook
544 544 R foo
545 545 Invoking status postcommit hook
546 546 C normal3
547 547 C sub/large4
548 548 C sub/normal4
549 549 C sub2/large6
550 550 C sub2/large7
551 551 $ hg st
552 552
553 553 Test 3507 (both normal files and largefiles were a problem)
554 554
555 555 $ touch normal
556 556 $ touch large
557 557 $ hg add normal
558 558 $ hg add --large large
559 559 $ hg ci -m "added"
560 560 Invoking status precommit hook
561 561 A large
562 562 A normal
563 563 Invoking status postcommit hook
564 564 C large
565 565 C normal
566 566 C normal3
567 567 C sub/large4
568 568 C sub/normal4
569 569 C sub2/large6
570 570 C sub2/large7
571 571 $ hg remove normal
572 572 $ hg addremove --traceback
573 573 $ hg ci -m "addremoved normal"
574 574 Invoking status precommit hook
575 575 R normal
576 576 Invoking status postcommit hook
577 577 C large
578 578 C normal3
579 579 C sub/large4
580 580 C sub/normal4
581 581 C sub2/large6
582 582 C sub2/large7
583 583 $ hg up -C '.^'
584 584 getting changed largefiles
585 585 0 largefiles updated, 0 removed
586 586 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
587 587 $ hg remove large
588 588 $ hg addremove --traceback
589 589 $ hg ci -m "removed large"
590 590 Invoking status precommit hook
591 591 R large
592 592 created new head
593 593 Invoking status postcommit hook
594 594 C normal
595 595 C normal3
596 596 C sub/large4
597 597 C sub/normal4
598 598 C sub2/large6
599 599 C sub2/large7
600 600
601 601 Test commit -A (issue3542)
602 602 $ echo large8 > large8
603 603 $ hg add --large large8
604 604 $ hg ci -Am 'this used to add large8 as normal and commit both'
605 605 Invoking status precommit hook
606 606 A large8
607 607 Invoking status postcommit hook
608 608 C large8
609 609 C normal
610 610 C normal3
611 611 C sub/large4
612 612 C sub/normal4
613 613 C sub2/large6
614 614 C sub2/large7
615 615 $ rm large8
616 616 $ hg ci -Am 'this used to not notice the rm'
617 617 removing large8
618 618 Invoking status precommit hook
619 619 R large8
620 620 Invoking status postcommit hook
621 621 C normal
622 622 C normal3
623 623 C sub/large4
624 624 C sub/normal4
625 625 C sub2/large6
626 626 C sub2/large7
627 627
628 628 Test that a standin can't be added as a large file
629 629
630 630 $ touch large
631 631 $ hg add --large large
632 632 $ hg ci -m "add"
633 633 Invoking status precommit hook
634 634 A large
635 635 Invoking status postcommit hook
636 636 C large
637 637 C normal
638 638 C normal3
639 639 C sub/large4
640 640 C sub/normal4
641 641 C sub2/large6
642 642 C sub2/large7
643 643 $ hg remove large
644 644 $ touch large
645 645 $ hg addremove --config largefiles.patterns=**large --traceback
646 646 adding large as a largefile
647 647
648 648 Test that outgoing --large works (with revsets too)
649 649 $ hg outgoing --rev '.^' --large
650 650 comparing with $TESTTMP/a (glob)
651 651 searching for changes
652 652 changeset: 8:c02fd3b77ec4
653 653 user: test
654 654 date: Thu Jan 01 00:00:00 1970 +0000
655 655 summary: add foo
656 656
657 657 changeset: 9:289dd08c9bbb
658 658 user: test
659 659 date: Thu Jan 01 00:00:00 1970 +0000
660 660 summary: used to say nothing changed
661 661
662 662 changeset: 10:34f23ac6ac12
663 663 user: test
664 664 date: Thu Jan 01 00:00:00 1970 +0000
665 665 summary: added
666 666
667 667 changeset: 12:710c1b2f523c
668 668 parent: 10:34f23ac6ac12
669 669 user: test
670 670 date: Thu Jan 01 00:00:00 1970 +0000
671 671 summary: removed large
672 672
673 673 changeset: 13:0a3e75774479
674 674 user: test
675 675 date: Thu Jan 01 00:00:00 1970 +0000
676 676 summary: this used to add large8 as normal and commit both
677 677
678 678 changeset: 14:84f3d378175c
679 679 user: test
680 680 date: Thu Jan 01 00:00:00 1970 +0000
681 681 summary: this used to not notice the rm
682 682
683 683 largefiles to upload (1 entities):
684 684 large8
685 685
686 686 $ cd ../a
687 687
688 688 Clone a largefiles repo.
689 689
690 690 $ hg clone . ../b
691 691 updating to branch default
692 692 getting changed largefiles
693 693 3 largefiles updated, 0 removed
694 694 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
695 695 $ cd ../b
696 696 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
697 697 7:daea875e9014 add/edit more largefiles
698 698 6:4355d653f84f edit files yet again
699 699 5:9d5af5072dbd edit files again
700 700 4:74c02385b94c move files
701 701 3:9e8fbc4bce62 copy files
702 702 2:51a0ae4d5864 remove files
703 703 1:ce8896473775 edit files
704 704 0:30d30fe6a5be add files
705 705 $ cat normal3
706 706 normal33
707 707
708 708 Test graph log
709 709
710 710 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n'
711 711 @ 7:daea875e9014 add/edit more largefiles
712 712 |
713 713 o 6:4355d653f84f edit files yet again
714 714 |
715 715 o 5:9d5af5072dbd edit files again
716 716 |
717 717 o 4:74c02385b94c move files
718 718 |
719 719 o 3:9e8fbc4bce62 copy files
720 720 |
721 721 o 2:51a0ae4d5864 remove files
722 722 |
723 723 o 1:ce8896473775 edit files
724 724 |
725 725 o 0:30d30fe6a5be add files
726 726
727 727
728 728 Test log with --patch
729 729
730 730 $ hg log --patch -r 6::7
731 731 changeset: 6:4355d653f84f
732 732 user: test
733 733 date: Thu Jan 01 00:00:00 1970 +0000
734 734 summary: edit files yet again
735 735
736 736 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/large3
737 737 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
738 738 +++ b/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
739 739 @@ -1,1 +1,1 @@
740 740 -baaf12afde9d8d67f25dab6dced0d2bf77dba47c
741 741 +7838695e10da2bb75ac1156565f40a2595fa2fa0
742 742 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
743 743 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
744 744 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
745 745 @@ -1,1 +1,1 @@
746 746 -aeb2210d19f02886dde00dac279729a48471e2f9
747 747 +971fb41e78fea4f8e0ba5244784239371cb00591
748 748 diff -r 9d5af5072dbd -r 4355d653f84f normal3
749 749 --- a/normal3 Thu Jan 01 00:00:00 1970 +0000
750 750 +++ b/normal3 Thu Jan 01 00:00:00 1970 +0000
751 751 @@ -1,1 +1,1 @@
752 752 -normal3
753 753 +normal33
754 754 diff -r 9d5af5072dbd -r 4355d653f84f sub/normal4
755 755 --- a/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
756 756 +++ b/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
757 757 @@ -1,1 +1,1 @@
758 758 -normal4
759 759 +normal44
760 760
761 761 changeset: 7:daea875e9014
762 762 tag: tip
763 763 user: test
764 764 date: Thu Jan 01 00:00:00 1970 +0000
765 765 summary: add/edit more largefiles
766 766
767 767 diff -r 4355d653f84f -r daea875e9014 .hglf/large3
768 768 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
769 769 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
770 770 @@ -1,1 +0,0 @@
771 771 -7838695e10da2bb75ac1156565f40a2595fa2fa0
772 772 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large6
773 773 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
774 774 +++ b/.hglf/sub2/large6 Thu Jan 01 00:00:00 1970 +0000
775 775 @@ -0,0 +1,1 @@
776 776 +0d6d75887db61b2c7e6c74b5dd8fc6ad50c0cc30
777 777 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large7
778 778 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
779 779 +++ b/.hglf/sub2/large7 Thu Jan 01 00:00:00 1970 +0000
780 780 @@ -0,0 +1,1 @@
781 781 +bb3151689acb10f0c3125c560d5e63df914bc1af
782 782
783 783
784 784 $ hg log --patch -r 6::7 sub/
785 785 changeset: 6:4355d653f84f
786 786 user: test
787 787 date: Thu Jan 01 00:00:00 1970 +0000
788 788 summary: edit files yet again
789 789
790 790 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
791 791 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
792 792 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
793 793 @@ -1,1 +1,1 @@
794 794 -aeb2210d19f02886dde00dac279729a48471e2f9
795 795 +971fb41e78fea4f8e0ba5244784239371cb00591
796 796 diff -r 9d5af5072dbd -r 4355d653f84f sub/normal4
797 797 --- a/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
798 798 +++ b/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
799 799 @@ -1,1 +1,1 @@
800 800 -normal4
801 801 +normal44
802 802
803 803
804 804 log with both --follow and --patch
805 805
806 806 $ hg log --follow --patch --limit 2
807 807 changeset: 7:daea875e9014
808 808 tag: tip
809 809 user: test
810 810 date: Thu Jan 01 00:00:00 1970 +0000
811 811 summary: add/edit more largefiles
812 812
813 813 diff -r 4355d653f84f -r daea875e9014 .hglf/large3
814 814 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
815 815 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
816 816 @@ -1,1 +0,0 @@
817 817 -7838695e10da2bb75ac1156565f40a2595fa2fa0
818 818 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large6
819 819 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
820 820 +++ b/.hglf/sub2/large6 Thu Jan 01 00:00:00 1970 +0000
821 821 @@ -0,0 +1,1 @@
822 822 +0d6d75887db61b2c7e6c74b5dd8fc6ad50c0cc30
823 823 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large7
824 824 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
825 825 +++ b/.hglf/sub2/large7 Thu Jan 01 00:00:00 1970 +0000
826 826 @@ -0,0 +1,1 @@
827 827 +bb3151689acb10f0c3125c560d5e63df914bc1af
828 828
829 829 changeset: 6:4355d653f84f
830 830 user: test
831 831 date: Thu Jan 01 00:00:00 1970 +0000
832 832 summary: edit files yet again
833 833
834 834 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/large3
835 835 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
836 836 +++ b/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
837 837 @@ -1,1 +1,1 @@
838 838 -baaf12afde9d8d67f25dab6dced0d2bf77dba47c
839 839 +7838695e10da2bb75ac1156565f40a2595fa2fa0
840 840 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
841 841 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
842 842 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
843 843 @@ -1,1 +1,1 @@
844 844 -aeb2210d19f02886dde00dac279729a48471e2f9
845 845 +971fb41e78fea4f8e0ba5244784239371cb00591
846 846 diff -r 9d5af5072dbd -r 4355d653f84f normal3
847 847 --- a/normal3 Thu Jan 01 00:00:00 1970 +0000
848 848 +++ b/normal3 Thu Jan 01 00:00:00 1970 +0000
849 849 @@ -1,1 +1,1 @@
850 850 -normal3
851 851 +normal33
852 852 diff -r 9d5af5072dbd -r 4355d653f84f sub/normal4
853 853 --- a/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
854 854 +++ b/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
855 855 @@ -1,1 +1,1 @@
856 856 -normal4
857 857 +normal44
858 858
859 859 $ hg log --follow --patch sub/large4
860 860 changeset: 6:4355d653f84f
861 861 user: test
862 862 date: Thu Jan 01 00:00:00 1970 +0000
863 863 summary: edit files yet again
864 864
865 865 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
866 866 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
867 867 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
868 868 @@ -1,1 +1,1 @@
869 869 -aeb2210d19f02886dde00dac279729a48471e2f9
870 870 +971fb41e78fea4f8e0ba5244784239371cb00591
871 871
872 872 changeset: 5:9d5af5072dbd
873 873 user: test
874 874 date: Thu Jan 01 00:00:00 1970 +0000
875 875 summary: edit files again
876 876
877 877 diff -r 74c02385b94c -r 9d5af5072dbd .hglf/sub/large4
878 878 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
879 879 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
880 880 @@ -1,1 +1,1 @@
881 881 -eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
882 882 +aeb2210d19f02886dde00dac279729a48471e2f9
883 883
884 884 changeset: 4:74c02385b94c
885 885 user: test
886 886 date: Thu Jan 01 00:00:00 1970 +0000
887 887 summary: move files
888 888
889 889 diff -r 9e8fbc4bce62 -r 74c02385b94c .hglf/sub/large4
890 890 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
891 891 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
892 892 @@ -0,0 +1,1 @@
893 893 +eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
894 894
895 895 changeset: 1:ce8896473775
896 896 user: test
897 897 date: Thu Jan 01 00:00:00 1970 +0000
898 898 summary: edit files
899 899
900 900 diff -r 30d30fe6a5be -r ce8896473775 .hglf/sub/large2
901 901 --- a/.hglf/sub/large2 Thu Jan 01 00:00:00 1970 +0000
902 902 +++ b/.hglf/sub/large2 Thu Jan 01 00:00:00 1970 +0000
903 903 @@ -1,1 +1,1 @@
904 904 -1deebade43c8c498a3c8daddac0244dc55d1331d
905 905 +eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
906 906
907 907 changeset: 0:30d30fe6a5be
908 908 user: test
909 909 date: Thu Jan 01 00:00:00 1970 +0000
910 910 summary: add files
911 911
912 912 diff -r 000000000000 -r 30d30fe6a5be .hglf/sub/large2
913 913 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
914 914 +++ b/.hglf/sub/large2 Thu Jan 01 00:00:00 1970 +0000
915 915 @@ -0,0 +1,1 @@
916 916 +1deebade43c8c498a3c8daddac0244dc55d1331d
917 917
918 918 $ cat sub/normal4
919 919 normal44
920 920 $ cat sub/large4
921 921 large44
922 922 $ cat sub2/large6
923 923 large6
924 924 $ cat sub2/large7
925 925 large7
926 926 $ hg log -qf sub2/large7
927 927 7:daea875e9014
928 928 $ hg log -Gqf sub2/large7
929 929 @ 7:daea875e9014
930 930 |
931 931 $ cd ..
932 932
933 933 Test log from outside repo
934 934
935 935 $ hg log b/sub -T '{rev}:{node|short} {desc|firstline}\n'
936 936 6:4355d653f84f edit files yet again
937 937 5:9d5af5072dbd edit files again
938 938 4:74c02385b94c move files
939 939 1:ce8896473775 edit files
940 940 0:30d30fe6a5be add files
941 941
942 942 Test clone at revision
943 943
944 944 $ hg clone a -r 3 c
945 945 adding changesets
946 946 adding manifests
947 947 adding file changes
948 948 added 4 changesets with 10 changes to 4 files
949 949 updating to branch default
950 950 getting changed largefiles
951 951 2 largefiles updated, 0 removed
952 952 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
953 953 $ cd c
954 954 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
955 955 3:9e8fbc4bce62 copy files
956 956 2:51a0ae4d5864 remove files
957 957 1:ce8896473775 edit files
958 958 0:30d30fe6a5be add files
959 959 $ cat normal1
960 960 normal22
961 961 $ cat large1
962 962 large22
963 963 $ cat sub/normal2
964 964 normal22
965 965 $ cat sub/large2
966 966 large22
967 967
968 968 Old revisions of a clone have correct largefiles content (this also
969 969 tests update).
970 970
971 971 $ hg update -r 1
972 972 getting changed largefiles
973 973 1 largefiles updated, 0 removed
974 974 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
975 975 $ cat large1
976 976 large11
977 977 $ cat sub/large2
978 978 large22
979 979 $ cd ..
980 980
981 981 Test cloning with --all-largefiles flag
982 982
983 983 $ rm "${USERCACHE}"/*
984 984 $ hg clone --all-largefiles a a-backup
985 985 updating to branch default
986 986 getting changed largefiles
987 987 3 largefiles updated, 0 removed
988 988 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
989 989 8 additional largefiles cached
990 990
991 991 $ rm "${USERCACHE}"/*
992 992 $ hg clone --all-largefiles -u 0 a a-clone0
993 993 updating to branch default
994 994 getting changed largefiles
995 995 2 largefiles updated, 0 removed
996 996 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
997 997 9 additional largefiles cached
998 998 $ hg -R a-clone0 sum
999 999 parent: 0:30d30fe6a5be
1000 1000 add files
1001 1001 branch: default
1002 1002 commit: (clean)
1003 1003 update: 7 new changesets (update)
1004 1004
1005 1005 $ rm "${USERCACHE}"/*
1006 1006 $ hg clone --all-largefiles -u 1 a a-clone1
1007 1007 updating to branch default
1008 1008 getting changed largefiles
1009 1009 2 largefiles updated, 0 removed
1010 1010 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1011 1011 8 additional largefiles cached
1012 1012 $ hg -R a-clone1 verify --large --lfa --lfc
1013 1013 checking changesets
1014 1014 checking manifests
1015 1015 crosschecking files in changesets and manifests
1016 1016 checking files
1017 1017 10 files, 8 changesets, 24 total revisions
1018 1018 searching 8 changesets for largefiles
1019 1019 verified contents of 13 revisions of 6 largefiles
1020 1020 $ hg -R a-clone1 sum
1021 1021 parent: 1:ce8896473775
1022 1022 edit files
1023 1023 branch: default
1024 1024 commit: (clean)
1025 1025 update: 6 new changesets (update)
1026 1026
1027 1027 $ rm "${USERCACHE}"/*
1028 1028 $ hg clone --all-largefiles -U a a-clone-u
1029 1029 11 additional largefiles cached
1030 1030 $ hg -R a-clone-u sum
1031 1031 parent: -1:000000000000 (no revision checked out)
1032 1032 branch: default
1033 1033 commit: (clean)
1034 1034 update: 8 new changesets (update)
1035 1035
1036 1036 Show computed destination directory:
1037 1037
1038 1038 $ mkdir xyz
1039 1039 $ cd xyz
1040 1040 $ hg clone ../a
1041 1041 destination directory: a
1042 1042 updating to branch default
1043 1043 getting changed largefiles
1044 1044 3 largefiles updated, 0 removed
1045 1045 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1046 1046 $ cd ..
1047 1047
1048 1048 Clone URL without path:
1049 1049
1050 1050 $ hg clone file://
1051 1051 abort: repository / not found!
1052 1052 [255]
1053 1053
1054 1054 Ensure base clone command argument validation
1055 1055
1056 1056 $ hg clone -U -u 0 a a-clone-failure
1057 1057 abort: cannot specify both --noupdate and --updaterev
1058 1058 [255]
1059 1059
1060 1060 $ hg clone --all-largefiles a ssh://localhost/a
1061 1061 abort: --all-largefiles is incompatible with non-local destination ssh://localhost/a
1062 1062 [255]
1063 1063
1064 1064 Test pulling with --all-largefiles flag. Also test that the largefiles are
1065 1065 downloaded from 'default' instead of 'default-push' when no source is specified
1066 1066 (issue3584)
1067 1067
1068 1068 $ rm -Rf a-backup
1069 1069 $ hg clone -r 1 a a-backup
1070 1070 adding changesets
1071 1071 adding manifests
1072 1072 adding file changes
1073 1073 added 2 changesets with 8 changes to 4 files
1074 1074 updating to branch default
1075 1075 getting changed largefiles
1076 1076 2 largefiles updated, 0 removed
1077 1077 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1078 1078 $ rm "${USERCACHE}"/*
1079 1079 $ cd a-backup
1080 1080 $ hg pull --all-largefiles --config paths.default-push=bogus/path
1081 1081 pulling from $TESTTMP/a (glob)
1082 1082 searching for changes
1083 1083 adding changesets
1084 1084 adding manifests
1085 1085 adding file changes
1086 1086 added 6 changesets with 16 changes to 8 files
1087 1087 (run 'hg update' to get a working copy)
1088 1088 6 largefiles cached
1089 1089
1090 1090 redo pull with --lfrev and check it pulls largefiles for the right revs
1091 1091
1092 1092 $ hg rollback
1093 1093 repository tip rolled back to revision 1 (undo pull)
1094 1094 $ hg pull -v --lfrev 'heads(pulled())+min(pulled())'
1095 1095 pulling from $TESTTMP/a (glob)
1096 1096 searching for changes
1097 1097 all local heads known remotely
1098 1098 6 changesets found
1099 1099 adding changesets
1100 1100 uncompressed size of bundle content:
1101 1101 1213 (changelog)
1102 1102 1479 (manifests)
1103 1103 234 .hglf/large1
1104 1104 504 .hglf/large3
1105 1105 512 .hglf/sub/large4
1106 1106 162 .hglf/sub2/large6
1107 1107 162 .hglf/sub2/large7
1108 1108 192 normal1
1109 1109 397 normal3
1110 1110 405 sub/normal4
1111 1111 adding manifests
1112 1112 adding file changes
1113 1113 added 6 changesets with 16 changes to 8 files
1114 1114 calling hook changegroup.lfiles: hgext.largefiles.reposetup.checkrequireslfiles
1115 1115 (run 'hg update' to get a working copy)
1116 1116 pulling largefiles for revision 7
1117 1117 found 971fb41e78fea4f8e0ba5244784239371cb00591 in store
1118 1118 found 0d6d75887db61b2c7e6c74b5dd8fc6ad50c0cc30 in store
1119 1119 found bb3151689acb10f0c3125c560d5e63df914bc1af in store
1120 1120 pulling largefiles for revision 2
1121 1121 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1122 1122 0 largefiles cached
1123 1123
1124 1124 lfpull
1125 1125
1126 1126 $ hg lfpull -r : --config largefiles.usercache=usercache-lfpull
1127 1127 2 largefiles cached
1128 1128 $ hg lfpull -v -r 4+2 --config largefiles.usercache=usercache-lfpull
1129 1129 pulling largefiles for revision 4
1130 1130 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1131 1131 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1132 1132 pulling largefiles for revision 2
1133 1133 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1134 1134 0 largefiles cached
1135 1135
1136 1136 $ ls usercache-lfpull/* | sort
1137 1137 usercache-lfpull/1deebade43c8c498a3c8daddac0244dc55d1331d
1138 1138 usercache-lfpull/4669e532d5b2c093a78eca010077e708a071bb64
1139 1139
1140 1140 $ cd ..
1141 1141
1142 1142 Rebasing between two repositories does not revert largefiles to old
1143 1143 revisions (this was a very bad bug that took a lot of work to fix).
1144 1144
1145 1145 $ hg clone a d
1146 1146 updating to branch default
1147 1147 getting changed largefiles
1148 1148 3 largefiles updated, 0 removed
1149 1149 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1150 1150 $ cd b
1151 1151 $ echo large4-modified > sub/large4
1152 1152 $ echo normal3-modified > normal3
1153 1153 $ hg commit -m "modify normal file and largefile in repo b"
1154 1154 Invoking status precommit hook
1155 1155 M normal3
1156 1156 M sub/large4
1157 1157 $ cd ../d
1158 1158 $ echo large6-modified > sub2/large6
1159 1159 $ echo normal4-modified > sub/normal4
1160 1160 $ hg commit -m "modify normal file largefile in repo d"
1161 1161 Invoking status precommit hook
1162 1162 M sub/normal4
1163 1163 M sub2/large6
1164 1164 $ cd ..
1165 1165 $ hg clone d e
1166 1166 updating to branch default
1167 1167 getting changed largefiles
1168 1168 3 largefiles updated, 0 removed
1169 1169 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1170 1170 $ cd d
1171 1171
1172 1172 More rebase testing, but also test that the largefiles are downloaded from
1173 1173 'default-push' when no source is specified (issue3584). (The largefile from the
1174 1174 pulled revision is however not downloaded but found in the local cache.)
1175 1175 Largefiles are fetched for the new pulled revision, not for existing revisions,
1176 1176 rebased or not.
1177 1177
1178 1178 $ [ ! -f .hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 ]
1179 1179 $ hg pull --rebase --all-largefiles --config paths.default-push=bogus/path --config paths.default=../b
1180 1180 pulling from $TESTTMP/b (glob)
1181 1181 searching for changes
1182 1182 adding changesets
1183 1183 adding manifests
1184 1184 adding file changes
1185 1185 added 1 changesets with 2 changes to 2 files (+1 heads)
1186 0 largefiles cached
1187 1186 rebasing 8:f574fb32bb45 "modify normal file largefile in repo d"
1188 1187 Invoking status precommit hook
1189 1188 M sub/normal4
1190 1189 M sub2/large6
1191 1190 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-dd1d9f80-backup.hg (glob)
1191 0 largefiles cached
1192 1192 $ [ -f .hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 ]
1193 1193 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1194 1194 9:598410d3eb9a modify normal file largefile in repo d
1195 1195 8:a381d2c8c80e modify normal file and largefile in repo b
1196 1196 7:daea875e9014 add/edit more largefiles
1197 1197 6:4355d653f84f edit files yet again
1198 1198 5:9d5af5072dbd edit files again
1199 1199 4:74c02385b94c move files
1200 1200 3:9e8fbc4bce62 copy files
1201 1201 2:51a0ae4d5864 remove files
1202 1202 1:ce8896473775 edit files
1203 1203 0:30d30fe6a5be add files
1204 1204 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n'
1205 1205 @ 9:598410d3eb9a modify normal file largefile in repo d
1206 1206 |
1207 1207 o 8:a381d2c8c80e modify normal file and largefile in repo b
1208 1208 |
1209 1209 o 7:daea875e9014 add/edit more largefiles
1210 1210 |
1211 1211 o 6:4355d653f84f edit files yet again
1212 1212 |
1213 1213 o 5:9d5af5072dbd edit files again
1214 1214 |
1215 1215 o 4:74c02385b94c move files
1216 1216 |
1217 1217 o 3:9e8fbc4bce62 copy files
1218 1218 |
1219 1219 o 2:51a0ae4d5864 remove files
1220 1220 |
1221 1221 o 1:ce8896473775 edit files
1222 1222 |
1223 1223 o 0:30d30fe6a5be add files
1224 1224
1225 1225 $ cat normal3
1226 1226 normal3-modified
1227 1227 $ cat sub/normal4
1228 1228 normal4-modified
1229 1229 $ cat sub/large4
1230 1230 large4-modified
1231 1231 $ cat sub2/large6
1232 1232 large6-modified
1233 1233 $ cat sub2/large7
1234 1234 large7
1235 1235 $ cd ../e
1236 1236 $ hg pull ../b
1237 1237 pulling from ../b
1238 1238 searching for changes
1239 1239 adding changesets
1240 1240 adding manifests
1241 1241 adding file changes
1242 1242 added 1 changesets with 2 changes to 2 files (+1 heads)
1243 1243 (run 'hg heads' to see heads, 'hg merge' to merge)
1244 1244 $ hg rebase
1245 1245 rebasing 8:f574fb32bb45 "modify normal file largefile in repo d"
1246 1246 Invoking status precommit hook
1247 1247 M sub/normal4
1248 1248 M sub2/large6
1249 1249 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-dd1d9f80-backup.hg (glob)
1250 1250 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1251 1251 9:598410d3eb9a modify normal file largefile in repo d
1252 1252 8:a381d2c8c80e modify normal file and largefile in repo b
1253 1253 7:daea875e9014 add/edit more largefiles
1254 1254 6:4355d653f84f edit files yet again
1255 1255 5:9d5af5072dbd edit files again
1256 1256 4:74c02385b94c move files
1257 1257 3:9e8fbc4bce62 copy files
1258 1258 2:51a0ae4d5864 remove files
1259 1259 1:ce8896473775 edit files
1260 1260 0:30d30fe6a5be add files
1261 1261 $ cat normal3
1262 1262 normal3-modified
1263 1263 $ cat sub/normal4
1264 1264 normal4-modified
1265 1265 $ cat sub/large4
1266 1266 large4-modified
1267 1267 $ cat sub2/large6
1268 1268 large6-modified
1269 1269 $ cat sub2/large7
1270 1270 large7
1271 1271
1272 1272 Log on largefiles
1273 1273
1274 1274 - same output
1275 1275 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
1276 1276 8:a381d2c8c80e modify normal file and largefile in repo b
1277 1277 6:4355d653f84f edit files yet again
1278 1278 5:9d5af5072dbd edit files again
1279 1279 4:74c02385b94c move files
1280 1280 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
1281 1281 o 8:a381d2c8c80e modify normal file and largefile in repo b
1282 1282 |
1283 1283 o 6:4355d653f84f edit files yet again
1284 1284 |
1285 1285 o 5:9d5af5072dbd edit files again
1286 1286 |
1287 1287 o 4:74c02385b94c move files
1288 1288 |
1289 1289 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub/large4
1290 1290 8:a381d2c8c80e modify normal file and largefile in repo b
1291 1291 6:4355d653f84f edit files yet again
1292 1292 5:9d5af5072dbd edit files again
1293 1293 4:74c02385b94c move files
1294 1294 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
1295 1295 o 8:a381d2c8c80e modify normal file and largefile in repo b
1296 1296 |
1297 1297 o 6:4355d653f84f edit files yet again
1298 1298 |
1299 1299 o 5:9d5af5072dbd edit files again
1300 1300 |
1301 1301 o 4:74c02385b94c move files
1302 1302 |
1303 1303
1304 1304 - .hglf only matches largefiles, without .hglf it matches 9 bco sub/normal
1305 1305 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub
1306 1306 8:a381d2c8c80e modify normal file and largefile in repo b
1307 1307 6:4355d653f84f edit files yet again
1308 1308 5:9d5af5072dbd edit files again
1309 1309 4:74c02385b94c move files
1310 1310 1:ce8896473775 edit files
1311 1311 0:30d30fe6a5be add files
1312 1312 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub
1313 1313 o 8:a381d2c8c80e modify normal file and largefile in repo b
1314 1314 |
1315 1315 o 6:4355d653f84f edit files yet again
1316 1316 |
1317 1317 o 5:9d5af5072dbd edit files again
1318 1318 |
1319 1319 o 4:74c02385b94c move files
1320 1320 |
1321 1321 o 1:ce8896473775 edit files
1322 1322 |
1323 1323 o 0:30d30fe6a5be add files
1324 1324
1325 1325 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub
1326 1326 9:598410d3eb9a modify normal file largefile in repo d
1327 1327 8:a381d2c8c80e modify normal file and largefile in repo b
1328 1328 6:4355d653f84f edit files yet again
1329 1329 5:9d5af5072dbd edit files again
1330 1330 4:74c02385b94c move files
1331 1331 1:ce8896473775 edit files
1332 1332 0:30d30fe6a5be add files
1333 1333 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' sub
1334 1334 @ 9:598410d3eb9a modify normal file largefile in repo d
1335 1335 |
1336 1336 o 8:a381d2c8c80e modify normal file and largefile in repo b
1337 1337 |
1338 1338 o 6:4355d653f84f edit files yet again
1339 1339 |
1340 1340 o 5:9d5af5072dbd edit files again
1341 1341 |
1342 1342 o 4:74c02385b94c move files
1343 1343 |
1344 1344 o 1:ce8896473775 edit files
1345 1345 |
1346 1346 o 0:30d30fe6a5be add files
1347 1347
1348 1348 - globbing gives same result
1349 1349 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' 'glob:sub/*'
1350 1350 9:598410d3eb9a modify normal file largefile in repo d
1351 1351 8:a381d2c8c80e modify normal file and largefile in repo b
1352 1352 6:4355d653f84f edit files yet again
1353 1353 5:9d5af5072dbd edit files again
1354 1354 4:74c02385b94c move files
1355 1355 1:ce8896473775 edit files
1356 1356 0:30d30fe6a5be add files
1357 1357 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' 'glob:sub/*'
1358 1358 @ 9:598410d3eb9a modify normal file largefile in repo d
1359 1359 |
1360 1360 o 8:a381d2c8c80e modify normal file and largefile in repo b
1361 1361 |
1362 1362 o 6:4355d653f84f edit files yet again
1363 1363 |
1364 1364 o 5:9d5af5072dbd edit files again
1365 1365 |
1366 1366 o 4:74c02385b94c move files
1367 1367 |
1368 1368 o 1:ce8896473775 edit files
1369 1369 |
1370 1370 o 0:30d30fe6a5be add files
1371 1371
1372 1372 Rollback on largefiles.
1373 1373
1374 1374 $ echo large4-modified-again > sub/large4
1375 1375 $ hg commit -m "Modify large4 again"
1376 1376 Invoking status precommit hook
1377 1377 M sub/large4
1378 1378 $ hg rollback
1379 1379 repository tip rolled back to revision 9 (undo commit)
1380 1380 working directory now based on revision 9
1381 1381 $ hg st
1382 1382 M sub/large4
1383 1383 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1384 1384 9:598410d3eb9a modify normal file largefile in repo d
1385 1385 8:a381d2c8c80e modify normal file and largefile in repo b
1386 1386 7:daea875e9014 add/edit more largefiles
1387 1387 6:4355d653f84f edit files yet again
1388 1388 5:9d5af5072dbd edit files again
1389 1389 4:74c02385b94c move files
1390 1390 3:9e8fbc4bce62 copy files
1391 1391 2:51a0ae4d5864 remove files
1392 1392 1:ce8896473775 edit files
1393 1393 0:30d30fe6a5be add files
1394 1394 $ cat sub/large4
1395 1395 large4-modified-again
1396 1396
1397 1397 "update --check" refuses to update with uncommitted changes.
1398 1398 $ hg update --check 8
1399 1399 abort: uncommitted changes
1400 1400 [255]
1401 1401
1402 1402 "update --clean" leaves correct largefiles in working copy, even when there is
1403 1403 .orig files from revert in .hglf.
1404 1404
1405 1405 $ echo mistake > sub2/large7
1406 1406 $ hg revert sub2/large7
1407 1407 $ cat sub2/large7
1408 1408 large7
1409 1409 $ cat sub2/large7.orig
1410 1410 mistake
1411 1411 $ test ! -f .hglf/sub2/large7.orig
1412 1412
1413 1413 $ hg -q update --clean -r null
1414 1414 $ hg update --clean
1415 1415 getting changed largefiles
1416 1416 3 largefiles updated, 0 removed
1417 1417 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1418 1418 $ cat normal3
1419 1419 normal3-modified
1420 1420 $ cat sub/normal4
1421 1421 normal4-modified
1422 1422 $ cat sub/large4
1423 1423 large4-modified
1424 1424 $ cat sub2/large6
1425 1425 large6-modified
1426 1426 $ cat sub2/large7
1427 1427 large7
1428 1428 $ cat sub2/large7.orig
1429 1429 mistake
1430 1430 $ test ! -f .hglf/sub2/large7.orig
1431 1431
1432 1432 verify that largefile .orig file no longer is overwritten on every update -C:
1433 1433 $ hg update --clean
1434 1434 getting changed largefiles
1435 1435 0 largefiles updated, 0 removed
1436 1436 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1437 1437 $ cat sub2/large7.orig
1438 1438 mistake
1439 1439 $ rm sub2/large7.orig
1440 1440
1441 1441 Now "update check" is happy.
1442 1442 $ hg update --check 8
1443 1443 getting changed largefiles
1444 1444 1 largefiles updated, 0 removed
1445 1445 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1446 1446 $ hg update --check
1447 1447 getting changed largefiles
1448 1448 1 largefiles updated, 0 removed
1449 1449 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1450 1450
1451 1451 Test removing empty largefiles directories on update
1452 1452 $ test -d sub2 && echo "sub2 exists"
1453 1453 sub2 exists
1454 1454 $ hg update -q null
1455 1455 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1456 1456 [1]
1457 1457 $ hg update -q
1458 1458
1459 1459 Test hg remove removes empty largefiles directories
1460 1460 $ test -d sub2 && echo "sub2 exists"
1461 1461 sub2 exists
1462 1462 $ hg remove sub2/*
1463 1463 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1464 1464 [1]
1465 1465 $ hg revert sub2/large6 sub2/large7
1466 1466
1467 1467 "revert" works on largefiles (and normal files too).
1468 1468 $ echo hack3 >> normal3
1469 1469 $ echo hack4 >> sub/normal4
1470 1470 $ echo hack4 >> sub/large4
1471 1471 $ rm sub2/large6
1472 1472 $ hg revert sub2/large6
1473 1473 $ hg rm sub2/large6
1474 1474 $ echo new >> sub2/large8
1475 1475 $ hg add --large sub2/large8
1476 1476 # XXX we don't really want to report that we're reverting the standin;
1477 1477 # that's just an implementation detail. But I don't see an obvious fix. ;-(
1478 1478 $ hg revert sub
1479 1479 reverting .hglf/sub/large4 (glob)
1480 1480 reverting sub/normal4 (glob)
1481 1481 $ hg status
1482 1482 M normal3
1483 1483 A sub2/large8
1484 1484 R sub2/large6
1485 1485 ? sub/large4.orig
1486 1486 ? sub/normal4.orig
1487 1487 $ cat sub/normal4
1488 1488 normal4-modified
1489 1489 $ cat sub/large4
1490 1490 large4-modified
1491 1491 $ hg revert -a --no-backup
1492 1492 undeleting .hglf/sub2/large6 (glob)
1493 1493 forgetting .hglf/sub2/large8 (glob)
1494 1494 reverting normal3
1495 1495 $ hg status
1496 1496 ? sub/large4.orig
1497 1497 ? sub/normal4.orig
1498 1498 ? sub2/large8
1499 1499 $ cat normal3
1500 1500 normal3-modified
1501 1501 $ cat sub2/large6
1502 1502 large6-modified
1503 1503 $ rm sub/*.orig sub2/large8
1504 1504
1505 1505 revert some files to an older revision
1506 1506 $ hg revert --no-backup -r 8 sub2
1507 1507 reverting .hglf/sub2/large6 (glob)
1508 1508 $ cat sub2/large6
1509 1509 large6
1510 1510 $ hg revert --no-backup -C -r '.^' sub2
1511 1511 $ hg revert --no-backup sub2
1512 1512 reverting .hglf/sub2/large6 (glob)
1513 1513 $ hg status
1514 1514
1515 1515 "verify --large" actually verifies largefiles
1516 1516
1517 1517 - Where Do We Come From? What Are We? Where Are We Going?
1518 1518 $ pwd
1519 1519 $TESTTMP/e
1520 1520 $ hg paths
1521 1521 default = $TESTTMP/d (glob)
1522 1522
1523 1523 $ hg verify --large
1524 1524 checking changesets
1525 1525 checking manifests
1526 1526 crosschecking files in changesets and manifests
1527 1527 checking files
1528 1528 10 files, 10 changesets, 28 total revisions
1529 1529 searching 1 changesets for largefiles
1530 1530 verified existence of 3 revisions of 3 largefiles
1531 1531
1532 1532 - introduce missing blob in local store repo and make sure that this is caught:
1533 1533 $ mv $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 .
1534 1534 $ hg verify --large
1535 1535 checking changesets
1536 1536 checking manifests
1537 1537 crosschecking files in changesets and manifests
1538 1538 checking files
1539 1539 10 files, 10 changesets, 28 total revisions
1540 1540 searching 1 changesets for largefiles
1541 1541 changeset 9:598410d3eb9a: sub/large4 references missing $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 (glob)
1542 1542 verified existence of 3 revisions of 3 largefiles
1543 1543 [1]
1544 1544
1545 1545 - introduce corruption and make sure that it is caught when checking content:
1546 1546 $ echo '5 cents' > $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928
1547 1547 $ hg verify -q --large --lfc
1548 1548 changeset 9:598410d3eb9a: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 (glob)
1549 1549 [1]
1550 1550
1551 1551 - cleanup
1552 1552 $ mv e166e74c7303192238d60af5a9c4ce9bef0b7928 $TESTTMP/d/.hg/largefiles/
1553 1553
1554 1554 - verifying all revisions will fail because we didn't clone all largefiles to d:
1555 1555 $ echo 'T-shirt' > $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1556 1556 $ hg verify -q --lfa --lfc
1557 1557 changeset 0:30d30fe6a5be: large1 references missing $TESTTMP/d/.hg/largefiles/4669e532d5b2c093a78eca010077e708a071bb64 (glob)
1558 1558 changeset 0:30d30fe6a5be: sub/large2 references missing $TESTTMP/d/.hg/largefiles/1deebade43c8c498a3c8daddac0244dc55d1331d (glob)
1559 1559 changeset 1:ce8896473775: large1 references missing $TESTTMP/d/.hg/largefiles/5f78770c0e77ba4287ad6ef3071c9bf9c379742f (glob)
1560 1560 changeset 1:ce8896473775: sub/large2 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
1561 1561 changeset 3:9e8fbc4bce62: large1 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
1562 1562 changeset 4:74c02385b94c: large3 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
1563 1563 changeset 4:74c02385b94c: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
1564 1564 changeset 5:9d5af5072dbd: large3 references missing $TESTTMP/d/.hg/largefiles/baaf12afde9d8d67f25dab6dced0d2bf77dba47c (glob)
1565 1565 changeset 5:9d5af5072dbd: sub/large4 references missing $TESTTMP/d/.hg/largefiles/aeb2210d19f02886dde00dac279729a48471e2f9 (glob)
1566 1566 changeset 6:4355d653f84f: large3 references missing $TESTTMP/d/.hg/largefiles/7838695e10da2bb75ac1156565f40a2595fa2fa0 (glob)
1567 1567 [1]
1568 1568
1569 1569 - cleanup
1570 1570 $ rm $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1571 1571 $ rm -f .hglf/sub/*.orig
1572 1572
1573 1573 Update to revision with missing largefile - and make sure it really is missing
1574 1574
1575 1575 $ rm ${USERCACHE}/7838695e10da2bb75ac1156565f40a2595fa2fa0
1576 1576 $ hg up -r 6
1577 1577 getting changed largefiles
1578 1578 large3: largefile 7838695e10da2bb75ac1156565f40a2595fa2fa0 not available from file:/*/$TESTTMP/d (glob)
1579 1579 1 largefiles updated, 2 removed
1580 1580 4 files updated, 0 files merged, 2 files removed, 0 files unresolved
1581 1581 $ rm normal3
1582 1582 $ echo >> sub/normal4
1583 1583 $ hg ci -m 'commit with missing files'
1584 1584 Invoking status precommit hook
1585 1585 M sub/normal4
1586 1586 ! large3
1587 1587 ! normal3
1588 1588 created new head
1589 1589 $ hg st
1590 1590 ! large3
1591 1591 ! normal3
1592 1592 $ hg up -r.
1593 1593 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1594 1594 $ hg st
1595 1595 ! large3
1596 1596 ! normal3
1597 1597 $ hg up -Cr.
1598 1598 getting changed largefiles
1599 1599 large3: largefile 7838695e10da2bb75ac1156565f40a2595fa2fa0 not available from file:/*/$TESTTMP/d (glob)
1600 1600 0 largefiles updated, 0 removed
1601 1601 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1602 1602 $ hg st
1603 1603 ! large3
1604 1604 $ hg rollback
1605 1605 repository tip rolled back to revision 9 (undo commit)
1606 1606 working directory now based on revision 6
1607 1607
1608 1608 Merge with revision with missing largefile - and make sure it tries to fetch it.
1609 1609
1610 1610 $ hg up -Cqr null
1611 1611 $ echo f > f
1612 1612 $ hg ci -Am branch
1613 1613 adding f
1614 1614 Invoking status precommit hook
1615 1615 A f
1616 1616 created new head
1617 1617 $ hg merge -r 6
1618 1618 getting changed largefiles
1619 1619 large3: largefile 7838695e10da2bb75ac1156565f40a2595fa2fa0 not available from file:/*/$TESTTMP/d (glob)
1620 1620 1 largefiles updated, 0 removed
1621 1621 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1622 1622 (branch merge, don't forget to commit)
1623 1623
1624 1624 $ hg rollback -q
1625 1625 $ hg up -Cq
1626 1626
1627 1627 Pulling 0 revisions with --all-largefiles should not fetch for all revisions
1628 1628
1629 1629 $ hg pull --all-largefiles
1630 1630 pulling from $TESTTMP/d (glob)
1631 1631 searching for changes
1632 1632 no changes found
1633 1633
1634 1634 Merging does not revert to old versions of largefiles and also check
1635 1635 that merging after having pulled from a non-default remote works
1636 1636 correctly.
1637 1637
1638 1638 $ cd ..
1639 1639 $ hg clone -r 7 e temp
1640 1640 adding changesets
1641 1641 adding manifests
1642 1642 adding file changes
1643 1643 added 8 changesets with 24 changes to 10 files
1644 1644 updating to branch default
1645 1645 getting changed largefiles
1646 1646 3 largefiles updated, 0 removed
1647 1647 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1648 1648 $ hg clone temp f
1649 1649 updating to branch default
1650 1650 getting changed largefiles
1651 1651 3 largefiles updated, 0 removed
1652 1652 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1653 1653 # Delete the largefiles in the largefiles system cache so that we have an
1654 1654 # opportunity to test that caching after a pull works.
1655 1655 $ rm "${USERCACHE}"/*
1656 1656 $ cd f
1657 1657 $ echo "large4-merge-test" > sub/large4
1658 1658 $ hg commit -m "Modify large4 to test merge"
1659 1659 Invoking status precommit hook
1660 1660 M sub/large4
1661 1661 # Test --cache-largefiles flag
1662 1662 $ hg pull --lfrev 'heads(pulled())' ../e
1663 1663 pulling from ../e
1664 1664 searching for changes
1665 1665 adding changesets
1666 1666 adding manifests
1667 1667 adding file changes
1668 1668 added 2 changesets with 4 changes to 4 files (+1 heads)
1669 1669 (run 'hg heads' to see heads, 'hg merge' to merge)
1670 1670 2 largefiles cached
1671 1671 $ hg merge
1672 1672 largefile sub/large4 has a merge conflict
1673 1673 ancestor was 971fb41e78fea4f8e0ba5244784239371cb00591
1674 1674 keep (l)ocal d846f26643bfa8ec210be40cc93cc6b7ff1128ea or
1675 1675 take (o)ther e166e74c7303192238d60af5a9c4ce9bef0b7928? l
1676 1676 getting changed largefiles
1677 1677 1 largefiles updated, 0 removed
1678 1678 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
1679 1679 (branch merge, don't forget to commit)
1680 1680 $ hg commit -m "Merge repos e and f"
1681 1681 Invoking status precommit hook
1682 1682 M normal3
1683 1683 M sub/normal4
1684 1684 M sub2/large6
1685 1685 $ cat normal3
1686 1686 normal3-modified
1687 1687 $ cat sub/normal4
1688 1688 normal4-modified
1689 1689 $ cat sub/large4
1690 1690 large4-merge-test
1691 1691 $ cat sub2/large6
1692 1692 large6-modified
1693 1693 $ cat sub2/large7
1694 1694 large7
1695 1695
1696 1696 Test status after merging with a branch that introduces a new largefile:
1697 1697
1698 1698 $ echo large > large
1699 1699 $ hg add --large large
1700 1700 $ hg commit -m 'add largefile'
1701 1701 Invoking status precommit hook
1702 1702 A large
1703 1703 $ hg update -q ".^"
1704 1704 $ echo change >> normal3
1705 1705 $ hg commit -m 'some change'
1706 1706 Invoking status precommit hook
1707 1707 M normal3
1708 1708 created new head
1709 1709 $ hg merge
1710 1710 getting changed largefiles
1711 1711 1 largefiles updated, 0 removed
1712 1712 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1713 1713 (branch merge, don't forget to commit)
1714 1714 $ hg status
1715 1715 M large
1716 1716
1717 1717 - make sure update of merge with removed largefiles fails as expected
1718 1718 $ hg rm sub2/large6
1719 1719 $ hg up -r.
1720 1720 abort: outstanding uncommitted merge
1721 1721 [255]
1722 1722
1723 1723 - revert should be able to revert files introduced in a pending merge
1724 1724 $ hg revert --all -r .
1725 1725 removing .hglf/large (glob)
1726 1726 undeleting .hglf/sub2/large6 (glob)
1727 1727
1728 1728 Test that a normal file and a largefile with the same name and path cannot
1729 1729 coexist.
1730 1730
1731 1731 $ rm sub2/large7
1732 1732 $ echo "largeasnormal" > sub2/large7
1733 1733 $ hg add sub2/large7
1734 1734 sub2/large7 already a largefile (glob)
1735 1735
1736 1736 Test that transplanting a largefile change works correctly.
1737 1737
1738 1738 $ cd ..
1739 1739 $ hg clone -r 8 d g
1740 1740 adding changesets
1741 1741 adding manifests
1742 1742 adding file changes
1743 1743 added 9 changesets with 26 changes to 10 files
1744 1744 updating to branch default
1745 1745 getting changed largefiles
1746 1746 3 largefiles updated, 0 removed
1747 1747 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1748 1748 $ cd g
1749 1749 $ hg transplant -s ../d 598410d3eb9a
1750 1750 searching for changes
1751 1751 searching for changes
1752 1752 adding changesets
1753 1753 adding manifests
1754 1754 adding file changes
1755 1755 added 1 changesets with 2 changes to 2 files
1756 1756 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1757 1757 9:598410d3eb9a modify normal file largefile in repo d
1758 1758 8:a381d2c8c80e modify normal file and largefile in repo b
1759 1759 7:daea875e9014 add/edit more largefiles
1760 1760 6:4355d653f84f edit files yet again
1761 1761 5:9d5af5072dbd edit files again
1762 1762 4:74c02385b94c move files
1763 1763 3:9e8fbc4bce62 copy files
1764 1764 2:51a0ae4d5864 remove files
1765 1765 1:ce8896473775 edit files
1766 1766 0:30d30fe6a5be add files
1767 1767 $ cat normal3
1768 1768 normal3-modified
1769 1769 $ cat sub/normal4
1770 1770 normal4-modified
1771 1771 $ cat sub/large4
1772 1772 large4-modified
1773 1773 $ cat sub2/large6
1774 1774 large6-modified
1775 1775 $ cat sub2/large7
1776 1776 large7
1777 1777
1778 1778 Cat a largefile
1779 1779 $ hg cat normal3
1780 1780 normal3-modified
1781 1781 $ hg cat sub/large4
1782 1782 large4-modified
1783 1783 $ rm "${USERCACHE}"/*
1784 1784 $ hg cat -r a381d2c8c80e -o cat.out sub/large4
1785 1785 $ cat cat.out
1786 1786 large4-modified
1787 1787 $ rm cat.out
1788 1788 $ hg cat -r a381d2c8c80e normal3
1789 1789 normal3-modified
1790 1790 $ hg cat -r '.^' normal3
1791 1791 normal3-modified
1792 1792 $ hg cat -r '.^' sub/large4 doesntexist
1793 1793 large4-modified
1794 1794 doesntexist: no such file in rev a381d2c8c80e
1795 1795 $ hg --cwd sub cat -r '.^' large4
1796 1796 large4-modified
1797 1797 $ hg --cwd sub cat -r '.^' ../normal3
1798 1798 normal3-modified
1799 1799 Cat a standin
1800 1800 $ hg cat .hglf/sub/large4
1801 1801 e166e74c7303192238d60af5a9c4ce9bef0b7928
1802 1802 $ hg cat .hglf/normal3
1803 1803 .hglf/normal3: no such file in rev 598410d3eb9a (glob)
1804 1804 [1]
1805 1805
1806 1806 Test that renaming a largefile results in correct output for status
1807 1807
1808 1808 $ hg rename sub/large4 large4-renamed
1809 1809 $ hg commit -m "test rename output"
1810 1810 Invoking status precommit hook
1811 1811 A large4-renamed
1812 1812 R sub/large4
1813 1813 $ cat large4-renamed
1814 1814 large4-modified
1815 1815 $ cd sub2
1816 1816 $ hg rename large6 large6-renamed
1817 1817 $ hg st
1818 1818 A sub2/large6-renamed
1819 1819 R sub2/large6
1820 1820 $ cd ..
1821 1821
1822 1822 Test --normal flag
1823 1823
1824 1824 $ dd if=/dev/zero bs=2k count=11k > new-largefile 2> /dev/null
1825 1825 $ hg add --normal --large new-largefile
1826 1826 abort: --normal cannot be used with --large
1827 1827 [255]
1828 1828 $ hg add --normal new-largefile
1829 1829 new-largefile: up to 69 MB of RAM may be required to manage this file
1830 1830 (use 'hg revert new-largefile' to cancel the pending addition)
1831 1831 $ cd ..
1832 1832
1833 1833
1834 1834
@@ -1,380 +1,422
1 1 Preparing the subrepository 'sub2'
2 2
3 3 $ hg init sub2
4 4 $ echo sub2 > sub2/sub2
5 5 $ hg add -R sub2
6 6 adding sub2/sub2 (glob)
7 7 $ hg commit -R sub2 -m "sub2 import"
8 8
9 9 Preparing the 'sub1' repo which depends on the subrepo 'sub2'
10 10
11 11 $ hg init sub1
12 12 $ echo sub1 > sub1/sub1
13 13 $ echo "sub2 = ../sub2" > sub1/.hgsub
14 14 $ hg clone sub2 sub1/sub2
15 15 updating to branch default
16 16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
17 17 $ hg add -R sub1
18 18 adding sub1/.hgsub (glob)
19 19 adding sub1/sub1 (glob)
20 20 $ hg commit -R sub1 -m "sub1 import"
21 21
22 22 Preparing the 'main' repo which depends on the subrepo 'sub1'
23 23
24 24 $ hg init main
25 25 $ echo main > main/main
26 26 $ echo "sub1 = ../sub1" > main/.hgsub
27 27 $ hg clone sub1 main/sub1
28 28 updating to branch default
29 29 cloning subrepo sub2 from $TESTTMP/sub2
30 30 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
31 31 $ hg add -R main
32 32 adding main/.hgsub (glob)
33 33 adding main/main (glob)
34 34 $ hg commit -R main -m "main import"
35 35
36 36 Cleaning both repositories, just as a clone -U
37 37
38 38 $ hg up -C -R sub2 null
39 39 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
40 40 $ hg up -C -R sub1 null
41 41 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
42 42 $ hg up -C -R main null
43 43 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
44 44 $ rm -rf main/sub1
45 45 $ rm -rf sub1/sub2
46 46
47 47 Clone main
48 48
49 $ hg clone main cloned
49 $ hg --config extensions.largefiles= clone main cloned
50 50 updating to branch default
51 51 cloning subrepo sub1 from $TESTTMP/sub1
52 52 cloning subrepo sub1/sub2 from $TESTTMP/sub2 (glob)
53 53 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
54 54
55 Largefiles is NOT enabled in the clone if the source repo doesn't require it
56 $ cat cloned/.hg/hgrc
57 # example repository config (see "hg help config" for more info)
58 [paths]
59 default = $TESTTMP/main (glob)
60
61 # path aliases to other clones of this repo in URLs or filesystem paths
62 # (see "hg help config.paths" for more info)
63 #
64 # default-push = ssh://jdoe@example.net/hg/jdoes-fork
65 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
66 # my-clone = /home/jdoe/jdoes-clone
67
68 [ui]
69 # name and email (local to this repository, optional), e.g.
70 # username = Jane Doe <jdoe@example.com>
71
55 72 Checking cloned repo ids
56 73
57 74 $ printf "cloned " ; hg id -R cloned
58 75 cloned 7f491f53a367 tip
59 76 $ printf "cloned/sub1 " ; hg id -R cloned/sub1
60 77 cloned/sub1 fc3b4ce2696f tip
61 78 $ printf "cloned/sub1/sub2 " ; hg id -R cloned/sub1/sub2
62 79 cloned/sub1/sub2 c57a0840e3ba tip
63 80
64 81 debugsub output for main and sub1
65 82
66 83 $ hg debugsub -R cloned
67 84 path sub1
68 85 source ../sub1
69 86 revision fc3b4ce2696f7741438c79207583768f2ce6b0dd
70 87 $ hg debugsub -R cloned/sub1
71 88 path sub2
72 89 source ../sub2
73 90 revision c57a0840e3badd667ef3c3ef65471609acb2ba3c
74 91
75 92 Modifying deeply nested 'sub2'
76 93
77 94 $ echo modified > cloned/sub1/sub2/sub2
78 95 $ hg commit --subrepos -m "deep nested modif should trigger a commit" -R cloned
79 96 committing subrepository sub1
80 97 committing subrepository sub1/sub2 (glob)
81 98
82 99 Checking modified node ids
83 100
84 101 $ printf "cloned " ; hg id -R cloned
85 102 cloned ffe6649062fe tip
86 103 $ printf "cloned/sub1 " ; hg id -R cloned/sub1
87 104 cloned/sub1 2ecb03bf44a9 tip
88 105 $ printf "cloned/sub1/sub2 " ; hg id -R cloned/sub1/sub2
89 106 cloned/sub1/sub2 53dd3430bcaf tip
90 107
91 108 debugsub output for main and sub1
92 109
93 110 $ hg debugsub -R cloned
94 111 path sub1
95 112 source ../sub1
96 113 revision 2ecb03bf44a94e749e8669481dd9069526ce7cb9
97 114 $ hg debugsub -R cloned/sub1
98 115 path sub2
99 116 source ../sub2
100 117 revision 53dd3430bcaf5ab4a7c48262bcad6d441f510487
101 118
102 119 Check that deep archiving works
103 120
104 121 $ cd cloned
105 122 $ echo 'test' > sub1/sub2/test.txt
106 123 $ hg --config extensions.largefiles=! add sub1/sub2/test.txt
107 124 $ mkdir sub1/sub2/folder
108 125 $ echo 'subfolder' > sub1/sub2/folder/test.txt
109 126 $ hg ci -ASm "add test.txt"
110 127 adding sub1/sub2/folder/test.txt
111 128 committing subrepository sub1
112 129 committing subrepository sub1/sub2 (glob)
113 130
114 131 .. but first take a detour through some deep removal testing
115 132
116 133 $ hg remove -S -I 're:.*.txt' .
117 134 removing sub1/sub2/folder/test.txt (glob)
118 135 removing sub1/sub2/test.txt (glob)
119 136 $ hg status -S
120 137 R sub1/sub2/folder/test.txt
121 138 R sub1/sub2/test.txt
122 139 $ hg update -Cq
123 140 $ hg remove -I 're:.*.txt' sub1
124 141 $ hg status -S
125 142 $ hg remove sub1/sub2/folder/test.txt
126 143 $ hg remove sub1/.hgsubstate
127 144 $ hg status -S
128 145 R sub1/.hgsubstate
129 146 R sub1/sub2/folder/test.txt
130 147 $ hg update -Cq
131 148 $ touch sub1/foo
132 149 $ hg forget sub1/sub2/folder/test.txt
133 150 $ rm sub1/sub2/test.txt
134 151
135 152 Test relative path printing + subrepos
136 153 $ mkdir -p foo/bar
137 154 $ cd foo
138 155 $ touch bar/abc
139 156 $ hg addremove -S ..
140 157 adding ../sub1/sub2/folder/test.txt (glob)
141 158 removing ../sub1/sub2/test.txt (glob)
142 159 adding ../sub1/foo (glob)
143 160 adding bar/abc (glob)
144 161 $ cd ..
145 162 $ hg status -S
146 163 A foo/bar/abc
147 164 A sub1/foo
148 165 R sub1/sub2/test.txt
149 166 $ hg update -Cq
150 167 $ touch sub1/sub2/folder/bar
151 168 $ hg addremove sub1/sub2
152 169 adding sub1/sub2/folder/bar (glob)
153 170 $ hg status -S
154 171 A sub1/sub2/folder/bar
155 172 ? foo/bar/abc
156 173 ? sub1/foo
157 174 $ hg update -Cq
158 175 $ hg addremove sub1
159 176 adding sub1/sub2/folder/bar (glob)
160 177 adding sub1/foo (glob)
161 178 $ hg update -Cq
162 179 $ rm sub1/sub2/folder/test.txt
163 180 $ rm sub1/sub2/test.txt
164 181 $ hg ci -ASm "remove test.txt"
165 182 adding sub1/sub2/folder/bar
166 183 removing sub1/sub2/folder/test.txt
167 184 removing sub1/sub2/test.txt
168 185 adding sub1/foo
169 186 adding foo/bar/abc
170 187 committing subrepository sub1
171 188 committing subrepository sub1/sub2 (glob)
172 189 $ hg rollback -q
173 190 $ hg up -Cq
174 191
175 192 $ hg --config extensions.largefiles=! archive -S ../archive_all
176 193 $ find ../archive_all | sort
177 194 ../archive_all
178 195 ../archive_all/.hg_archival.txt
179 196 ../archive_all/.hgsub
180 197 ../archive_all/.hgsubstate
181 198 ../archive_all/main
182 199 ../archive_all/sub1
183 200 ../archive_all/sub1/.hgsub
184 201 ../archive_all/sub1/.hgsubstate
185 202 ../archive_all/sub1/sub1
186 203 ../archive_all/sub1/sub2
187 204 ../archive_all/sub1/sub2/folder
188 205 ../archive_all/sub1/sub2/folder/test.txt
189 206 ../archive_all/sub1/sub2/sub2
190 207 ../archive_all/sub1/sub2/test.txt
191 208
192 209 Check that archive -X works in deep subrepos
193 210
194 211 $ hg --config extensions.largefiles=! archive -S -X '**test*' ../archive_exclude
195 212 $ find ../archive_exclude | sort
196 213 ../archive_exclude
197 214 ../archive_exclude/.hg_archival.txt
198 215 ../archive_exclude/.hgsub
199 216 ../archive_exclude/.hgsubstate
200 217 ../archive_exclude/main
201 218 ../archive_exclude/sub1
202 219 ../archive_exclude/sub1/.hgsub
203 220 ../archive_exclude/sub1/.hgsubstate
204 221 ../archive_exclude/sub1/sub1
205 222 ../archive_exclude/sub1/sub2
206 223 ../archive_exclude/sub1/sub2/sub2
207 224
208 225 $ hg --config extensions.largefiles=! archive -S -I '**test*' ../archive_include
209 226 $ find ../archive_include | sort
210 227 ../archive_include
211 228 ../archive_include/sub1
212 229 ../archive_include/sub1/sub2
213 230 ../archive_include/sub1/sub2/folder
214 231 ../archive_include/sub1/sub2/folder/test.txt
215 232 ../archive_include/sub1/sub2/test.txt
216 233
217 234 Check that deep archive works with largefiles (which overrides hgsubrepo impl)
218 235 This also tests the repo.ui regression in 43fb170a23bd, and that lf subrepo
219 236 subrepos are archived properly.
220 237 Note that add --large through a subrepo currently adds the file as a normal file
221 238
222 239 $ echo "large" > sub1/sub2/large.bin
223 240 $ hg --config extensions.largefiles= add --large -R sub1/sub2 sub1/sub2/large.bin
224 241 $ echo "large" > large.bin
225 242 $ hg --config extensions.largefiles= add --large large.bin
226 243 $ hg --config extensions.largefiles= ci -S -m "add large files"
227 244 committing subrepository sub1
228 245 committing subrepository sub1/sub2 (glob)
229 246
230 247 $ hg --config extensions.largefiles= archive -S ../archive_lf
231 248 $ find ../archive_lf | sort
232 249 ../archive_lf
233 250 ../archive_lf/.hg_archival.txt
234 251 ../archive_lf/.hgsub
235 252 ../archive_lf/.hgsubstate
236 253 ../archive_lf/large.bin
237 254 ../archive_lf/main
238 255 ../archive_lf/sub1
239 256 ../archive_lf/sub1/.hgsub
240 257 ../archive_lf/sub1/.hgsubstate
241 258 ../archive_lf/sub1/sub1
242 259 ../archive_lf/sub1/sub2
243 260 ../archive_lf/sub1/sub2/folder
244 261 ../archive_lf/sub1/sub2/folder/test.txt
245 262 ../archive_lf/sub1/sub2/large.bin
246 263 ../archive_lf/sub1/sub2/sub2
247 264 ../archive_lf/sub1/sub2/test.txt
248 265 $ rm -rf ../archive_lf
249 266
250 267 Exclude large files from main and sub-sub repo
251 268
252 269 $ hg --config extensions.largefiles= archive -S -X '**.bin' ../archive_lf
253 270 $ find ../archive_lf | sort
254 271 ../archive_lf
255 272 ../archive_lf/.hg_archival.txt
256 273 ../archive_lf/.hgsub
257 274 ../archive_lf/.hgsubstate
258 275 ../archive_lf/main
259 276 ../archive_lf/sub1
260 277 ../archive_lf/sub1/.hgsub
261 278 ../archive_lf/sub1/.hgsubstate
262 279 ../archive_lf/sub1/sub1
263 280 ../archive_lf/sub1/sub2
264 281 ../archive_lf/sub1/sub2/folder
265 282 ../archive_lf/sub1/sub2/folder/test.txt
266 283 ../archive_lf/sub1/sub2/sub2
267 284 ../archive_lf/sub1/sub2/test.txt
268 285 $ rm -rf ../archive_lf
269 286
270 287 Exclude normal files from main and sub-sub repo
271 288
272 289 $ hg --config extensions.largefiles= archive -S -X '**.txt' ../archive_lf
273 290 $ find ../archive_lf | sort
274 291 ../archive_lf
275 292 ../archive_lf/.hgsub
276 293 ../archive_lf/.hgsubstate
277 294 ../archive_lf/large.bin
278 295 ../archive_lf/main
279 296 ../archive_lf/sub1
280 297 ../archive_lf/sub1/.hgsub
281 298 ../archive_lf/sub1/.hgsubstate
282 299 ../archive_lf/sub1/sub1
283 300 ../archive_lf/sub1/sub2
284 301 ../archive_lf/sub1/sub2/large.bin
285 302 ../archive_lf/sub1/sub2/sub2
286 303 $ rm -rf ../archive_lf
287 304
288 305 Include normal files from within a largefiles subrepo
289 306
290 307 $ hg --config extensions.largefiles= archive -S -I '**.txt' ../archive_lf
291 308 $ find ../archive_lf | sort
292 309 ../archive_lf
293 310 ../archive_lf/.hg_archival.txt
294 311 ../archive_lf/sub1
295 312 ../archive_lf/sub1/sub2
296 313 ../archive_lf/sub1/sub2/folder
297 314 ../archive_lf/sub1/sub2/folder/test.txt
298 315 ../archive_lf/sub1/sub2/test.txt
299 316 $ rm -rf ../archive_lf
300 317
301 318 Include large files from within a largefiles subrepo
302 319
303 320 $ hg --config extensions.largefiles= archive -S -I '**.bin' ../archive_lf
304 321 $ find ../archive_lf | sort
305 322 ../archive_lf
306 323 ../archive_lf/large.bin
307 324 ../archive_lf/sub1
308 325 ../archive_lf/sub1/sub2
309 326 ../archive_lf/sub1/sub2/large.bin
310 327 $ rm -rf ../archive_lf
311 328
312 329 Find an exact largefile match in a largefiles subrepo
313 330
314 331 $ hg --config extensions.largefiles= archive -S -I 'sub1/sub2/large.bin' ../archive_lf
315 332 $ find ../archive_lf | sort
316 333 ../archive_lf
317 334 ../archive_lf/sub1
318 335 ../archive_lf/sub1/sub2
319 336 ../archive_lf/sub1/sub2/large.bin
320 337 $ rm -rf ../archive_lf
321 338
339 The local repo enables largefiles if a largefiles repo is cloned
340 $ hg showconfig extensions
341 abort: repository requires features unknown to this Mercurial: largefiles!
342 (see http://mercurial.selenic.com/wiki/MissingRequirement for more information)
343 [255]
344 $ hg --config extensions.largefiles= clone -qU . ../lfclone
345 $ cat ../lfclone/.hg/hgrc
346 # example repository config (see "hg help config" for more info)
347 [paths]
348 default = $TESTTMP/cloned (glob)
349
350 # path aliases to other clones of this repo in URLs or filesystem paths
351 # (see "hg help config.paths" for more info)
352 #
353 # default-push = ssh://jdoe@example.net/hg/jdoes-fork
354 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
355 # my-clone = /home/jdoe/jdoes-clone
356
357 [ui]
358 # name and email (local to this repository, optional), e.g.
359 # username = Jane Doe <jdoe@example.com>
360
361 [extensions]
362 largefiles=
363
322 364 Find an exact match to a standin (should archive nothing)
323 365 $ hg --config extensions.largefiles= archive -S -I 'sub/sub2/.hglf/large.bin' ../archive_lf
324 366 $ find ../archive_lf 2> /dev/null | sort
325 367
326 368 $ cat >> $HGRCPATH <<EOF
327 369 > [extensions]
328 370 > largefiles=
329 371 > [largefiles]
330 372 > patterns=glob:**.dat
331 373 > EOF
332 374
333 375 Test forget through a deep subrepo with the largefiles extension, both a
334 376 largefile and a normal file. Then a largefile that hasn't been committed yet.
335 377 $ touch sub1/sub2/untracked.txt
336 378 $ touch sub1/sub2/large.dat
337 379 $ hg forget sub1/sub2/large.bin sub1/sub2/test.txt sub1/sub2/untracked.txt
338 380 not removing sub1/sub2/untracked.txt: file is already untracked (glob)
339 381 [1]
340 382 $ hg add --large --dry-run -v sub1/sub2/untracked.txt
341 383 adding sub1/sub2/untracked.txt as a largefile (glob)
342 384 $ hg add --large -v sub1/sub2/untracked.txt
343 385 adding sub1/sub2/untracked.txt as a largefile (glob)
344 386 $ hg add --normal -v sub1/sub2/large.dat
345 387 adding sub1/sub2/large.dat (glob)
346 388 $ hg forget -v sub1/sub2/untracked.txt
347 389 removing sub1/sub2/untracked.txt (glob)
348 390 $ hg status -S
349 391 A sub1/sub2/large.dat
350 392 R sub1/sub2/large.bin
351 393 R sub1/sub2/test.txt
352 394 ? foo/bar/abc
353 395 ? sub1/sub2/untracked.txt
354 396 $ hg add sub1/sub2
355 397 $ hg ci -Sqm 'forget testing'
356 398
357 399 Test issue4330: commit a directory where only normal files have changed
358 400 $ touch foo/bar/large.dat
359 401 $ hg add --large foo/bar/large.dat
360 402 $ hg ci -m 'add foo/bar/large.dat'
361 403 $ touch a.txt
362 404 $ touch a.dat
363 405 $ hg add -v foo/bar/abc a.txt a.dat
364 406 adding a.dat as a largefile
365 407 adding a.txt
366 408 adding foo/bar/abc (glob)
367 409 $ hg ci -m 'dir commit with only normal file deltas' foo/bar
368 410 $ hg status
369 411 A a.dat
370 412 A a.txt
371 413
372 414 Test a directory commit with a changed largefile and a changed normal file
373 415 $ echo changed > foo/bar/large.dat
374 416 $ echo changed > foo/bar/abc
375 417 $ hg ci -m 'dir commit with normal and lf file deltas' foo
376 418 $ hg status
377 419 A a.dat
378 420 A a.txt
379 421
380 422 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now