Mercurial > hg
view mercurial/dirstateguard.py @ 37271:0194dac77c93
scmutil: add method for looking up a context given a revision symbol
changectx's constructor currently supports a mix if inputs:
* integer revnums
* binary nodeids
* '.', 'tip', 'null'
* stringified revnums
* namespaced identifiers (e.g. bookmarks and tags)
* hex nodeids
* partial hex nodeids
The first two are always internal [1]. The other five can be specified
by the user. The third type ('.', 'tip', 'null') often comes from
either the user or internal callers. We probably have some internal
callers that pass hex nodeids too, perhaps even partial ones
(histedit?). There are only a few callers that pass user-supplied
strings: revsets.stringset, peer.lookup, webutil.changeidctx, and
maybe one or two more.
Supporting this mix of things in the constructor is convenient, but a
bit strange, IMO. For example, if repo[node] is given a node that's
not in the repo, it will first check if it's bookmark etc before
raising an exception. Of course, the risk of it being a bookmark is
extremely small, but it just feels ugly.
Also, a problem with having this code in the constructor (whether it
supports a mix of types or not) is that it's harder to override (I'd
like to override it, and that's how this series started).
This patch starts moving out the handling of user-supplied strings by
introducing scmutil.revsymbol(). So far, that just checks that the
input is indeed a string, and then delegates to repo[symbol]. The
patch also calls it from revsets.stringset to prove that it works.
[1] Well, you probably can enter a 20-byte binary nodeid on the
command line, but I don't think we should care to preserve
support for that.
Differential Revision: https://phab.mercurial-scm.org/D3024
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Mon, 02 Apr 2018 16:18:33 -0700 |
parents | bbbbd3c30bfc |
children | ad24b581e4d9 |
line wrap: on
line source
# dirstateguard.py - class to allow restoring dirstate after failure # # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import absolute_import from .i18n import _ from . import ( error, util, ) class dirstateguard(util.transactional): '''Restore dirstate at unexpected failure. At the construction, this class does: - write current ``repo.dirstate`` out, and - save ``.hg/dirstate`` into the backup file This restores ``.hg/dirstate`` from backup file, if ``release()`` is invoked before ``close()``. This just removes the backup file at ``close()`` before ``release()``. ''' def __init__(self, repo, name): self._repo = repo self._active = False self._closed = False self._backupname = 'dirstate.backup.%s.%d' % (name, id(self)) repo.dirstate.savebackup(repo.currenttransaction(), self._backupname) self._active = True def __del__(self): if self._active: # still active # this may occur, even if this class is used correctly: # for example, releasing other resources like transaction # may raise exception before ``dirstateguard.release`` in # ``release(tr, ....)``. self._abort() def close(self): if not self._active: # already inactivated msg = (_("can't close already inactivated backup: %s") % self._backupname) raise error.Abort(msg) self._repo.dirstate.clearbackup(self._repo.currenttransaction(), self._backupname) self._active = False self._closed = True def _abort(self): self._repo.dirstate.restorebackup(self._repo.currenttransaction(), self._backupname) self._active = False def release(self): if not self._closed: if not self._active: # already inactivated msg = (_("can't release already inactivated backup: %s") % self._backupname) raise error.Abort(msg) self._abort()