comparison mercurial/context.py @ 37852:8b86acc7aa64

context: drop support for looking up context by ambiguous changeid (API) This removes support for using the changectx constructor (and thereby repo[x]) for looking up contexts by a stringified int, a namespace key (e.g. a bookmark), or a partial hex nodeid. This means that e.g. repo[<hex nodeid>] will now fail even if a bookmark with the same name exists (which is a good thing IMO). It also means that doing repo[<non-existent node>] no longer ends up loading namespaces (which was a surprising side-effect of creating of failing to create a context object that I recently ran into while debugging something unrelated to this series). Differential Revision: https://phab.mercurial-scm.org/D3449
author Martin von Zweigbergk <martinvonz@google.com>
date Sat, 28 Apr 2018 23:16:41 -0700
parents 43221a57e22f
children fdd8da79eb85
comparison
equal deleted inserted replaced
37851:8327fd79adf8 37852:8b86acc7aa64
22 nullid, 22 nullid,
23 nullrev, 23 nullrev,
24 short, 24 short,
25 wdirfilenodeids, 25 wdirfilenodeids,
26 wdirid, 26 wdirid,
27 wdirrev,
28 ) 27 )
29 from . import ( 28 from . import (
30 dagop, 29 dagop,
31 encoding, 30 encoding,
32 error, 31 error,
375 for l in r: 374 for l in r:
376 l.sort() 375 l.sort()
377 376
378 return r 377 return r
379 378
380 def changectxdeprecwarn(repo):
381 # changectx's constructor will soon lose support for these forms of
382 # changeids:
383 # * stringinfied ints
384 # * bookmarks, tags, branches, and other namespace identifiers
385 # * hex nodeid prefixes
386 #
387 # Depending on your use case, replace repo[x] by one of these:
388 # * If you want to support general revsets, use scmutil.revsingle(x)
389 # * If you know that "x" is a stringified int, use repo[int(x)]
390 # * If you know that "x" is a bookmark, use repo._bookmarks.changectx(x)
391 # * If you know that "x" is a tag, use repo[repo.tags()[x]]
392 # * If you know that "x" is a branch or in some other namespace,
393 # use the appropriate mechanism for that namespace
394 # * If you know that "x" is a hex nodeid prefix, use
395 # repo[scmutil.resolvehexnodeidprefix(repo, x)]
396 # * If "x" is a string that can be any of the above, but you don't want
397 # to allow general revsets (perhaps because "x" may come from a remote
398 # user and the revset may be too costly), use scmutil.revsymbol(repo, x)
399 # * If "x" can be a mix of the above, you'll have to figure it out
400 # yourself
401 repo.ui.deprecwarn("changectx.__init__ is getting more limited, see "
402 "context.changectxdeprecwarn() for details", "4.6",
403 stacklevel=4)
404
405 class changectx(basectx): 379 class changectx(basectx):
406 """A changecontext object makes access to data related to a particular 380 """A changecontext object makes access to data related to a particular
407 changeset convenient. It represents a read-only context already present in 381 changeset convenient. It represents a read-only context already present in
408 the repo.""" 382 the repo."""
409 def __init__(self, repo, changeid='.'): 383 def __init__(self, repo, changeid='.'):
438 except error.FilteredLookupError: 412 except error.FilteredLookupError:
439 raise 413 raise
440 except LookupError: 414 except LookupError:
441 pass 415 pass
442 416
443 try:
444 r = int(changeid)
445 if '%d' % r != changeid:
446 raise ValueError
447 l = len(repo.changelog)
448 if r < 0:
449 r += l
450 if r < 0 or r >= l and r != wdirrev:
451 raise ValueError
452 self._rev = r
453 self._node = repo.changelog.node(r)
454 changectxdeprecwarn(repo)
455 return
456 except error.FilteredIndexError:
457 raise
458 except (ValueError, OverflowError, IndexError):
459 pass
460
461 if len(changeid) == 40: 417 if len(changeid) == 40:
462 try: 418 try:
463 self._node = bin(changeid) 419 self._node = bin(changeid)
464 self._rev = repo.changelog.rev(self._node) 420 self._rev = repo.changelog.rev(self._node)
465 return 421 return
466 except error.FilteredLookupError: 422 except error.FilteredLookupError:
467 raise 423 raise
468 except (TypeError, LookupError): 424 except (TypeError, LookupError):
469 pass 425 pass
470
471 # lookup bookmarks through the name interface
472 try:
473 self._node = repo.names.singlenode(repo, changeid)
474 self._rev = repo.changelog.rev(self._node)
475 changectxdeprecwarn(repo)
476 return
477 except KeyError:
478 pass
479
480 self._node = scmutil.resolvehexnodeidprefix(repo, changeid)
481 if self._node is not None:
482 self._rev = repo.changelog.rev(self._node)
483 changectxdeprecwarn(repo)
484 return
485 426
486 # lookup failed 427 # lookup failed
487 # check if it might have come from damaged dirstate 428 # check if it might have come from damaged dirstate
488 # 429 #
489 # XXX we could avoid the unfiltered if we had a recognizable 430 # XXX we could avoid the unfiltered if we had a recognizable