6 # This software may be used and distributed according to the terms of the |
6 # This software may be used and distributed according to the terms of the |
7 # GNU General Public License version 2 or any later version. |
7 # GNU General Public License version 2 or any later version. |
8 |
8 |
9 '''High-level command function for lfconvert, plus the cmdtable.''' |
9 '''High-level command function for lfconvert, plus the cmdtable.''' |
10 |
10 |
11 import os |
11 import os, errno |
12 import shutil |
12 import shutil |
13 |
13 |
14 from mercurial import util, match as match_, hg, node, context, error, \ |
14 from mercurial import util, match as match_, hg, node, context, error, \ |
15 cmdutil, scmutil, commands |
15 cmdutil, scmutil, commands |
16 from mercurial.i18n import _ |
16 from mercurial.i18n import _ |
401 if filelist: |
401 if filelist: |
402 lfiles = set(lfiles) & set(filelist) |
402 lfiles = set(lfiles) & set(filelist) |
403 toget = [] |
403 toget = [] |
404 |
404 |
405 for lfile in lfiles: |
405 for lfile in lfiles: |
406 # If we are mid-merge, then we have to trust the standin that is in the |
406 try: |
407 # working copy to have the correct hashvalue. This is because the |
|
408 # original hg.merge() already updated the standin as part of the normal |
|
409 # merge process -- we just have to update the largefile to match. |
|
410 if (getattr(repo, "_ismerging", False) and |
|
411 os.path.exists(repo.wjoin(lfutil.standin(lfile)))): |
|
412 expectedhash = lfutil.readstandin(repo, lfile) |
|
413 else: |
|
414 expectedhash = repo[node][lfutil.standin(lfile)].data().strip() |
407 expectedhash = repo[node][lfutil.standin(lfile)].data().strip() |
415 |
408 except IOError, err: |
416 # if it exists and its hash matches, it might have been locally |
409 if err.errno == errno.ENOENT: |
417 # modified before updating and the user chose 'local'. in this case, |
410 continue # node must be None and standin wasn't found in wctx |
418 # it will not be in any store, so don't look for it. |
411 raise |
419 if ((not os.path.exists(repo.wjoin(lfile)) or |
412 if not lfutil.findfile(repo, expectedhash): |
420 expectedhash != lfutil.hashfile(repo.wjoin(lfile))) and |
|
421 not lfutil.findfile(repo, expectedhash)): |
|
422 toget.append((lfile, expectedhash)) |
413 toget.append((lfile, expectedhash)) |
423 |
414 |
424 if toget: |
415 if toget: |
425 store = basestore._openstore(repo) |
416 store = basestore._openstore(repo) |
426 ret = store.get(toget) |
417 ret = store.get(toget) |
433 [repo.wjoin(lfutil.shortname)], {}) |
424 [repo.wjoin(lfutil.shortname)], {}) |
434 def prepare(ctx, fns): |
425 def prepare(ctx, fns): |
435 pass |
426 pass |
436 totalsuccess = 0 |
427 totalsuccess = 0 |
437 totalmissing = 0 |
428 totalmissing = 0 |
438 for ctx in cmdutil.walkchangerevs(repo, matchfn, {'rev' : rev}, |
429 if rev != []: # walkchangerevs on empty list would return all revs |
439 prepare): |
430 for ctx in cmdutil.walkchangerevs(repo, matchfn, {'rev' : rev}, |
440 success, missing = cachelfiles(ui, repo, ctx.node()) |
431 prepare): |
441 totalsuccess += len(success) |
432 success, missing = cachelfiles(ui, repo, ctx.node()) |
442 totalmissing += len(missing) |
433 totalsuccess += len(success) |
|
434 totalmissing += len(missing) |
443 ui.status(_("%d additional largefiles cached\n") % totalsuccess) |
435 ui.status(_("%d additional largefiles cached\n") % totalsuccess) |
444 if totalmissing > 0: |
436 if totalmissing > 0: |
445 ui.status(_("%d largefiles failed to download\n") % totalmissing) |
437 ui.status(_("%d largefiles failed to download\n") % totalmissing) |
446 return totalsuccess, totalmissing |
438 return totalsuccess, totalmissing |
447 |
439 |
456 |
448 |
457 printed = False |
449 printed = False |
458 if printmessage and lfiles: |
450 if printmessage and lfiles: |
459 ui.status(_('getting changed largefiles\n')) |
451 ui.status(_('getting changed largefiles\n')) |
460 printed = True |
452 printed = True |
461 cachelfiles(ui, repo, '.', lfiles) |
453 cachelfiles(ui, repo, None, lfiles) |
462 |
454 |
463 updated, removed = 0, 0 |
455 updated, removed = 0, 0 |
464 for f in lfiles: |
456 for f in lfiles: |
465 i = _updatelfile(repo, lfdirstate, f) |
457 i = _updatelfile(repo, lfdirstate, f) |
466 if i: |
458 if i: |
498 expecthash != lfutil.hashfile(abslfile))): |
490 expecthash != lfutil.hashfile(abslfile))): |
499 if not lfutil.copyfromcache(repo, expecthash, lfile): |
491 if not lfutil.copyfromcache(repo, expecthash, lfile): |
500 # use normallookup() to allocate entry in largefiles dirstate, |
492 # use normallookup() to allocate entry in largefiles dirstate, |
501 # because lack of it misleads lfilesrepo.status() into |
493 # because lack of it misleads lfilesrepo.status() into |
502 # recognition that such cache missing files are REMOVED. |
494 # recognition that such cache missing files are REMOVED. |
|
495 if lfile not in repo[None]: # not switched to normal file |
|
496 util.unlinkpath(abslfile, ignoremissing=True) |
503 lfdirstate.normallookup(lfile) |
497 lfdirstate.normallookup(lfile) |
504 return None # don't try to set the mode |
498 return None # don't try to set the mode |
505 else: |
499 else: |
506 # Synchronize largefile dirstate to the last modified time of |
500 # Synchronize largefile dirstate to the last modified time of |
507 # the file |
501 # the file |