##// END OF EJS Templates
py3: add r'' prefixes to fix kwargs handling in hgext/sparse.py...
Pulkit Goyal -
r38124:d7cecea0 default
parent child Browse files
Show More
@@ -1,343 +1,343 b''
1 # sparse.py - allow sparse checkouts of the working directory
1 # sparse.py - allow sparse checkouts of the working directory
2 #
2 #
3 # Copyright 2014 Facebook, Inc.
3 # Copyright 2014 Facebook, Inc.
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 """allow sparse checkouts of the working directory (EXPERIMENTAL)
8 """allow sparse checkouts of the working directory (EXPERIMENTAL)
9
9
10 (This extension is not yet protected by backwards compatibility
10 (This extension is not yet protected by backwards compatibility
11 guarantees. Any aspect may break in future releases until this
11 guarantees. Any aspect may break in future releases until this
12 notice is removed.)
12 notice is removed.)
13
13
14 This extension allows the working directory to only consist of a
14 This extension allows the working directory to only consist of a
15 subset of files for the revision. This allows specific files or
15 subset of files for the revision. This allows specific files or
16 directories to be explicitly included or excluded. Many repository
16 directories to be explicitly included or excluded. Many repository
17 operations have performance proportional to the number of files in
17 operations have performance proportional to the number of files in
18 the working directory. So only realizing a subset of files in the
18 the working directory. So only realizing a subset of files in the
19 working directory can improve performance.
19 working directory can improve performance.
20
20
21 Sparse Config Files
21 Sparse Config Files
22 -------------------
22 -------------------
23
23
24 The set of files that are part of a sparse checkout are defined by
24 The set of files that are part of a sparse checkout are defined by
25 a sparse config file. The file defines 3 things: includes (files to
25 a sparse config file. The file defines 3 things: includes (files to
26 include in the sparse checkout), excludes (files to exclude from the
26 include in the sparse checkout), excludes (files to exclude from the
27 sparse checkout), and profiles (links to other config files).
27 sparse checkout), and profiles (links to other config files).
28
28
29 The file format is newline delimited. Empty lines and lines beginning
29 The file format is newline delimited. Empty lines and lines beginning
30 with ``#`` are ignored.
30 with ``#`` are ignored.
31
31
32 Lines beginning with ``%include `` denote another sparse config file
32 Lines beginning with ``%include `` denote another sparse config file
33 to include. e.g. ``%include tests.sparse``. The filename is relative
33 to include. e.g. ``%include tests.sparse``. The filename is relative
34 to the repository root.
34 to the repository root.
35
35
36 The special lines ``[include]`` and ``[exclude]`` denote the section
36 The special lines ``[include]`` and ``[exclude]`` denote the section
37 for includes and excludes that follow, respectively. It is illegal to
37 for includes and excludes that follow, respectively. It is illegal to
38 have ``[include]`` after ``[exclude]``.
38 have ``[include]`` after ``[exclude]``.
39
39
40 Non-special lines resemble file patterns to be added to either includes
40 Non-special lines resemble file patterns to be added to either includes
41 or excludes. The syntax of these lines is documented by :hg:`help patterns`.
41 or excludes. The syntax of these lines is documented by :hg:`help patterns`.
42 Patterns are interpreted as ``glob:`` by default and match against the
42 Patterns are interpreted as ``glob:`` by default and match against the
43 root of the repository.
43 root of the repository.
44
44
45 Exclusion patterns take precedence over inclusion patterns. So even
45 Exclusion patterns take precedence over inclusion patterns. So even
46 if a file is explicitly included, an ``[exclude]`` entry can remove it.
46 if a file is explicitly included, an ``[exclude]`` entry can remove it.
47
47
48 For example, say you have a repository with 3 directories, ``frontend/``,
48 For example, say you have a repository with 3 directories, ``frontend/``,
49 ``backend/``, and ``tools/``. ``frontend/`` and ``backend/`` correspond
49 ``backend/``, and ``tools/``. ``frontend/`` and ``backend/`` correspond
50 to different projects and it is uncommon for someone working on one
50 to different projects and it is uncommon for someone working on one
51 to need the files for the other. But ``tools/`` contains files shared
51 to need the files for the other. But ``tools/`` contains files shared
52 between both projects. Your sparse config files may resemble::
52 between both projects. Your sparse config files may resemble::
53
53
54 # frontend.sparse
54 # frontend.sparse
55 frontend/**
55 frontend/**
56 tools/**
56 tools/**
57
57
58 # backend.sparse
58 # backend.sparse
59 backend/**
59 backend/**
60 tools/**
60 tools/**
61
61
62 Say the backend grows in size. Or there's a directory with thousands
62 Say the backend grows in size. Or there's a directory with thousands
63 of files you wish to exclude. You can modify the profile to exclude
63 of files you wish to exclude. You can modify the profile to exclude
64 certain files::
64 certain files::
65
65
66 [include]
66 [include]
67 backend/**
67 backend/**
68 tools/**
68 tools/**
69
69
70 [exclude]
70 [exclude]
71 tools/tests/**
71 tools/tests/**
72 """
72 """
73
73
74 from __future__ import absolute_import
74 from __future__ import absolute_import
75
75
76 from mercurial.i18n import _
76 from mercurial.i18n import _
77 from mercurial import (
77 from mercurial import (
78 commands,
78 commands,
79 dirstate,
79 dirstate,
80 error,
80 error,
81 extensions,
81 extensions,
82 hg,
82 hg,
83 logcmdutil,
83 logcmdutil,
84 match as matchmod,
84 match as matchmod,
85 pycompat,
85 pycompat,
86 registrar,
86 registrar,
87 sparse,
87 sparse,
88 util,
88 util,
89 )
89 )
90
90
91 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
91 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
92 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
92 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
93 # be specifying the version(s) of Mercurial they are tested with, or
93 # be specifying the version(s) of Mercurial they are tested with, or
94 # leave the attribute unspecified.
94 # leave the attribute unspecified.
95 testedwith = 'ships-with-hg-core'
95 testedwith = 'ships-with-hg-core'
96
96
97 cmdtable = {}
97 cmdtable = {}
98 command = registrar.command(cmdtable)
98 command = registrar.command(cmdtable)
99
99
100 def extsetup(ui):
100 def extsetup(ui):
101 sparse.enabled = True
101 sparse.enabled = True
102
102
103 _setupclone(ui)
103 _setupclone(ui)
104 _setuplog(ui)
104 _setuplog(ui)
105 _setupadd(ui)
105 _setupadd(ui)
106 _setupdirstate(ui)
106 _setupdirstate(ui)
107
107
108 def replacefilecache(cls, propname, replacement):
108 def replacefilecache(cls, propname, replacement):
109 """Replace a filecache property with a new class. This allows changing the
109 """Replace a filecache property with a new class. This allows changing the
110 cache invalidation condition."""
110 cache invalidation condition."""
111 origcls = cls
111 origcls = cls
112 assert callable(replacement)
112 assert callable(replacement)
113 while cls is not object:
113 while cls is not object:
114 if propname in cls.__dict__:
114 if propname in cls.__dict__:
115 orig = cls.__dict__[propname]
115 orig = cls.__dict__[propname]
116 setattr(cls, propname, replacement(orig))
116 setattr(cls, propname, replacement(orig))
117 break
117 break
118 cls = cls.__bases__[0]
118 cls = cls.__bases__[0]
119
119
120 if cls is object:
120 if cls is object:
121 raise AttributeError(_("type '%s' has no property '%s'") % (origcls,
121 raise AttributeError(_("type '%s' has no property '%s'") % (origcls,
122 propname))
122 propname))
123
123
124 def _setuplog(ui):
124 def _setuplog(ui):
125 entry = commands.table['^log|history']
125 entry = commands.table['^log|history']
126 entry[1].append(('', 'sparse', None,
126 entry[1].append(('', 'sparse', None,
127 "limit to changesets affecting the sparse checkout"))
127 "limit to changesets affecting the sparse checkout"))
128
128
129 def _initialrevs(orig, repo, opts):
129 def _initialrevs(orig, repo, opts):
130 revs = orig(repo, opts)
130 revs = orig(repo, opts)
131 if opts.get('sparse'):
131 if opts.get('sparse'):
132 sparsematch = sparse.matcher(repo)
132 sparsematch = sparse.matcher(repo)
133 def ctxmatch(rev):
133 def ctxmatch(rev):
134 ctx = repo[rev]
134 ctx = repo[rev]
135 return any(f for f in ctx.files() if sparsematch(f))
135 return any(f for f in ctx.files() if sparsematch(f))
136 revs = revs.filter(ctxmatch)
136 revs = revs.filter(ctxmatch)
137 return revs
137 return revs
138 extensions.wrapfunction(logcmdutil, '_initialrevs', _initialrevs)
138 extensions.wrapfunction(logcmdutil, '_initialrevs', _initialrevs)
139
139
140 def _clonesparsecmd(orig, ui, repo, *args, **opts):
140 def _clonesparsecmd(orig, ui, repo, *args, **opts):
141 include_pat = opts.get('include')
141 include_pat = opts.get(r'include')
142 exclude_pat = opts.get('exclude')
142 exclude_pat = opts.get(r'exclude')
143 enableprofile_pat = opts.get('enable_profile')
143 enableprofile_pat = opts.get(r'enable_profile')
144 include = exclude = enableprofile = False
144 include = exclude = enableprofile = False
145 if include_pat:
145 if include_pat:
146 pat = include_pat
146 pat = include_pat
147 include = True
147 include = True
148 if exclude_pat:
148 if exclude_pat:
149 pat = exclude_pat
149 pat = exclude_pat
150 exclude = True
150 exclude = True
151 if enableprofile_pat:
151 if enableprofile_pat:
152 pat = enableprofile_pat
152 pat = enableprofile_pat
153 enableprofile = True
153 enableprofile = True
154 if sum([include, exclude, enableprofile]) > 1:
154 if sum([include, exclude, enableprofile]) > 1:
155 raise error.Abort(_("too many flags specified."))
155 raise error.Abort(_("too many flags specified."))
156 if include or exclude or enableprofile:
156 if include or exclude or enableprofile:
157 def clonesparse(orig, self, node, overwrite, *args, **kwargs):
157 def clonesparse(orig, self, node, overwrite, *args, **kwargs):
158 sparse.updateconfig(self.unfiltered(), pat, {}, include=include,
158 sparse.updateconfig(self.unfiltered(), pat, {}, include=include,
159 exclude=exclude, enableprofile=enableprofile,
159 exclude=exclude, enableprofile=enableprofile,
160 usereporootpaths=True)
160 usereporootpaths=True)
161 return orig(self, node, overwrite, *args, **kwargs)
161 return orig(self, node, overwrite, *args, **kwargs)
162 extensions.wrapfunction(hg, 'updaterepo', clonesparse)
162 extensions.wrapfunction(hg, 'updaterepo', clonesparse)
163 return orig(ui, repo, *args, **opts)
163 return orig(ui, repo, *args, **opts)
164
164
165 def _setupclone(ui):
165 def _setupclone(ui):
166 entry = commands.table['^clone']
166 entry = commands.table['^clone']
167 entry[1].append(('', 'enable-profile', [],
167 entry[1].append(('', 'enable-profile', [],
168 'enable a sparse profile'))
168 'enable a sparse profile'))
169 entry[1].append(('', 'include', [],
169 entry[1].append(('', 'include', [],
170 'include sparse pattern'))
170 'include sparse pattern'))
171 entry[1].append(('', 'exclude', [],
171 entry[1].append(('', 'exclude', [],
172 'exclude sparse pattern'))
172 'exclude sparse pattern'))
173 extensions.wrapcommand(commands.table, 'clone', _clonesparsecmd)
173 extensions.wrapcommand(commands.table, 'clone', _clonesparsecmd)
174
174
175 def _setupadd(ui):
175 def _setupadd(ui):
176 entry = commands.table['^add']
176 entry = commands.table['^add']
177 entry[1].append(('s', 'sparse', None,
177 entry[1].append(('s', 'sparse', None,
178 'also include directories of added files in sparse config'))
178 'also include directories of added files in sparse config'))
179
179
180 def _add(orig, ui, repo, *pats, **opts):
180 def _add(orig, ui, repo, *pats, **opts):
181 if opts.get('sparse'):
181 if opts.get(r'sparse'):
182 dirs = set()
182 dirs = set()
183 for pat in pats:
183 for pat in pats:
184 dirname, basename = util.split(pat)
184 dirname, basename = util.split(pat)
185 dirs.add(dirname)
185 dirs.add(dirname)
186 sparse.updateconfig(repo, list(dirs), opts, include=True)
186 sparse.updateconfig(repo, list(dirs), opts, include=True)
187 return orig(ui, repo, *pats, **opts)
187 return orig(ui, repo, *pats, **opts)
188
188
189 extensions.wrapcommand(commands.table, 'add', _add)
189 extensions.wrapcommand(commands.table, 'add', _add)
190
190
191 def _setupdirstate(ui):
191 def _setupdirstate(ui):
192 """Modify the dirstate to prevent stat'ing excluded files,
192 """Modify the dirstate to prevent stat'ing excluded files,
193 and to prevent modifications to files outside the checkout.
193 and to prevent modifications to files outside the checkout.
194 """
194 """
195
195
196 def walk(orig, self, match, subrepos, unknown, ignored, full=True):
196 def walk(orig, self, match, subrepos, unknown, ignored, full=True):
197 # hack to not exclude explicitly-specified paths so that they can
197 # hack to not exclude explicitly-specified paths so that they can
198 # be warned later on e.g. dirstate.add()
198 # be warned later on e.g. dirstate.add()
199 em = matchmod.exact(match._root, match._cwd, match.files())
199 em = matchmod.exact(match._root, match._cwd, match.files())
200 sm = matchmod.unionmatcher([self._sparsematcher, em])
200 sm = matchmod.unionmatcher([self._sparsematcher, em])
201 match = matchmod.intersectmatchers(match, sm)
201 match = matchmod.intersectmatchers(match, sm)
202 return orig(self, match, subrepos, unknown, ignored, full)
202 return orig(self, match, subrepos, unknown, ignored, full)
203
203
204 extensions.wrapfunction(dirstate.dirstate, 'walk', walk)
204 extensions.wrapfunction(dirstate.dirstate, 'walk', walk)
205
205
206 # dirstate.rebuild should not add non-matching files
206 # dirstate.rebuild should not add non-matching files
207 def _rebuild(orig, self, parent, allfiles, changedfiles=None):
207 def _rebuild(orig, self, parent, allfiles, changedfiles=None):
208 matcher = self._sparsematcher
208 matcher = self._sparsematcher
209 if not matcher.always():
209 if not matcher.always():
210 allfiles = allfiles.matches(matcher)
210 allfiles = allfiles.matches(matcher)
211 if changedfiles:
211 if changedfiles:
212 changedfiles = [f for f in changedfiles if matcher(f)]
212 changedfiles = [f for f in changedfiles if matcher(f)]
213
213
214 if changedfiles is not None:
214 if changedfiles is not None:
215 # In _rebuild, these files will be deleted from the dirstate
215 # In _rebuild, these files will be deleted from the dirstate
216 # when they are not found to be in allfiles
216 # when they are not found to be in allfiles
217 dirstatefilestoremove = set(f for f in self if not matcher(f))
217 dirstatefilestoremove = set(f for f in self if not matcher(f))
218 changedfiles = dirstatefilestoremove.union(changedfiles)
218 changedfiles = dirstatefilestoremove.union(changedfiles)
219
219
220 return orig(self, parent, allfiles, changedfiles)
220 return orig(self, parent, allfiles, changedfiles)
221 extensions.wrapfunction(dirstate.dirstate, 'rebuild', _rebuild)
221 extensions.wrapfunction(dirstate.dirstate, 'rebuild', _rebuild)
222
222
223 # Prevent adding files that are outside the sparse checkout
223 # Prevent adding files that are outside the sparse checkout
224 editfuncs = ['normal', 'add', 'normallookup', 'copy', 'remove', 'merge']
224 editfuncs = ['normal', 'add', 'normallookup', 'copy', 'remove', 'merge']
225 hint = _('include file with `hg debugsparse --include <pattern>` or use ' +
225 hint = _('include file with `hg debugsparse --include <pattern>` or use ' +
226 '`hg add -s <file>` to include file directory while adding')
226 '`hg add -s <file>` to include file directory while adding')
227 for func in editfuncs:
227 for func in editfuncs:
228 def _wrapper(orig, self, *args):
228 def _wrapper(orig, self, *args):
229 sparsematch = self._sparsematcher
229 sparsematch = self._sparsematcher
230 if not sparsematch.always():
230 if not sparsematch.always():
231 for f in args:
231 for f in args:
232 if (f is not None and not sparsematch(f) and
232 if (f is not None and not sparsematch(f) and
233 f not in self):
233 f not in self):
234 raise error.Abort(_("cannot add '%s' - it is outside "
234 raise error.Abort(_("cannot add '%s' - it is outside "
235 "the sparse checkout") % f,
235 "the sparse checkout") % f,
236 hint=hint)
236 hint=hint)
237 return orig(self, *args)
237 return orig(self, *args)
238 extensions.wrapfunction(dirstate.dirstate, func, _wrapper)
238 extensions.wrapfunction(dirstate.dirstate, func, _wrapper)
239
239
240 @command('^debugsparse', [
240 @command('^debugsparse', [
241 ('I', 'include', False, _('include files in the sparse checkout')),
241 ('I', 'include', False, _('include files in the sparse checkout')),
242 ('X', 'exclude', False, _('exclude files in the sparse checkout')),
242 ('X', 'exclude', False, _('exclude files in the sparse checkout')),
243 ('d', 'delete', False, _('delete an include/exclude rule')),
243 ('d', 'delete', False, _('delete an include/exclude rule')),
244 ('f', 'force', False, _('allow changing rules even with pending changes')),
244 ('f', 'force', False, _('allow changing rules even with pending changes')),
245 ('', 'enable-profile', False, _('enables the specified profile')),
245 ('', 'enable-profile', False, _('enables the specified profile')),
246 ('', 'disable-profile', False, _('disables the specified profile')),
246 ('', 'disable-profile', False, _('disables the specified profile')),
247 ('', 'import-rules', False, _('imports rules from a file')),
247 ('', 'import-rules', False, _('imports rules from a file')),
248 ('', 'clear-rules', False, _('clears local include/exclude rules')),
248 ('', 'clear-rules', False, _('clears local include/exclude rules')),
249 ('', 'refresh', False, _('updates the working after sparseness changes')),
249 ('', 'refresh', False, _('updates the working after sparseness changes')),
250 ('', 'reset', False, _('makes the repo full again')),
250 ('', 'reset', False, _('makes the repo full again')),
251 ] + commands.templateopts,
251 ] + commands.templateopts,
252 _('[--OPTION] PATTERN...'))
252 _('[--OPTION] PATTERN...'))
253 def debugsparse(ui, repo, *pats, **opts):
253 def debugsparse(ui, repo, *pats, **opts):
254 """make the current checkout sparse, or edit the existing checkout
254 """make the current checkout sparse, or edit the existing checkout
255
255
256 The sparse command is used to make the current checkout sparse.
256 The sparse command is used to make the current checkout sparse.
257 This means files that don't meet the sparse condition will not be
257 This means files that don't meet the sparse condition will not be
258 written to disk, or show up in any working copy operations. It does
258 written to disk, or show up in any working copy operations. It does
259 not affect files in history in any way.
259 not affect files in history in any way.
260
260
261 Passing no arguments prints the currently applied sparse rules.
261 Passing no arguments prints the currently applied sparse rules.
262
262
263 --include and --exclude are used to add and remove files from the sparse
263 --include and --exclude are used to add and remove files from the sparse
264 checkout. The effects of adding an include or exclude rule are applied
264 checkout. The effects of adding an include or exclude rule are applied
265 immediately. If applying the new rule would cause a file with pending
265 immediately. If applying the new rule would cause a file with pending
266 changes to be added or removed, the command will fail. Pass --force to
266 changes to be added or removed, the command will fail. Pass --force to
267 force a rule change even with pending changes (the changes on disk will
267 force a rule change even with pending changes (the changes on disk will
268 be preserved).
268 be preserved).
269
269
270 --delete removes an existing include/exclude rule. The effects are
270 --delete removes an existing include/exclude rule. The effects are
271 immediate.
271 immediate.
272
272
273 --refresh refreshes the files on disk based on the sparse rules. This is
273 --refresh refreshes the files on disk based on the sparse rules. This is
274 only necessary if .hg/sparse was changed by hand.
274 only necessary if .hg/sparse was changed by hand.
275
275
276 --enable-profile and --disable-profile accept a path to a .hgsparse file.
276 --enable-profile and --disable-profile accept a path to a .hgsparse file.
277 This allows defining sparse checkouts and tracking them inside the
277 This allows defining sparse checkouts and tracking them inside the
278 repository. This is useful for defining commonly used sparse checkouts for
278 repository. This is useful for defining commonly used sparse checkouts for
279 many people to use. As the profile definition changes over time, the sparse
279 many people to use. As the profile definition changes over time, the sparse
280 checkout will automatically be updated appropriately, depending on which
280 checkout will automatically be updated appropriately, depending on which
281 changeset is checked out. Changes to .hgsparse are not applied until they
281 changeset is checked out. Changes to .hgsparse are not applied until they
282 have been committed.
282 have been committed.
283
283
284 --import-rules accepts a path to a file containing rules in the .hgsparse
284 --import-rules accepts a path to a file containing rules in the .hgsparse
285 format, allowing you to add --include, --exclude and --enable-profile rules
285 format, allowing you to add --include, --exclude and --enable-profile rules
286 in bulk. Like the --include, --exclude and --enable-profile switches, the
286 in bulk. Like the --include, --exclude and --enable-profile switches, the
287 changes are applied immediately.
287 changes are applied immediately.
288
288
289 --clear-rules removes all local include and exclude rules, while leaving
289 --clear-rules removes all local include and exclude rules, while leaving
290 any enabled profiles in place.
290 any enabled profiles in place.
291
291
292 Returns 0 if editing the sparse checkout succeeds.
292 Returns 0 if editing the sparse checkout succeeds.
293 """
293 """
294 opts = pycompat.byteskwargs(opts)
294 opts = pycompat.byteskwargs(opts)
295 include = opts.get('include')
295 include = opts.get('include')
296 exclude = opts.get('exclude')
296 exclude = opts.get('exclude')
297 force = opts.get('force')
297 force = opts.get('force')
298 enableprofile = opts.get('enable_profile')
298 enableprofile = opts.get('enable_profile')
299 disableprofile = opts.get('disable_profile')
299 disableprofile = opts.get('disable_profile')
300 importrules = opts.get('import_rules')
300 importrules = opts.get('import_rules')
301 clearrules = opts.get('clear_rules')
301 clearrules = opts.get('clear_rules')
302 delete = opts.get('delete')
302 delete = opts.get('delete')
303 refresh = opts.get('refresh')
303 refresh = opts.get('refresh')
304 reset = opts.get('reset')
304 reset = opts.get('reset')
305 count = sum([include, exclude, enableprofile, disableprofile, delete,
305 count = sum([include, exclude, enableprofile, disableprofile, delete,
306 importrules, refresh, clearrules, reset])
306 importrules, refresh, clearrules, reset])
307 if count > 1:
307 if count > 1:
308 raise error.Abort(_("too many flags specified"))
308 raise error.Abort(_("too many flags specified"))
309
309
310 if count == 0:
310 if count == 0:
311 if repo.vfs.exists('sparse'):
311 if repo.vfs.exists('sparse'):
312 ui.status(repo.vfs.read("sparse") + "\n")
312 ui.status(repo.vfs.read("sparse") + "\n")
313 temporaryincludes = sparse.readtemporaryincludes(repo)
313 temporaryincludes = sparse.readtemporaryincludes(repo)
314 if temporaryincludes:
314 if temporaryincludes:
315 ui.status(_("Temporarily Included Files (for merge/rebase):\n"))
315 ui.status(_("Temporarily Included Files (for merge/rebase):\n"))
316 ui.status(("\n".join(temporaryincludes) + "\n"))
316 ui.status(("\n".join(temporaryincludes) + "\n"))
317 else:
317 else:
318 ui.status(_('repo is not sparse\n'))
318 ui.status(_('repo is not sparse\n'))
319 return
319 return
320
320
321 if include or exclude or delete or reset or enableprofile or disableprofile:
321 if include or exclude or delete or reset or enableprofile or disableprofile:
322 sparse.updateconfig(repo, pats, opts, include=include, exclude=exclude,
322 sparse.updateconfig(repo, pats, opts, include=include, exclude=exclude,
323 reset=reset, delete=delete,
323 reset=reset, delete=delete,
324 enableprofile=enableprofile,
324 enableprofile=enableprofile,
325 disableprofile=disableprofile, force=force)
325 disableprofile=disableprofile, force=force)
326
326
327 if importrules:
327 if importrules:
328 sparse.importfromfiles(repo, opts, pats, force=force)
328 sparse.importfromfiles(repo, opts, pats, force=force)
329
329
330 if clearrules:
330 if clearrules:
331 sparse.clearrules(repo, force=force)
331 sparse.clearrules(repo, force=force)
332
332
333 if refresh:
333 if refresh:
334 try:
334 try:
335 wlock = repo.wlock()
335 wlock = repo.wlock()
336 fcounts = map(
336 fcounts = map(
337 len,
337 len,
338 sparse.refreshwdir(repo, repo.status(), sparse.matcher(repo),
338 sparse.refreshwdir(repo, repo.status(), sparse.matcher(repo),
339 force=force))
339 force=force))
340 sparse.printchanges(ui, opts, added=fcounts[0], dropped=fcounts[1],
340 sparse.printchanges(ui, opts, added=fcounts[0], dropped=fcounts[1],
341 conflicting=fcounts[2])
341 conflicting=fcounts[2])
342 finally:
342 finally:
343 wlock.release()
343 wlock.release()
General Comments 0
You need to be logged in to leave comments. Login now