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