Mercurial > hg
comparison hgext/largefiles/lfutil.py @ 23185:9870173e0b48
largefiles: factor out procedures to update standins for pre-committing
This patch factors out procedures to update standins for
pre-committing. This is one of preparations to avoid execution of such
procedures according to invocation context.
For example, resuming automated committing (e.g. "hg rebase
--continue") should update standins at the 1st commit, because
largefiles in the working directory may be modified manually. But on
the other hand, it should avoid updating standins at subsequent
committings for efficiency reason.
For simplicity, this patch just moves procedures mechanically only
with replacing below.
- "self" => "repo"
- "lfutil." => (none)
- "orig" invocation => returning "match"
Using "fstandin" instead "standin" as the name of local variable for
the loop below is the only special care, because the latter shadows
the same name function in "lfutil.py".
[before]
for standin in standins:
lfile = lfutil.splitstandin(standin)
if lfdirstate[lfile] != 'r':
lfutil.updatestandin(self, standin)
[after]
for fstandin in standins:
lfile = splitstandin(fstandin)
if lfdirstate[lfile] != 'r':
updatestandin(repo, fstandin)
author | FUJIWARA Katsunori <foozy@lares.dti.ne.jp> |
---|---|
date | Wed, 05 Nov 2014 23:24:47 +0900 |
parents | 3100d1cbce32 |
children | f726b05ecfe6 |
comparison
equal
deleted
inserted
replaced
23184:3100d1cbce32 | 23185:9870173e0b48 |
---|---|
10 | 10 |
11 import os | 11 import os |
12 import platform | 12 import platform |
13 import shutil | 13 import shutil |
14 import stat | 14 import stat |
15 import copy | |
15 | 16 |
16 from mercurial import dirstate, httpconnection, match as match_, util, scmutil | 17 from mercurial import dirstate, httpconnection, match as match_, util, scmutil |
17 from mercurial.i18n import _ | 18 from mercurial.i18n import _ |
18 from mercurial import node | 19 from mercurial import node |
19 | 20 |
425 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None): | 426 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None): |
426 files.add(f) | 427 files.add(f) |
427 for fn in files: | 428 for fn in files: |
428 if isstandin(fn) and fn in ctx: | 429 if isstandin(fn) and fn in ctx: |
429 addfunc(fn, ctx[fn].data().strip()) | 430 addfunc(fn, ctx[fn].data().strip()) |
431 | |
432 def updatestandinsbymatch(repo, match): | |
433 '''Update standins in the working directory according to specified match | |
434 | |
435 This returns (possibly modified) ``match`` object to be used for | |
436 subsequent commit process. | |
437 ''' | |
438 | |
439 ui = repo.ui | |
440 | |
441 # Case 0: Automated committing | |
442 # | |
443 # While automated committing (like rebase, transplant | |
444 # and so on), this code path is used to avoid: | |
445 # (1) updating standins, because standins should | |
446 # be already updated at this point | |
447 # (2) aborting when standins are matched by "match", | |
448 # because automated committing may specify them directly | |
449 # | |
450 if getattr(repo, "_isrebasing", False) or \ | |
451 getattr(repo, "_istransplanting", False): | |
452 return match | |
453 | |
454 # Case 1: user calls commit with no specific files or | |
455 # include/exclude patterns: refresh and commit all files that | |
456 # are "dirty". | |
457 if match is None or match.always(): | |
458 # Spend a bit of time here to get a list of files we know | |
459 # are modified so we can compare only against those. | |
460 # It can cost a lot of time (several seconds) | |
461 # otherwise to update all standins if the largefiles are | |
462 # large. | |
463 lfdirstate = openlfdirstate(ui, repo) | |
464 dirtymatch = match_.always(repo.root, repo.getcwd()) | |
465 unsure, s = lfdirstate.status(dirtymatch, [], False, False, | |
466 False) | |
467 modifiedfiles = unsure + s.modified + s.added + s.removed | |
468 lfiles = listlfiles(repo) | |
469 # this only loops through largefiles that exist (not | |
470 # removed/renamed) | |
471 for lfile in lfiles: | |
472 if lfile in modifiedfiles: | |
473 if os.path.exists( | |
474 repo.wjoin(standin(lfile))): | |
475 # this handles the case where a rebase is being | |
476 # performed and the working copy is not updated | |
477 # yet. | |
478 if os.path.exists(repo.wjoin(lfile)): | |
479 updatestandin(repo, | |
480 standin(lfile)) | |
481 | |
482 return match | |
483 | |
484 lfiles = listlfiles(repo) | |
485 match._files = repo._subdirlfs(match.files(), lfiles) | |
486 | |
487 # Case 2: user calls commit with specified patterns: refresh | |
488 # any matching big files. | |
489 smatcher = composestandinmatcher(repo, match) | |
490 standins = repo.dirstate.walk(smatcher, [], False, False) | |
491 | |
492 # No matching big files: get out of the way and pass control to | |
493 # the usual commit() method. | |
494 if not standins: | |
495 return match | |
496 | |
497 # Refresh all matching big files. It's possible that the | |
498 # commit will end up failing, in which case the big files will | |
499 # stay refreshed. No harm done: the user modified them and | |
500 # asked to commit them, so sooner or later we're going to | |
501 # refresh the standins. Might as well leave them refreshed. | |
502 lfdirstate = openlfdirstate(ui, repo) | |
503 for fstandin in standins: | |
504 lfile = splitstandin(fstandin) | |
505 if lfdirstate[lfile] != 'r': | |
506 updatestandin(repo, fstandin) | |
507 | |
508 # Cook up a new matcher that only matches regular files or | |
509 # standins corresponding to the big files requested by the | |
510 # user. Have to modify _files to prevent commit() from | |
511 # complaining "not tracked" for big files. | |
512 match = copy.copy(match) | |
513 origmatchfn = match.matchfn | |
514 | |
515 # Check both the list of largefiles and the list of | |
516 # standins because if a largefile was removed, it | |
517 # won't be in the list of largefiles at this point | |
518 match._files += sorted(standins) | |
519 | |
520 actualfiles = [] | |
521 for f in match._files: | |
522 fstandin = standin(f) | |
523 | |
524 # ignore known largefiles and standins | |
525 if f in lfiles or fstandin in standins: | |
526 continue | |
527 | |
528 actualfiles.append(f) | |
529 match._files = actualfiles | |
530 | |
531 def matchfn(f): | |
532 if origmatchfn(f): | |
533 return f not in lfiles | |
534 else: | |
535 return f in standins | |
536 | |
537 match.matchfn = matchfn | |
538 | |
539 return match |