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