comparison mercurial/sparse.py @ 33371:c6415195fa78

sparse: move code for importing rules from files into core This is a pretty straightforward port. Some code cleanup was performed. But no major changes to the logic were made. I'm not a huge fan of this function because it does multiple things. I'd like to get things into core first to facilitate refactoring later. Please also note the added inline comment about the oddities of writeconfig() and the try..except to undo it. This is because of the hackiness in which the sparse matcher is obtained by various consumers, notably dirstate. We'll need a massive refactor to address this. That refactor is effectively blocked on having the sparse dirstate hacks live in core.
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 08 Jul 2017 14:15:07 -0700
parents 482320104672
children 4dc04cdf2520
comparison
equal deleted inserted replaced
33370:482320104672 33371:c6415195fa78
16 from . import ( 16 from . import (
17 error, 17 error,
18 match as matchmod, 18 match as matchmod,
19 merge as mergemod, 19 merge as mergemod,
20 pycompat, 20 pycompat,
21 util,
21 ) 22 )
22 23
23 # Whether sparse features are enabled. This variable is intended to be 24 # Whether sparse features are enabled. This variable is intended to be
24 # temporary to facilitate porting sparse to core. It should eventually be 25 # temporary to facilitate porting sparse to core. It should eventually be
25 # a per-repo option, possibly a repo requirement. 26 # a per-repo option, possibly a repo requirement.
519 oldstatus = repo.status() 520 oldstatus = repo.status()
520 oldmatch = matcher(repo) 521 oldmatch = matcher(repo)
521 writeconfig(repo, set(), set(), profiles) 522 writeconfig(repo, set(), set(), profiles)
522 refreshwdir(repo, oldstatus, oldmatch, force=force) 523 refreshwdir(repo, oldstatus, oldmatch, force=force)
523 524
525 def importfromfiles(repo, opts, paths, force=False):
526 """Import sparse config rules from files.
527
528 The updated sparse config is written out and the working directory
529 is refreshed, as needed.
530 """
531 with repo.wlock():
532 # read current configuration
533 raw = repo.vfs.tryread('sparse')
534 oincludes, oexcludes, oprofiles = parseconfig(repo.ui, raw)
535 includes, excludes, profiles = map(
536 set, (oincludes, oexcludes, oprofiles))
537
538 aincludes, aexcludes, aprofiles = activeconfig(repo)
539
540 # Import rules on top; only take in rules that are not yet
541 # part of the active rules.
542 changed = False
543 for p in paths:
544 with util.posixfile(util.expandpath(p)) as fh:
545 raw = fh.read()
546
547 iincludes, iexcludes, iprofiles = parseconfig(repo.ui, raw)
548 oldsize = len(includes) + len(excludes) + len(profiles)
549 includes.update(iincludes - aincludes)
550 excludes.update(iexcludes - aexcludes)
551 profiles.update(set(iprofiles) - aprofiles)
552 if len(includes) + len(excludes) + len(profiles) > oldsize:
553 changed = True
554
555 profilecount = includecount = excludecount = 0
556 fcounts = (0, 0, 0)
557
558 if changed:
559 profilecount = len(profiles - aprofiles)
560 includecount = len(includes - aincludes)
561 excludecount = len(excludes - aexcludes)
562
563 oldstatus = repo.status()
564 oldsparsematch = matcher(repo)
565
566 # TODO remove this try..except once the matcher integrates better
567 # with dirstate. We currently have to write the updated config
568 # because that will invalidate the matcher cache and force a
569 # re-read. We ideally want to update the cached matcher on the
570 # repo instance then flush the new config to disk once wdir is
571 # updated. But this requires massive rework to matcher() and its
572 # consumers.
573 writeconfig(repo, includes, excludes, profiles)
574
575 try:
576 fcounts = map(
577 len,
578 refreshwdir(repo, oldstatus, oldsparsematch, force=force))
579 except Exception:
580 writeconfig(repo, oincludes, oexcludes, oprofiles)
581 raise
582
583 printchanges(repo.ui, opts, profilecount, includecount, excludecount,
584 *fcounts)
585
524 def printchanges(ui, opts, profilecount=0, includecount=0, excludecount=0, 586 def printchanges(ui, opts, profilecount=0, includecount=0, excludecount=0,
525 added=0, dropped=0, conflicting=0): 587 added=0, dropped=0, conflicting=0):
526 """Print output summarizing sparse config changes.""" 588 """Print output summarizing sparse config changes."""
527 with ui.formatter('sparse', opts) as fm: 589 with ui.formatter('sparse', opts) as fm:
528 fm.startitem() 590 fm.startitem()