diff --git a/hgext/sparse.py b/hgext/sparse.py --- a/hgext/sparse.py +++ b/hgext/sparse.py @@ -361,7 +361,7 @@ def debugsparse(ui, repo, *pats, **opts) disableprofile=disableprofile, force=force) if importrules: - _import(ui, repo, pats, opts, force=force) + sparse.importfromfiles(repo, opts, pats, force=force) if clearrules: sparse.clearrules(repo, force=force) @@ -444,51 +444,3 @@ def _config(ui, repo, pats, opts, includ raise finally: wlock.release() - -def _import(ui, repo, files, opts, force=False): - with repo.wlock(): - # read current configuration - raw = repo.vfs.tryread('sparse') - oincludes, oexcludes, oprofiles = sparse.parseconfig(ui, raw) - includes, excludes, profiles = map( - set, (oincludes, oexcludes, oprofiles)) - - aincludes, aexcludes, aprofiles = sparse.activeconfig(repo) - - # import rules on top; only take in rules that are not yet - # part of the active rules. - changed = False - for file in files: - with util.posixfile(util.expandpath(file)) as importfile: - iincludes, iexcludes, iprofiles = sparse.parseconfig( - ui, importfile.read()) - oldsize = len(includes) + len(excludes) + len(profiles) - includes.update(iincludes - aincludes) - excludes.update(iexcludes - aexcludes) - profiles.update(set(iprofiles) - aprofiles) - if len(includes) + len(excludes) + len(profiles) > oldsize: - changed = True - - profilecount = includecount = excludecount = 0 - fcounts = (0, 0, 0) - - if changed: - profilecount = len(profiles - aprofiles) - includecount = len(includes - aincludes) - excludecount = len(excludes - aexcludes) - - oldstatus = repo.status() - oldsparsematch = sparse.matcher(repo) - sparse.writeconfig(repo, includes, excludes, profiles) - - try: - fcounts = map( - len, - sparse.refreshwdir(repo, oldstatus, oldsparsematch, - force=force)) - except Exception: - sparse.writeconfig(repo, oincludes, oexcludes, oprofiles) - raise - - sparse.printchanges(ui, opts, profilecount, includecount, excludecount, - *fcounts) diff --git a/mercurial/sparse.py b/mercurial/sparse.py --- a/mercurial/sparse.py +++ b/mercurial/sparse.py @@ -18,6 +18,7 @@ from . import ( match as matchmod, merge as mergemod, pycompat, + util, ) # Whether sparse features are enabled. This variable is intended to be @@ -521,6 +522,67 @@ def clearrules(repo, force=False): writeconfig(repo, set(), set(), profiles) refreshwdir(repo, oldstatus, oldmatch, force=force) +def importfromfiles(repo, opts, paths, force=False): + """Import sparse config rules from files. + + The updated sparse config is written out and the working directory + is refreshed, as needed. + """ + with repo.wlock(): + # read current configuration + raw = repo.vfs.tryread('sparse') + oincludes, oexcludes, oprofiles = parseconfig(repo.ui, raw) + includes, excludes, profiles = map( + set, (oincludes, oexcludes, oprofiles)) + + aincludes, aexcludes, aprofiles = activeconfig(repo) + + # Import rules on top; only take in rules that are not yet + # part of the active rules. + changed = False + for p in paths: + with util.posixfile(util.expandpath(p)) as fh: + raw = fh.read() + + iincludes, iexcludes, iprofiles = parseconfig(repo.ui, raw) + oldsize = len(includes) + len(excludes) + len(profiles) + includes.update(iincludes - aincludes) + excludes.update(iexcludes - aexcludes) + profiles.update(set(iprofiles) - aprofiles) + if len(includes) + len(excludes) + len(profiles) > oldsize: + changed = True + + profilecount = includecount = excludecount = 0 + fcounts = (0, 0, 0) + + if changed: + profilecount = len(profiles - aprofiles) + includecount = len(includes - aincludes) + excludecount = len(excludes - aexcludes) + + oldstatus = repo.status() + oldsparsematch = matcher(repo) + + # TODO remove this try..except once the matcher integrates better + # with dirstate. We currently have to write the updated config + # because that will invalidate the matcher cache and force a + # re-read. We ideally want to update the cached matcher on the + # repo instance then flush the new config to disk once wdir is + # updated. But this requires massive rework to matcher() and its + # consumers. + writeconfig(repo, includes, excludes, profiles) + + try: + fcounts = map( + len, + refreshwdir(repo, oldstatus, oldsparsematch, force=force)) + except Exception: + writeconfig(repo, oincludes, oexcludes, oprofiles) + raise + + printchanges(repo.ui, opts, profilecount, includecount, excludecount, + *fcounts) + def printchanges(ui, opts, profilecount=0, includecount=0, excludecount=0, added=0, dropped=0, conflicting=0): """Print output summarizing sparse config changes."""