annotate mercurial/sparse.py @ 33320:153456f02426

sparse: move function for resolving sparse matcher into core As part of the move, the function arguments changed so revs are passed as a list instead of *args. This allows us to use keyword arguments properly. Since the plan is to integrate sparse into core and have it enabled by default, we need to prepare for a sparse matcher to always be obtained and operated on. As part of the move, we inserted code that returns an always matcher if sparse isn't enabled. Some callers in the sparse extension take this into account and conditionally perform matching depending on whether the special always matcher is seen. I /think/ this may have sped up some operations where the extension is installed but no sparse config is activated. One thing I'm ensure of in this code is whether os.path.dirname() is semantically correct. os.posixpath.dirname() (which is exported as pathutil.dirname) might be a better choise because all patterns should be using posix directory separators (/) instead of Windows (\). There's an inline comment that implies Windows was tested. So hopefully it won't be a problem. We can improve this in a follow-up. I've added a TODO to track it.
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 06 Jul 2017 17:41:45 -0700
parents 526255fe7899
children d09e948dc303
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
33297
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1 # sparse.py - functionality for sparse checkouts
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
2 #
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
3 # Copyright 2014 Facebook, Inc.
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
4 #
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
7
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
8 from __future__ import absolute_import
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
9
33317
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
10 import hashlib
33320
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
11 import os
33317
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
12
33297
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
13 from .i18n import _
33301
ca4b78eb11e7 sparse: move active profiles function into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33300
diff changeset
14 from .node import nullid
33297
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
15 from . import (
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
16 error,
33320
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
17 match as matchmod,
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
18 pycompat,
33297
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
19 )
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
20
33299
41448fc51510 sparse: variable to track if sparse is enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33298
diff changeset
21 # Whether sparse features are enabled. This variable is intended to be
41448fc51510 sparse: variable to track if sparse is enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33298
diff changeset
22 # temporary to facilitate porting sparse to core. It should eventually be
41448fc51510 sparse: variable to track if sparse is enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33298
diff changeset
23 # a per-repo option, possibly a repo requirement.
41448fc51510 sparse: variable to track if sparse is enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33298
diff changeset
24 enabled = False
41448fc51510 sparse: variable to track if sparse is enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33298
diff changeset
25
33297
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
26 def parseconfig(ui, raw):
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
27 """Parse sparse config file content.
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
28
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
29 Returns a tuple of includes, excludes, and profiles.
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
30 """
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
31 includes = set()
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
32 excludes = set()
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
33 current = includes
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
34 profiles = []
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
35 for line in raw.split('\n'):
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
36 line = line.strip()
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
37 if not line or line.startswith('#'):
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
38 # empty or comment line, skip
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
39 continue
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
40 elif line.startswith('%include '):
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
41 line = line[9:].strip()
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
42 if line:
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
43 profiles.append(line)
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
44 elif line == '[include]':
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
45 if current != includes:
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
46 # TODO pass filename into this API so we can report it.
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
47 raise error.Abort(_('sparse config cannot have includes ' +
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
48 'after excludes'))
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
49 continue
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
50 elif line == '[exclude]':
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
51 current = excludes
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
52 elif line:
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
53 if line.strip().startswith('/'):
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
54 ui.warn(_('warning: sparse profile cannot use' +
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
55 ' paths starting with /, ignoring %s\n') % line)
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
56 continue
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
57 current.add(line)
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
58
ba5d89774db6 sparse: move config parsing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
59 return includes, excludes, profiles
33298
f41a99c45956 sparse: move profile reading into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33297
diff changeset
60
f41a99c45956 sparse: move profile reading into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33297
diff changeset
61 # Exists as separate function to facilitate monkeypatching.
f41a99c45956 sparse: move profile reading into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33297
diff changeset
62 def readprofile(repo, profile, changeid):
f41a99c45956 sparse: move profile reading into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33297
diff changeset
63 """Resolve the raw content of a sparse profile file."""
f41a99c45956 sparse: move profile reading into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33297
diff changeset
64 # TODO add some kind of cache here because this incurs a manifest
f41a99c45956 sparse: move profile reading into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33297
diff changeset
65 # resolve and can be slow.
f41a99c45956 sparse: move profile reading into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33297
diff changeset
66 return repo.filectx(profile, changeid=changeid).data()
33300
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
67
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
68 def patternsforrev(repo, rev):
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
69 """Obtain sparse checkout patterns for the given rev.
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
70
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
71 Returns a tuple of iterables representing includes, excludes, and
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
72 patterns.
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
73 """
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
74 # Feature isn't enabled. No-op.
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
75 if not enabled:
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
76 return set(), set(), []
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
77
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
78 raw = repo.vfs.tryread('sparse')
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
79 if not raw:
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
80 return set(), set(), []
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
81
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
82 if rev is None:
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
83 raise error.Abort(_('cannot parse sparse patterns from working '
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
84 'directory'))
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
85
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
86 includes, excludes, profiles = parseconfig(repo.ui, raw)
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
87 ctx = repo[rev]
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
88
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
89 if profiles:
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
90 visited = set()
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
91 while profiles:
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
92 profile = profiles.pop()
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
93 if profile in visited:
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
94 continue
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
95
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
96 visited.add(profile)
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
97
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
98 try:
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
99 raw = readprofile(repo, profile, rev)
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
100 except error.ManifestLookupError:
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
101 msg = (
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
102 "warning: sparse profile '%s' not found "
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
103 "in rev %s - ignoring it\n" % (profile, ctx))
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
104 # experimental config: sparse.missingwarning
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
105 if repo.ui.configbool(
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
106 'sparse', 'missingwarning', True):
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
107 repo.ui.warn(msg)
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
108 else:
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
109 repo.ui.debug(msg)
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
110 continue
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
111
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
112 pincludes, pexcludes, subprofs = parseconfig(repo.ui, raw)
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
113 includes.update(pincludes)
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
114 excludes.update(pexcludes)
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
115 for subprofile in subprofs:
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
116 profiles.append(subprofile)
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
117
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
118 profiles = visited
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
119
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
120 if includes:
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
121 includes.add('.hg*')
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
122
f7a106b3f089 sparse: move resolving of sparse patterns for rev into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33299
diff changeset
123 return includes, excludes, profiles
33301
ca4b78eb11e7 sparse: move active profiles function into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33300
diff changeset
124
ca4b78eb11e7 sparse: move active profiles function into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33300
diff changeset
125 def activeprofiles(repo):
ca4b78eb11e7 sparse: move active profiles function into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33300
diff changeset
126 revs = [repo.changelog.rev(node) for node in
ca4b78eb11e7 sparse: move active profiles function into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33300
diff changeset
127 repo.dirstate.parents() if node != nullid]
ca4b78eb11e7 sparse: move active profiles function into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33300
diff changeset
128
ca4b78eb11e7 sparse: move active profiles function into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33300
diff changeset
129 profiles = set()
ca4b78eb11e7 sparse: move active profiles function into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33300
diff changeset
130 for rev in revs:
ca4b78eb11e7 sparse: move active profiles function into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33300
diff changeset
131 profiles.update(patternsforrev(repo, rev)[2])
ca4b78eb11e7 sparse: move active profiles function into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33300
diff changeset
132
ca4b78eb11e7 sparse: move active profiles function into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33300
diff changeset
133 return profiles
33302
36a415b5a4b2 localrepo: add sparse caches
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33301
diff changeset
134
36a415b5a4b2 localrepo: add sparse caches
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33301
diff changeset
135 def invalidatesignaturecache(repo):
36a415b5a4b2 localrepo: add sparse caches
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33301
diff changeset
136 repo._sparsesignaturecache.clear()
33303
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
137
33317
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
138 def configsignature(repo, includetemp=True):
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
139 """Obtain the signature string for the current sparse configuration.
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
140
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
141 This is used to construct a cache key for matchers.
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
142 """
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
143 cache = repo._sparsesignaturecache
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
144
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
145 signature = cache.get('signature')
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
146
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
147 if includetemp:
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
148 tempsignature = cache.get('tempsignature')
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
149 else:
33318
526255fe7899 sparse: clean up config signature code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33317
diff changeset
150 tempsignature = '0'
33317
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
151
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
152 if signature is None or (includetemp and tempsignature is None):
33318
526255fe7899 sparse: clean up config signature code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33317
diff changeset
153 signature = hashlib.sha1(repo.vfs.tryread('sparse')).hexdigest()
33317
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
154 cache['signature'] = signature
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
155
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
156 if includetemp:
33318
526255fe7899 sparse: clean up config signature code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33317
diff changeset
157 raw = repo.vfs.tryread('tempsparse')
526255fe7899 sparse: clean up config signature code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33317
diff changeset
158 tempsignature = hashlib.sha1(raw).hexdigest()
33317
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
159 cache['tempsignature'] = tempsignature
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
160
33318
526255fe7899 sparse: clean up config signature code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33317
diff changeset
161 return '%s %s' % (signature, tempsignature)
33317
df1287268cc0 sparse: move config signature logic into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33304
diff changeset
162
33303
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
163 def writeconfig(repo, includes, excludes, profiles):
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
164 """Write the sparse config file given a sparse configuration."""
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
165 with repo.vfs('sparse', 'wb') as fh:
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
166 for p in sorted(profiles):
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
167 fh.write('%%include %s\n' % p)
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
168
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
169 if includes:
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
170 fh.write('[include]\n')
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
171 for i in sorted(includes):
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
172 fh.write(i)
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
173 fh.write('\n')
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
174
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
175 if excludes:
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
176 fh.write('[exclude]\n')
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
177 for e in sorted(excludes):
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
178 fh.write(e)
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
179 fh.write('\n')
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
180
8b571495d811 sparse: move config file writing into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33302
diff changeset
181 invalidatesignaturecache(repo)
33304
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
182
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
183 def readtemporaryincludes(repo):
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
184 raw = repo.vfs.tryread('tempsparse')
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
185 if not raw:
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
186 return set()
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
187
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
188 return set(raw.split('\n'))
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
189
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
190 def writetemporaryincludes(repo, includes):
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
191 repo.vfs.write('tempsparse', '\n'.join(sorted(includes)))
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
192 invalidatesignaturecache(repo)
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
193
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
194 def addtemporaryincludes(repo, additional):
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
195 includes = readtemporaryincludes(repo)
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
196 for i in additional:
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
197 includes.add(i)
3e1accab7447 sparse: move some temporary includes functions into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33303
diff changeset
198 writetemporaryincludes(repo, includes)
33320
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
199
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
200 def matcher(repo, revs=None, includetemp=True):
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
201 """Obtain a matcher for sparse working directories for the given revs.
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
202
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
203 If multiple revisions are specified, the matcher is the union of all
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
204 revs.
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
205
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
206 ``includetemp`` indicates whether to use the temporary sparse profile.
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
207 """
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
208 # If sparse isn't enabled, sparse matcher matches everything.
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
209 if not enabled:
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
210 return matchmod.always(repo.root, '')
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
211
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
212 if not revs or revs == [None]:
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
213 revs = [repo.changelog.rev(node)
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
214 for node in repo.dirstate.parents() if node != nullid]
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
215
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
216 signature = configsignature(repo, includetemp=includetemp)
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
217
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
218 key = '%s %s' % (signature, ' '.join(map(pycompat.bytestr, revs)))
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
219
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
220 result = repo._sparsematchercache.get(key)
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
221 if result:
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
222 return result
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
223
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
224 matchers = []
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
225 for rev in revs:
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
226 try:
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
227 includes, excludes, profiles = patternsforrev(repo, rev)
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
228
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
229 if includes or excludes:
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
230 # Explicitly include subdirectories of includes so
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
231 # status will walk them down to the actual include.
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
232 subdirs = set()
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
233 for include in includes:
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
234 # TODO consider using posix path functions here so Windows
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
235 # \ directory separators don't come into play.
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
236 dirname = os.path.dirname(include)
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
237 # basename is used to avoid issues with absolute
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
238 # paths (which on Windows can include the drive).
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
239 while os.path.basename(dirname):
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
240 subdirs.add(dirname)
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
241 dirname = os.path.dirname(dirname)
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
242
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
243 matcher = matchmod.match(repo.root, '', [],
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
244 include=includes, exclude=excludes,
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
245 default='relpath')
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
246 if subdirs:
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
247 matcher = matchmod.forceincludematcher(matcher, subdirs)
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
248 matchers.append(matcher)
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
249 except IOError:
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
250 pass
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
251
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
252 if not matchers:
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
253 result = matchmod.always(repo.root, '')
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
254 elif len(matchers) == 1:
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
255 result = matchers[0]
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
256 else:
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
257 result = matchmod.unionmatcher(matchers)
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
258
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
259 if includetemp:
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
260 tempincludes = readtemporaryincludes(repo)
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
261 result = matchmod.forceincludematcher(result, tempincludes)
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
262
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
263 repo._sparsematchercache[key] = result
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
264
153456f02426 sparse: move function for resolving sparse matcher into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33318
diff changeset
265 return result