Mercurial > hg
comparison hgext/narrow/narrowcommands.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | 40f78072fda9 |
children | 687b865b95ad |
comparison
equal
deleted
inserted
replaced
43075:57875cf423c9 | 43076:2372284d9457 |
---|---|
28 repoview, | 28 repoview, |
29 sparse, | 29 sparse, |
30 util, | 30 util, |
31 wireprototypes, | 31 wireprototypes, |
32 ) | 32 ) |
33 from mercurial.interfaces import ( | 33 from mercurial.interfaces import repository |
34 repository, | |
35 ) | |
36 | 34 |
37 table = {} | 35 table = {} |
38 command = registrar.command(table) | 36 command = registrar.command(table) |
39 | 37 |
38 | |
40 def setup(): | 39 def setup(): |
41 """Wraps user-facing mercurial commands with narrow-aware versions.""" | 40 """Wraps user-facing mercurial commands with narrow-aware versions.""" |
42 | 41 |
43 entry = extensions.wrapcommand(commands.table, 'clone', clonenarrowcmd) | 42 entry = extensions.wrapcommand(commands.table, 'clone', clonenarrowcmd) |
44 entry[1].append(('', 'narrow', None, | 43 entry[1].append( |
45 _("create a narrow clone of select files"))) | 44 ('', 'narrow', None, _("create a narrow clone of select files")) |
46 entry[1].append(('', 'depth', '', | 45 ) |
47 _("limit the history fetched by distance from heads"))) | 46 entry[1].append( |
48 entry[1].append(('', 'narrowspec', '', | 47 ('', 'depth', '', _("limit the history fetched by distance from heads")) |
49 _("read narrowspecs from file"))) | 48 ) |
49 entry[1].append(('', 'narrowspec', '', _("read narrowspecs from file"))) | |
50 # TODO(durin42): unify sparse/narrow --include/--exclude logic a bit | 50 # TODO(durin42): unify sparse/narrow --include/--exclude logic a bit |
51 if 'sparse' not in extensions.enabled(): | 51 if 'sparse' not in extensions.enabled(): |
52 entry[1].append(('', 'include', [], | |
53 _("specifically fetch this file/directory"))) | |
54 entry[1].append( | 52 entry[1].append( |
55 ('', 'exclude', [], | 53 ('', 'include', [], _("specifically fetch this file/directory")) |
56 _("do not fetch this file/directory, even if included"))) | 54 ) |
55 entry[1].append( | |
56 ( | |
57 '', | |
58 'exclude', | |
59 [], | |
60 _("do not fetch this file/directory, even if included"), | |
61 ) | |
62 ) | |
57 | 63 |
58 entry = extensions.wrapcommand(commands.table, 'pull', pullnarrowcmd) | 64 entry = extensions.wrapcommand(commands.table, 'pull', pullnarrowcmd) |
59 entry[1].append(('', 'depth', '', | 65 entry[1].append( |
60 _("limit the history fetched by distance from heads"))) | 66 ('', 'depth', '', _("limit the history fetched by distance from heads")) |
67 ) | |
61 | 68 |
62 extensions.wrapcommand(commands.table, 'archive', archivenarrowcmd) | 69 extensions.wrapcommand(commands.table, 'archive', archivenarrowcmd) |
70 | |
63 | 71 |
64 def clonenarrowcmd(orig, ui, repo, *args, **opts): | 72 def clonenarrowcmd(orig, ui, repo, *args, **opts): |
65 """Wraps clone command, so 'hg clone' first wraps localrepo.clone().""" | 73 """Wraps clone command, so 'hg clone' first wraps localrepo.clone().""" |
66 opts = pycompat.byteskwargs(opts) | 74 opts = pycompat.byteskwargs(opts) |
67 wrappedextraprepare = util.nullcontextmanager() | 75 wrappedextraprepare = util.nullcontextmanager() |
71 filepath = os.path.join(encoding.getcwd(), narrowspecfile) | 79 filepath = os.path.join(encoding.getcwd(), narrowspecfile) |
72 ui.status(_("reading narrowspec from '%s'\n") % filepath) | 80 ui.status(_("reading narrowspec from '%s'\n") % filepath) |
73 try: | 81 try: |
74 fdata = util.readfile(filepath) | 82 fdata = util.readfile(filepath) |
75 except IOError as inst: | 83 except IOError as inst: |
76 raise error.Abort(_("cannot read narrowspecs from '%s': %s") % | 84 raise error.Abort( |
77 (filepath, encoding.strtolocal(inst.strerror))) | 85 _("cannot read narrowspecs from '%s': %s") |
86 % (filepath, encoding.strtolocal(inst.strerror)) | |
87 ) | |
78 | 88 |
79 includes, excludes, profiles = sparse.parseconfig(ui, fdata, 'narrow') | 89 includes, excludes, profiles = sparse.parseconfig(ui, fdata, 'narrow') |
80 if profiles: | 90 if profiles: |
81 raise error.Abort(_("cannot specify other files using '%include' in" | 91 raise error.Abort( |
82 " narrowspec")) | 92 _( |
93 "cannot specify other files using '%include' in" | |
94 " narrowspec" | |
95 ) | |
96 ) | |
83 | 97 |
84 narrowspec.validatepatterns(includes) | 98 narrowspec.validatepatterns(includes) |
85 narrowspec.validatepatterns(excludes) | 99 narrowspec.validatepatterns(excludes) |
86 | 100 |
87 # narrowspec is passed so we should assume that user wants narrow clone | 101 # narrowspec is passed so we should assume that user wants narrow clone |
88 opts['narrow'] = True | 102 opts['narrow'] = True |
89 opts['include'].extend(includes) | 103 opts['include'].extend(includes) |
90 opts['exclude'].extend(excludes) | 104 opts['exclude'].extend(excludes) |
91 | 105 |
92 if opts['narrow']: | 106 if opts['narrow']: |
107 | |
93 def pullbundle2extraprepare_widen(orig, pullop, kwargs): | 108 def pullbundle2extraprepare_widen(orig, pullop, kwargs): |
94 orig(pullop, kwargs) | 109 orig(pullop, kwargs) |
95 | 110 |
96 if opts.get('depth'): | 111 if opts.get('depth'): |
97 kwargs['depth'] = opts['depth'] | 112 kwargs['depth'] = opts['depth'] |
98 wrappedextraprepare = extensions.wrappedfunction(exchange, | 113 |
99 '_pullbundle2extraprepare', pullbundle2extraprepare_widen) | 114 wrappedextraprepare = extensions.wrappedfunction( |
115 exchange, '_pullbundle2extraprepare', pullbundle2extraprepare_widen | |
116 ) | |
100 | 117 |
101 with wrappedextraprepare: | 118 with wrappedextraprepare: |
102 return orig(ui, repo, *args, **pycompat.strkwargs(opts)) | 119 return orig(ui, repo, *args, **pycompat.strkwargs(opts)) |
120 | |
103 | 121 |
104 def pullnarrowcmd(orig, ui, repo, *args, **opts): | 122 def pullnarrowcmd(orig, ui, repo, *args, **opts): |
105 """Wraps pull command to allow modifying narrow spec.""" | 123 """Wraps pull command to allow modifying narrow spec.""" |
106 wrappedextraprepare = util.nullcontextmanager() | 124 wrappedextraprepare = util.nullcontextmanager() |
107 if repository.NARROW_REQUIREMENT in repo.requirements: | 125 if repository.NARROW_REQUIREMENT in repo.requirements: |
108 | 126 |
109 def pullbundle2extraprepare_widen(orig, pullop, kwargs): | 127 def pullbundle2extraprepare_widen(orig, pullop, kwargs): |
110 orig(pullop, kwargs) | 128 orig(pullop, kwargs) |
111 if opts.get(r'depth'): | 129 if opts.get(r'depth'): |
112 kwargs['depth'] = opts[r'depth'] | 130 kwargs['depth'] = opts[r'depth'] |
113 wrappedextraprepare = extensions.wrappedfunction(exchange, | 131 |
114 '_pullbundle2extraprepare', pullbundle2extraprepare_widen) | 132 wrappedextraprepare = extensions.wrappedfunction( |
133 exchange, '_pullbundle2extraprepare', pullbundle2extraprepare_widen | |
134 ) | |
115 | 135 |
116 with wrappedextraprepare: | 136 with wrappedextraprepare: |
117 return orig(ui, repo, *args, **opts) | 137 return orig(ui, repo, *args, **opts) |
138 | |
118 | 139 |
119 def archivenarrowcmd(orig, ui, repo, *args, **opts): | 140 def archivenarrowcmd(orig, ui, repo, *args, **opts): |
120 """Wraps archive command to narrow the default includes.""" | 141 """Wraps archive command to narrow the default includes.""" |
121 if repository.NARROW_REQUIREMENT in repo.requirements: | 142 if repository.NARROW_REQUIREMENT in repo.requirements: |
122 repo_includes, repo_excludes = repo.narrowpats | 143 repo_includes, repo_excludes = repo.narrowpats |
123 includes = set(opts.get(r'include', [])) | 144 includes = set(opts.get(r'include', [])) |
124 excludes = set(opts.get(r'exclude', [])) | 145 excludes = set(opts.get(r'exclude', [])) |
125 includes, excludes, unused_invalid = narrowspec.restrictpatterns( | 146 includes, excludes, unused_invalid = narrowspec.restrictpatterns( |
126 includes, excludes, repo_includes, repo_excludes) | 147 includes, excludes, repo_includes, repo_excludes |
148 ) | |
127 if includes: | 149 if includes: |
128 opts[r'include'] = includes | 150 opts[r'include'] = includes |
129 if excludes: | 151 if excludes: |
130 opts[r'exclude'] = excludes | 152 opts[r'exclude'] = excludes |
131 return orig(ui, repo, *args, **opts) | 153 return orig(ui, repo, *args, **opts) |
154 | |
132 | 155 |
133 def pullbundle2extraprepare(orig, pullop, kwargs): | 156 def pullbundle2extraprepare(orig, pullop, kwargs): |
134 repo = pullop.repo | 157 repo = pullop.repo |
135 if repository.NARROW_REQUIREMENT not in repo.requirements: | 158 if repository.NARROW_REQUIREMENT not in repo.requirements: |
136 return orig(pullop, kwargs) | 159 return orig(pullop, kwargs) |
147 if exclude: | 170 if exclude: |
148 kwargs['excludepats'] = exclude | 171 kwargs['excludepats'] = exclude |
149 # calculate known nodes only in ellipses cases because in non-ellipses cases | 172 # calculate known nodes only in ellipses cases because in non-ellipses cases |
150 # we have all the nodes | 173 # we have all the nodes |
151 if wireprototypes.ELLIPSESCAP1 in pullop.remote.capabilities(): | 174 if wireprototypes.ELLIPSESCAP1 in pullop.remote.capabilities(): |
152 kwargs['known'] = [node.hex(ctx.node()) for ctx in | 175 kwargs['known'] = [ |
153 repo.set('::%ln', pullop.common) | 176 node.hex(ctx.node()) |
154 if ctx.node() != node.nullid] | 177 for ctx in repo.set('::%ln', pullop.common) |
178 if ctx.node() != node.nullid | |
179 ] | |
155 if not kwargs['known']: | 180 if not kwargs['known']: |
156 # Mercurial serializes an empty list as '' and deserializes it as | 181 # Mercurial serializes an empty list as '' and deserializes it as |
157 # [''], so delete it instead to avoid handling the empty string on | 182 # [''], so delete it instead to avoid handling the empty string on |
158 # the server. | 183 # the server. |
159 del kwargs['known'] | 184 del kwargs['known'] |
160 | 185 |
161 extensions.wrapfunction(exchange,'_pullbundle2extraprepare', | 186 |
162 pullbundle2extraprepare) | 187 extensions.wrapfunction( |
163 | 188 exchange, '_pullbundle2extraprepare', pullbundle2extraprepare |
164 def _narrow(ui, repo, remote, commoninc, oldincludes, oldexcludes, | 189 ) |
165 newincludes, newexcludes, force): | 190 |
191 | |
192 def _narrow( | |
193 ui, | |
194 repo, | |
195 remote, | |
196 commoninc, | |
197 oldincludes, | |
198 oldexcludes, | |
199 newincludes, | |
200 newexcludes, | |
201 force, | |
202 ): | |
166 oldmatch = narrowspec.match(repo.root, oldincludes, oldexcludes) | 203 oldmatch = narrowspec.match(repo.root, oldincludes, oldexcludes) |
167 newmatch = narrowspec.match(repo.root, newincludes, newexcludes) | 204 newmatch = narrowspec.match(repo.root, newincludes, newexcludes) |
168 | 205 |
169 # This is essentially doing "hg outgoing" to find all local-only | 206 # This is essentially doing "hg outgoing" to find all local-only |
170 # commits. We will then check that the local-only commits don't | 207 # commits. We will then check that the local-only commits don't |
171 # have any changes to files that will be untracked. | 208 # have any changes to files that will be untracked. |
172 unfi = repo.unfiltered() | 209 unfi = repo.unfiltered() |
173 outgoing = discovery.findcommonoutgoing(unfi, remote, | 210 outgoing = discovery.findcommonoutgoing(unfi, remote, commoninc=commoninc) |
174 commoninc=commoninc) | |
175 ui.status(_('looking for local changes to affected paths\n')) | 211 ui.status(_('looking for local changes to affected paths\n')) |
176 localnodes = [] | 212 localnodes = [] |
177 for n in itertools.chain(outgoing.missing, outgoing.excluded): | 213 for n in itertools.chain(outgoing.missing, outgoing.excluded): |
178 if any(oldmatch(f) and not newmatch(f) for f in unfi[n].files()): | 214 if any(oldmatch(f) and not newmatch(f) for f in unfi[n].files()): |
179 localnodes.append(n) | 215 localnodes.append(n) |
180 revstostrip = unfi.revs('descendants(%ln)', localnodes) | 216 revstostrip = unfi.revs('descendants(%ln)', localnodes) |
181 hiddenrevs = repoview.filterrevs(repo, 'visible') | 217 hiddenrevs = repoview.filterrevs(repo, 'visible') |
182 visibletostrip = list(repo.changelog.node(r) | 218 visibletostrip = list( |
183 for r in (revstostrip - hiddenrevs)) | 219 repo.changelog.node(r) for r in (revstostrip - hiddenrevs) |
220 ) | |
184 if visibletostrip: | 221 if visibletostrip: |
185 ui.status(_('The following changeset(s) or their ancestors have ' | 222 ui.status( |
186 'local changes not on the remote:\n')) | 223 _( |
224 'The following changeset(s) or their ancestors have ' | |
225 'local changes not on the remote:\n' | |
226 ) | |
227 ) | |
187 maxnodes = 10 | 228 maxnodes = 10 |
188 if ui.verbose or len(visibletostrip) <= maxnodes: | 229 if ui.verbose or len(visibletostrip) <= maxnodes: |
189 for n in visibletostrip: | 230 for n in visibletostrip: |
190 ui.status('%s\n' % node.short(n)) | 231 ui.status('%s\n' % node.short(n)) |
191 else: | 232 else: |
192 for n in visibletostrip[:maxnodes]: | 233 for n in visibletostrip[:maxnodes]: |
193 ui.status('%s\n' % node.short(n)) | 234 ui.status('%s\n' % node.short(n)) |
194 ui.status(_('...and %d more, use --verbose to list all\n') % | 235 ui.status( |
195 (len(visibletostrip) - maxnodes)) | 236 _('...and %d more, use --verbose to list all\n') |
237 % (len(visibletostrip) - maxnodes) | |
238 ) | |
196 if not force: | 239 if not force: |
197 raise error.Abort(_('local changes found'), | 240 raise error.Abort( |
198 hint=_('use --force-delete-local-changes to ' | 241 _('local changes found'), |
199 'ignore')) | 242 hint=_('use --force-delete-local-changes to ' 'ignore'), |
243 ) | |
200 | 244 |
201 with ui.uninterruptible(): | 245 with ui.uninterruptible(): |
202 if revstostrip: | 246 if revstostrip: |
203 tostrip = [unfi.changelog.node(r) for r in revstostrip] | 247 tostrip = [unfi.changelog.node(r) for r in revstostrip] |
204 if repo['.'].node() in tostrip: | 248 if repo['.'].node() in tostrip: |
205 # stripping working copy, so move to a different commit first | 249 # stripping working copy, so move to a different commit first |
206 urev = max(repo.revs('(::%n) - %ln + null', | 250 urev = max( |
207 repo['.'].node(), visibletostrip)) | 251 repo.revs( |
252 '(::%n) - %ln + null', repo['.'].node(), visibletostrip | |
253 ) | |
254 ) | |
208 hg.clean(repo, urev) | 255 hg.clean(repo, urev) |
209 overrides = {('devel', 'strip-obsmarkers'): False} | 256 overrides = {('devel', 'strip-obsmarkers'): False} |
210 with ui.configoverride(overrides, 'narrow'): | 257 with ui.configoverride(overrides, 'narrow'): |
211 repair.strip(ui, unfi, tostrip, topic='narrow') | 258 repair.strip(ui, unfi, tostrip, topic='narrow') |
212 | 259 |
245 narrowspec.updateworkingcopy(repo, assumeclean=True) | 292 narrowspec.updateworkingcopy(repo, assumeclean=True) |
246 narrowspec.copytoworkingcopy(repo) | 293 narrowspec.copytoworkingcopy(repo) |
247 | 294 |
248 repo.destroyed() | 295 repo.destroyed() |
249 | 296 |
250 def _widen(ui, repo, remote, commoninc, oldincludes, oldexcludes, | 297 |
251 newincludes, newexcludes): | 298 def _widen( |
299 ui, | |
300 repo, | |
301 remote, | |
302 commoninc, | |
303 oldincludes, | |
304 oldexcludes, | |
305 newincludes, | |
306 newexcludes, | |
307 ): | |
252 # for now we assume that if a server has ellipses enabled, we will be | 308 # for now we assume that if a server has ellipses enabled, we will be |
253 # exchanging ellipses nodes. In future we should add ellipses as a client | 309 # exchanging ellipses nodes. In future we should add ellipses as a client |
254 # side requirement (maybe) to distinguish a client is shallow or not and | 310 # side requirement (maybe) to distinguish a client is shallow or not and |
255 # then send that information to server whether we want ellipses or not. | 311 # then send that information to server whether we want ellipses or not. |
256 # Theoretically a non-ellipses repo should be able to use narrow | 312 # Theoretically a non-ellipses repo should be able to use narrow |
257 # functionality from an ellipses enabled server | 313 # functionality from an ellipses enabled server |
258 remotecap = remote.capabilities() | 314 remotecap = remote.capabilities() |
259 ellipsesremote = any(cap in remotecap | 315 ellipsesremote = any( |
260 for cap in wireprototypes.SUPPORTED_ELLIPSESCAP) | 316 cap in remotecap for cap in wireprototypes.SUPPORTED_ELLIPSESCAP |
317 ) | |
261 | 318 |
262 # check whether we are talking to a server which supports old version of | 319 # check whether we are talking to a server which supports old version of |
263 # ellipses capabilities | 320 # ellipses capabilities |
264 isoldellipses = (ellipsesremote and wireprototypes.ELLIPSESCAP1 in | 321 isoldellipses = ( |
265 remotecap and wireprototypes.ELLIPSESCAP not in remotecap) | 322 ellipsesremote |
323 and wireprototypes.ELLIPSESCAP1 in remotecap | |
324 and wireprototypes.ELLIPSESCAP not in remotecap | |
325 ) | |
266 | 326 |
267 def pullbundle2extraprepare_widen(orig, pullop, kwargs): | 327 def pullbundle2extraprepare_widen(orig, pullop, kwargs): |
268 orig(pullop, kwargs) | 328 orig(pullop, kwargs) |
269 # The old{in,ex}cludepats have already been set by orig() | 329 # The old{in,ex}cludepats have already been set by orig() |
270 kwargs['includepats'] = newincludes | 330 kwargs['includepats'] = newincludes |
271 kwargs['excludepats'] = newexcludes | 331 kwargs['excludepats'] = newexcludes |
272 wrappedextraprepare = extensions.wrappedfunction(exchange, | 332 |
273 '_pullbundle2extraprepare', pullbundle2extraprepare_widen) | 333 wrappedextraprepare = extensions.wrappedfunction( |
334 exchange, '_pullbundle2extraprepare', pullbundle2extraprepare_widen | |
335 ) | |
274 | 336 |
275 # define a function that narrowbundle2 can call after creating the | 337 # define a function that narrowbundle2 can call after creating the |
276 # backup bundle, but before applying the bundle from the server | 338 # backup bundle, but before applying the bundle from the server |
277 def setnewnarrowpats(): | 339 def setnewnarrowpats(): |
278 repo.setnarrowpats(newincludes, newexcludes) | 340 repo.setnarrowpats(newincludes, newexcludes) |
341 | |
279 repo.setnewnarrowpats = setnewnarrowpats | 342 repo.setnewnarrowpats = setnewnarrowpats |
280 # silence the devel-warning of applying an empty changegroup | 343 # silence the devel-warning of applying an empty changegroup |
281 overrides = {('devel', 'all-warnings'): False} | 344 overrides = {('devel', 'all-warnings'): False} |
282 | 345 |
283 common = commoninc[0] | 346 common = commoninc[0] |
291 with wrappedextraprepare: | 354 with wrappedextraprepare: |
292 exchange.pull(repo, remote, heads=common) | 355 exchange.pull(repo, remote, heads=common) |
293 else: | 356 else: |
294 known = [] | 357 known = [] |
295 if ellipsesremote: | 358 if ellipsesremote: |
296 known = [ctx.node() for ctx in | 359 known = [ |
297 repo.set('::%ln', common) | 360 ctx.node() |
298 if ctx.node() != node.nullid] | 361 for ctx in repo.set('::%ln', common) |
362 if ctx.node() != node.nullid | |
363 ] | |
299 with remote.commandexecutor() as e: | 364 with remote.commandexecutor() as e: |
300 bundle = e.callcommand('narrow_widen', { | 365 bundle = e.callcommand( |
301 'oldincludes': oldincludes, | 366 'narrow_widen', |
302 'oldexcludes': oldexcludes, | 367 { |
303 'newincludes': newincludes, | 368 'oldincludes': oldincludes, |
304 'newexcludes': newexcludes, | 369 'oldexcludes': oldexcludes, |
305 'cgversion': '03', | 370 'newincludes': newincludes, |
306 'commonheads': common, | 371 'newexcludes': newexcludes, |
307 'known': known, | 372 'cgversion': '03', |
308 'ellipses': ellipsesremote, | 373 'commonheads': common, |
309 }).result() | 374 'known': known, |
375 'ellipses': ellipsesremote, | |
376 }, | |
377 ).result() | |
310 | 378 |
311 trmanager = exchange.transactionmanager(repo, 'widen', remote.url()) | 379 trmanager = exchange.transactionmanager(repo, 'widen', remote.url()) |
312 with trmanager, repo.ui.configoverride(overrides, 'widen'): | 380 with trmanager, repo.ui.configoverride(overrides, 'widen'): |
313 op = bundle2.bundleoperation(repo, trmanager.transaction, | 381 op = bundle2.bundleoperation( |
314 source='widen') | 382 repo, trmanager.transaction, source='widen' |
383 ) | |
315 # TODO: we should catch error.Abort here | 384 # TODO: we should catch error.Abort here |
316 bundle2.processbundle(repo, bundle, op=op) | 385 bundle2.processbundle(repo, bundle, op=op) |
317 | 386 |
318 if ellipsesremote: | 387 if ellipsesremote: |
319 with ds.parentchange(): | 388 with ds.parentchange(): |
322 with repo.transaction('widening'): | 391 with repo.transaction('widening'): |
323 repo.setnewnarrowpats() | 392 repo.setnewnarrowpats() |
324 narrowspec.updateworkingcopy(repo) | 393 narrowspec.updateworkingcopy(repo) |
325 narrowspec.copytoworkingcopy(repo) | 394 narrowspec.copytoworkingcopy(repo) |
326 | 395 |
396 | |
327 # TODO(rdamazio): Make new matcher format and update description | 397 # TODO(rdamazio): Make new matcher format and update description |
328 @command('tracked', | 398 @command( |
329 [('', 'addinclude', [], _('new paths to include')), | 399 'tracked', |
330 ('', 'removeinclude', [], _('old paths to no longer include')), | 400 [ |
331 ('', 'auto-remove-includes', False, | 401 ('', 'addinclude', [], _('new paths to include')), |
332 _('automatically choose unused includes to remove')), | 402 ('', 'removeinclude', [], _('old paths to no longer include')), |
333 ('', 'addexclude', [], _('new paths to exclude')), | 403 ( |
334 ('', 'import-rules', '', _('import narrowspecs from a file')), | 404 '', |
335 ('', 'removeexclude', [], _('old paths to no longer exclude')), | 405 'auto-remove-includes', |
336 ('', 'clear', False, _('whether to replace the existing narrowspec')), | 406 False, |
337 ('', 'force-delete-local-changes', False, | 407 _('automatically choose unused includes to remove'), |
338 _('forces deletion of local changes when narrowing')), | 408 ), |
339 ('', 'update-working-copy', False, | 409 ('', 'addexclude', [], _('new paths to exclude')), |
340 _('update working copy when the store has changed')), | 410 ('', 'import-rules', '', _('import narrowspecs from a file')), |
341 ] + commands.remoteopts, | 411 ('', 'removeexclude', [], _('old paths to no longer exclude')), |
412 ('', 'clear', False, _('whether to replace the existing narrowspec')), | |
413 ( | |
414 '', | |
415 'force-delete-local-changes', | |
416 False, | |
417 _('forces deletion of local changes when narrowing'), | |
418 ), | |
419 ( | |
420 '', | |
421 'update-working-copy', | |
422 False, | |
423 _('update working copy when the store has changed'), | |
424 ), | |
425 ] | |
426 + commands.remoteopts, | |
342 _('[OPTIONS]... [REMOTE]'), | 427 _('[OPTIONS]... [REMOTE]'), |
343 inferrepo=True) | 428 inferrepo=True, |
429 ) | |
344 def trackedcmd(ui, repo, remotepath=None, *pats, **opts): | 430 def trackedcmd(ui, repo, remotepath=None, *pats, **opts): |
345 """show or change the current narrowspec | 431 """show or change the current narrowspec |
346 | 432 |
347 With no argument, shows the current narrowspec entries, one per line. Each | 433 With no argument, shows the current narrowspec entries, one per line. Each |
348 line will be prefixed with 'I' or 'X' for included or excluded patterns, | 434 line will be prefixed with 'I' or 'X' for included or excluded patterns, |
374 add --addinclude, --addexclude rules in bulk. Like the other include and | 460 add --addinclude, --addexclude rules in bulk. Like the other include and |
375 exclude switches, the changes are applied immediately. | 461 exclude switches, the changes are applied immediately. |
376 """ | 462 """ |
377 opts = pycompat.byteskwargs(opts) | 463 opts = pycompat.byteskwargs(opts) |
378 if repository.NARROW_REQUIREMENT not in repo.requirements: | 464 if repository.NARROW_REQUIREMENT not in repo.requirements: |
379 raise error.Abort(_('the tracked command is only supported on ' | 465 raise error.Abort( |
380 'repositories cloned with --narrow')) | 466 _( |
467 'the tracked command is only supported on ' | |
468 'repositories cloned with --narrow' | |
469 ) | |
470 ) | |
381 | 471 |
382 # Before supporting, decide whether it "hg tracked --clear" should mean | 472 # Before supporting, decide whether it "hg tracked --clear" should mean |
383 # tracking no paths or all paths. | 473 # tracking no paths or all paths. |
384 if opts['clear']: | 474 if opts['clear']: |
385 raise error.Abort(_('the --clear option is not yet supported')) | 475 raise error.Abort(_('the --clear option is not yet supported')) |
389 if newrules: | 479 if newrules: |
390 try: | 480 try: |
391 filepath = os.path.join(encoding.getcwd(), newrules) | 481 filepath = os.path.join(encoding.getcwd(), newrules) |
392 fdata = util.readfile(filepath) | 482 fdata = util.readfile(filepath) |
393 except IOError as inst: | 483 except IOError as inst: |
394 raise error.Abort(_("cannot read narrowspecs from '%s': %s") % | 484 raise error.Abort( |
395 (filepath, encoding.strtolocal(inst.strerror))) | 485 _("cannot read narrowspecs from '%s': %s") |
396 includepats, excludepats, profiles = sparse.parseconfig(ui, fdata, | 486 % (filepath, encoding.strtolocal(inst.strerror)) |
397 'narrow') | 487 ) |
488 includepats, excludepats, profiles = sparse.parseconfig( | |
489 ui, fdata, 'narrow' | |
490 ) | |
398 if profiles: | 491 if profiles: |
399 raise error.Abort(_("including other spec files using '%include' " | 492 raise error.Abort( |
400 "is not supported in narrowspec")) | 493 _( |
494 "including other spec files using '%include' " | |
495 "is not supported in narrowspec" | |
496 ) | |
497 ) | |
401 opts['addinclude'].extend(includepats) | 498 opts['addinclude'].extend(includepats) |
402 opts['addexclude'].extend(excludepats) | 499 opts['addexclude'].extend(excludepats) |
403 | 500 |
404 addedincludes = narrowspec.parsepatterns(opts['addinclude']) | 501 addedincludes = narrowspec.parsepatterns(opts['addinclude']) |
405 removedincludes = narrowspec.parsepatterns(opts['removeinclude']) | 502 removedincludes = narrowspec.parsepatterns(opts['removeinclude']) |
406 addedexcludes = narrowspec.parsepatterns(opts['addexclude']) | 503 addedexcludes = narrowspec.parsepatterns(opts['addexclude']) |
407 removedexcludes = narrowspec.parsepatterns(opts['removeexclude']) | 504 removedexcludes = narrowspec.parsepatterns(opts['removeexclude']) |
408 autoremoveincludes = opts['auto_remove_includes'] | 505 autoremoveincludes = opts['auto_remove_includes'] |
409 | 506 |
410 update_working_copy = opts['update_working_copy'] | 507 update_working_copy = opts['update_working_copy'] |
411 only_show = not (addedincludes or removedincludes or addedexcludes or | 508 only_show = not ( |
412 removedexcludes or newrules or autoremoveincludes or | 509 addedincludes |
413 update_working_copy) | 510 or removedincludes |
511 or addedexcludes | |
512 or removedexcludes | |
513 or newrules | |
514 or autoremoveincludes | |
515 or update_working_copy | |
516 ) | |
414 | 517 |
415 oldincludes, oldexcludes = repo.narrowpats | 518 oldincludes, oldexcludes = repo.narrowpats |
416 | 519 |
417 # filter the user passed additions and deletions into actual additions and | 520 # filter the user passed additions and deletions into actual additions and |
418 # deletions of excludes and includes | 521 # deletions of excludes and includes |
467 raise error.Abort(_("server does not support narrow clones")) | 570 raise error.Abort(_("server does not support narrow clones")) |
468 | 571 |
469 commoninc = discovery.findcommonincoming(repo, remote) | 572 commoninc = discovery.findcommonincoming(repo, remote) |
470 | 573 |
471 if autoremoveincludes: | 574 if autoremoveincludes: |
472 outgoing = discovery.findcommonoutgoing(repo, remote, | 575 outgoing = discovery.findcommonoutgoing( |
473 commoninc=commoninc) | 576 repo, remote, commoninc=commoninc |
577 ) | |
474 ui.status(_('looking for unused includes to remove\n')) | 578 ui.status(_('looking for unused includes to remove\n')) |
475 localfiles = set() | 579 localfiles = set() |
476 for n in itertools.chain(outgoing.missing, outgoing.excluded): | 580 for n in itertools.chain(outgoing.missing, outgoing.excluded): |
477 localfiles.update(repo[n].files()) | 581 localfiles.update(repo[n].files()) |
478 suggestedremovals = [] | 582 suggestedremovals = [] |
481 if not any(match(f) for f in localfiles): | 585 if not any(match(f) for f in localfiles): |
482 suggestedremovals.append(include) | 586 suggestedremovals.append(include) |
483 if suggestedremovals: | 587 if suggestedremovals: |
484 for s in suggestedremovals: | 588 for s in suggestedremovals: |
485 ui.status('%s\n' % s) | 589 ui.status('%s\n' % s) |
486 if (ui.promptchoice(_('remove these unused includes (yn)?' | 590 if ( |
487 '$$ &Yes $$ &No')) == 0): | 591 ui.promptchoice( |
592 _('remove these unused includes (yn)?' '$$ &Yes $$ &No') | |
593 ) | |
594 == 0 | |
595 ): | |
488 removedincludes.update(suggestedremovals) | 596 removedincludes.update(suggestedremovals) |
489 narrowing = True | 597 narrowing = True |
490 else: | 598 else: |
491 ui.status(_('found no unused includes\n')) | 599 ui.status(_('found no unused includes\n')) |
492 | 600 |
493 if narrowing: | 601 if narrowing: |
494 newincludes = oldincludes - removedincludes | 602 newincludes = oldincludes - removedincludes |
495 newexcludes = oldexcludes | addedexcludes | 603 newexcludes = oldexcludes | addedexcludes |
496 _narrow(ui, repo, remote, commoninc, oldincludes, oldexcludes, | 604 _narrow( |
497 newincludes, newexcludes, | 605 ui, |
498 opts['force_delete_local_changes']) | 606 repo, |
607 remote, | |
608 commoninc, | |
609 oldincludes, | |
610 oldexcludes, | |
611 newincludes, | |
612 newexcludes, | |
613 opts['force_delete_local_changes'], | |
614 ) | |
499 # _narrow() updated the narrowspec and _widen() below needs to | 615 # _narrow() updated the narrowspec and _widen() below needs to |
500 # use the updated values as its base (otherwise removed includes | 616 # use the updated values as its base (otherwise removed includes |
501 # and addedexcludes will be lost in the resulting narrowspec) | 617 # and addedexcludes will be lost in the resulting narrowspec) |
502 oldincludes = newincludes | 618 oldincludes = newincludes |
503 oldexcludes = newexcludes | 619 oldexcludes = newexcludes |
504 | 620 |
505 if widening: | 621 if widening: |
506 newincludes = oldincludes | addedincludes | 622 newincludes = oldincludes | addedincludes |
507 newexcludes = oldexcludes - removedexcludes | 623 newexcludes = oldexcludes - removedexcludes |
508 _widen(ui, repo, remote, commoninc, oldincludes, oldexcludes, | 624 _widen( |
509 newincludes, newexcludes) | 625 ui, |
626 repo, | |
627 remote, | |
628 commoninc, | |
629 oldincludes, | |
630 oldexcludes, | |
631 newincludes, | |
632 newexcludes, | |
633 ) | |
510 | 634 |
511 return 0 | 635 return 0 |