119 break |
119 break |
120 cls = cls.__bases__[0] |
120 cls = cls.__bases__[0] |
121 |
121 |
122 if cls is object: |
122 if cls is object: |
123 raise AttributeError( |
123 raise AttributeError( |
124 _("type '%s' has no property '%s'") % (origcls, propname) |
124 _(b"type '%s' has no property '%s'") % (origcls, propname) |
125 ) |
125 ) |
126 |
126 |
127 |
127 |
128 def _setuplog(ui): |
128 def _setuplog(ui): |
129 entry = commands.table['log|history'] |
129 entry = commands.table[b'log|history'] |
130 entry[1].append( |
130 entry[1].append( |
131 ( |
131 ( |
132 '', |
132 b'', |
133 'sparse', |
133 b'sparse', |
134 None, |
134 None, |
135 "limit to changesets affecting the sparse checkout", |
135 b"limit to changesets affecting the sparse checkout", |
136 ) |
136 ) |
137 ) |
137 ) |
138 |
138 |
139 def _initialrevs(orig, repo, opts): |
139 def _initialrevs(orig, repo, opts): |
140 revs = orig(repo, opts) |
140 revs = orig(repo, opts) |
141 if opts.get('sparse'): |
141 if opts.get(b'sparse'): |
142 sparsematch = sparse.matcher(repo) |
142 sparsematch = sparse.matcher(repo) |
143 |
143 |
144 def ctxmatch(rev): |
144 def ctxmatch(rev): |
145 ctx = repo[rev] |
145 ctx = repo[rev] |
146 return any(f for f in ctx.files() if sparsematch(f)) |
146 return any(f for f in ctx.files() if sparsematch(f)) |
147 |
147 |
148 revs = revs.filter(ctxmatch) |
148 revs = revs.filter(ctxmatch) |
149 return revs |
149 return revs |
150 |
150 |
151 extensions.wrapfunction(logcmdutil, '_initialrevs', _initialrevs) |
151 extensions.wrapfunction(logcmdutil, b'_initialrevs', _initialrevs) |
152 |
152 |
153 |
153 |
154 def _clonesparsecmd(orig, ui, repo, *args, **opts): |
154 def _clonesparsecmd(orig, ui, repo, *args, **opts): |
155 include_pat = opts.get(r'include') |
155 include_pat = opts.get(r'include') |
156 exclude_pat = opts.get(r'exclude') |
156 exclude_pat = opts.get(r'exclude') |
182 enableprofile=enableprofile, |
182 enableprofile=enableprofile, |
183 usereporootpaths=True, |
183 usereporootpaths=True, |
184 ) |
184 ) |
185 return orig(self, node, overwrite, *args, **kwargs) |
185 return orig(self, node, overwrite, *args, **kwargs) |
186 |
186 |
187 extensions.wrapfunction(hg, 'updaterepo', clonesparse) |
187 extensions.wrapfunction(hg, b'updaterepo', clonesparse) |
188 return orig(ui, repo, *args, **opts) |
188 return orig(ui, repo, *args, **opts) |
189 |
189 |
190 |
190 |
191 def _setupclone(ui): |
191 def _setupclone(ui): |
192 entry = commands.table['clone'] |
192 entry = commands.table[b'clone'] |
193 entry[1].append(('', 'enable-profile', [], 'enable a sparse profile')) |
193 entry[1].append((b'', b'enable-profile', [], b'enable a sparse profile')) |
194 entry[1].append(('', 'include', [], 'include sparse pattern')) |
194 entry[1].append((b'', b'include', [], b'include sparse pattern')) |
195 entry[1].append(('', 'exclude', [], 'exclude sparse pattern')) |
195 entry[1].append((b'', b'exclude', [], b'exclude sparse pattern')) |
196 extensions.wrapcommand(commands.table, 'clone', _clonesparsecmd) |
196 extensions.wrapcommand(commands.table, b'clone', _clonesparsecmd) |
197 |
197 |
198 |
198 |
199 def _setupadd(ui): |
199 def _setupadd(ui): |
200 entry = commands.table['add'] |
200 entry = commands.table[b'add'] |
201 entry[1].append( |
201 entry[1].append( |
202 ( |
202 ( |
203 's', |
203 b's', |
204 'sparse', |
204 b'sparse', |
205 None, |
205 None, |
206 'also include directories of added files in sparse config', |
206 b'also include directories of added files in sparse config', |
207 ) |
207 ) |
208 ) |
208 ) |
209 |
209 |
210 def _add(orig, ui, repo, *pats, **opts): |
210 def _add(orig, ui, repo, *pats, **opts): |
211 if opts.get(r'sparse'): |
211 if opts.get(r'sparse'): |
214 dirname, basename = util.split(pat) |
214 dirname, basename = util.split(pat) |
215 dirs.add(dirname) |
215 dirs.add(dirname) |
216 sparse.updateconfig(repo, list(dirs), opts, include=True) |
216 sparse.updateconfig(repo, list(dirs), opts, include=True) |
217 return orig(ui, repo, *pats, **opts) |
217 return orig(ui, repo, *pats, **opts) |
218 |
218 |
219 extensions.wrapcommand(commands.table, 'add', _add) |
219 extensions.wrapcommand(commands.table, b'add', _add) |
220 |
220 |
221 |
221 |
222 def _setupdirstate(ui): |
222 def _setupdirstate(ui): |
223 """Modify the dirstate to prevent stat'ing excluded files, |
223 """Modify the dirstate to prevent stat'ing excluded files, |
224 and to prevent modifications to files outside the checkout. |
224 and to prevent modifications to files outside the checkout. |
230 em = matchmod.exact(match.files()) |
230 em = matchmod.exact(match.files()) |
231 sm = matchmod.unionmatcher([self._sparsematcher, em]) |
231 sm = matchmod.unionmatcher([self._sparsematcher, em]) |
232 match = matchmod.intersectmatchers(match, sm) |
232 match = matchmod.intersectmatchers(match, sm) |
233 return orig(self, match, subrepos, unknown, ignored, full) |
233 return orig(self, match, subrepos, unknown, ignored, full) |
234 |
234 |
235 extensions.wrapfunction(dirstate.dirstate, 'walk', walk) |
235 extensions.wrapfunction(dirstate.dirstate, b'walk', walk) |
236 |
236 |
237 # dirstate.rebuild should not add non-matching files |
237 # dirstate.rebuild should not add non-matching files |
238 def _rebuild(orig, self, parent, allfiles, changedfiles=None): |
238 def _rebuild(orig, self, parent, allfiles, changedfiles=None): |
239 matcher = self._sparsematcher |
239 matcher = self._sparsematcher |
240 if not matcher.always(): |
240 if not matcher.always(): |
248 dirstatefilestoremove = set(f for f in self if not matcher(f)) |
248 dirstatefilestoremove = set(f for f in self if not matcher(f)) |
249 changedfiles = dirstatefilestoremove.union(changedfiles) |
249 changedfiles = dirstatefilestoremove.union(changedfiles) |
250 |
250 |
251 return orig(self, parent, allfiles, changedfiles) |
251 return orig(self, parent, allfiles, changedfiles) |
252 |
252 |
253 extensions.wrapfunction(dirstate.dirstate, 'rebuild', _rebuild) |
253 extensions.wrapfunction(dirstate.dirstate, b'rebuild', _rebuild) |
254 |
254 |
255 # Prevent adding files that are outside the sparse checkout |
255 # Prevent adding files that are outside the sparse checkout |
256 editfuncs = ['normal', 'add', 'normallookup', 'copy', 'remove', 'merge'] |
256 editfuncs = [ |
|
257 b'normal', |
|
258 b'add', |
|
259 b'normallookup', |
|
260 b'copy', |
|
261 b'remove', |
|
262 b'merge', |
|
263 ] |
257 hint = _( |
264 hint = _( |
258 'include file with `hg debugsparse --include <pattern>` or use ' |
265 b'include file with `hg debugsparse --include <pattern>` or use ' |
259 + '`hg add -s <file>` to include file directory while adding' |
266 + b'`hg add -s <file>` to include file directory while adding' |
260 ) |
267 ) |
261 for func in editfuncs: |
268 for func in editfuncs: |
262 |
269 |
263 def _wrapper(orig, self, *args, **kwargs): |
270 def _wrapper(orig, self, *args, **kwargs): |
264 sparsematch = self._sparsematcher |
271 sparsematch = self._sparsematcher |
265 if not sparsematch.always(): |
272 if not sparsematch.always(): |
266 for f in args: |
273 for f in args: |
267 if f is not None and not sparsematch(f) and f not in self: |
274 if f is not None and not sparsematch(f) and f not in self: |
268 raise error.Abort( |
275 raise error.Abort( |
269 _( |
276 _( |
270 "cannot add '%s' - it is outside " |
277 b"cannot add '%s' - it is outside " |
271 "the sparse checkout" |
278 b"the sparse checkout" |
272 ) |
279 ) |
273 % f, |
280 % f, |
274 hint=hint, |
281 hint=hint, |
275 ) |
282 ) |
276 return orig(self, *args, **kwargs) |
283 return orig(self, *args, **kwargs) |
277 |
284 |
278 extensions.wrapfunction(dirstate.dirstate, func, _wrapper) |
285 extensions.wrapfunction(dirstate.dirstate, func, _wrapper) |
279 |
286 |
280 |
287 |
281 @command( |
288 @command( |
282 'debugsparse', |
289 b'debugsparse', |
283 [ |
290 [ |
284 ('I', 'include', False, _('include files in the sparse checkout')), |
291 (b'I', b'include', False, _(b'include files in the sparse checkout')), |
285 ('X', 'exclude', False, _('exclude files in the sparse checkout')), |
292 (b'X', b'exclude', False, _(b'exclude files in the sparse checkout')), |
286 ('d', 'delete', False, _('delete an include/exclude rule')), |
293 (b'd', b'delete', False, _(b'delete an include/exclude rule')), |
287 ( |
294 ( |
288 'f', |
295 b'f', |
289 'force', |
296 b'force', |
290 False, |
297 False, |
291 _('allow changing rules even with pending changes'), |
298 _(b'allow changing rules even with pending changes'), |
292 ), |
299 ), |
293 ('', 'enable-profile', False, _('enables the specified profile')), |
300 (b'', b'enable-profile', False, _(b'enables the specified profile')), |
294 ('', 'disable-profile', False, _('disables the specified profile')), |
301 (b'', b'disable-profile', False, _(b'disables the specified profile')), |
295 ('', 'import-rules', False, _('imports rules from a file')), |
302 (b'', b'import-rules', False, _(b'imports rules from a file')), |
296 ('', 'clear-rules', False, _('clears local include/exclude rules')), |
303 (b'', b'clear-rules', False, _(b'clears local include/exclude rules')), |
297 ( |
304 ( |
298 '', |
305 b'', |
299 'refresh', |
306 b'refresh', |
300 False, |
307 False, |
301 _('updates the working after sparseness changes'), |
308 _(b'updates the working after sparseness changes'), |
302 ), |
309 ), |
303 ('', 'reset', False, _('makes the repo full again')), |
310 (b'', b'reset', False, _(b'makes the repo full again')), |
304 ] |
311 ] |
305 + commands.templateopts, |
312 + commands.templateopts, |
306 _('[--OPTION] PATTERN...'), |
313 _(b'[--OPTION] PATTERN...'), |
307 helpbasic=True, |
314 helpbasic=True, |
308 ) |
315 ) |
309 def debugsparse(ui, repo, *pats, **opts): |
316 def debugsparse(ui, repo, *pats, **opts): |
310 """make the current checkout sparse, or edit the existing checkout |
317 """make the current checkout sparse, or edit the existing checkout |
311 |
318 |
346 any enabled profiles in place. |
353 any enabled profiles in place. |
347 |
354 |
348 Returns 0 if editing the sparse checkout succeeds. |
355 Returns 0 if editing the sparse checkout succeeds. |
349 """ |
356 """ |
350 opts = pycompat.byteskwargs(opts) |
357 opts = pycompat.byteskwargs(opts) |
351 include = opts.get('include') |
358 include = opts.get(b'include') |
352 exclude = opts.get('exclude') |
359 exclude = opts.get(b'exclude') |
353 force = opts.get('force') |
360 force = opts.get(b'force') |
354 enableprofile = opts.get('enable_profile') |
361 enableprofile = opts.get(b'enable_profile') |
355 disableprofile = opts.get('disable_profile') |
362 disableprofile = opts.get(b'disable_profile') |
356 importrules = opts.get('import_rules') |
363 importrules = opts.get(b'import_rules') |
357 clearrules = opts.get('clear_rules') |
364 clearrules = opts.get(b'clear_rules') |
358 delete = opts.get('delete') |
365 delete = opts.get(b'delete') |
359 refresh = opts.get('refresh') |
366 refresh = opts.get(b'refresh') |
360 reset = opts.get('reset') |
367 reset = opts.get(b'reset') |
361 count = sum( |
368 count = sum( |
362 [ |
369 [ |
363 include, |
370 include, |
364 exclude, |
371 exclude, |
365 enableprofile, |
372 enableprofile, |