mercurial/pushkey.py
author Martin von Zweigbergk <martinvonz@google.com>
Tue, 26 Jun 2018 10:02:01 -0700
changeset 38490 4c0683655599
parent 25969 7b200566e474
child 43075 57875cf423c9
permissions -rw-r--r--
namespaces: let namespaces override singlenode() definition Some namespaces have multiple nodes per name (meaning that their namemap() returns multiple nodes). One such namespace is the "topics" namespace (from the evolve repo). We also have our own internal namespace at Google (for review units) that has multiple nodes per name. These namespaces may not want to use the default "pick highest revnum" resolution that we currently use when resolving a name to a single node. As an example, they may decide that `hg co <name>` should check out a commit that's last in some sense even if an earlier commit had just been amended and thus had a higher revnum [1]. This patch gives the namespace the option to continue to return multiple nodes and to override how the best node is picked. Allowing namespaces to override that may also be useful as an optimization (it may be cheaper for the namespace to find just that node). I have been arguing (in D3715) for using all the nodes returned from namemap() when resolving the symbol to a revset, so e.g. `hg log -r stable` would resolve to *all* nodes on stable, not just the one with the highest revnum (except that I don't actually think we should change it for the branch namespace because of BC). Most people seem opposed to that. If we decide not to do it, I think we can deprecate the namemap() function in favor of the new singlenode() (I find it weird to have namespaces, like the branch namespace, where namemap() isn't nodemap()'s inverse). I therefore think this patch makes sense regardless of what we decide on that issue. [1] Actually, even the branch namespace would have wanted to override singlenode() if it had supported multiple nodes. That's because closes branch heads are mostly ignored, so "hg co default" will not check out the highest-revnum node if that's a closed head. Differential Revision: https://phab.mercurial-scm.org/D3852
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11367
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# pushkey.py - dispatching for pushing and pulling keys
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2010 Matt Mackall <mpm@selenic.com>
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
25969
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
     8
from __future__ import absolute_import
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
     9
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
    10
from . import (
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
    11
    bookmarks,
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
    12
    encoding,
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
    13
    obsolete,
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
    14
    phases,
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
    15
)
13353
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 11367
diff changeset
    16
11367
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
def _nslist(repo):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
    n = {}
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
    for k in _namespaces:
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
        n[k] = ""
22953
b1d694d3975e obsolete: add exchange option
Durham Goode <durham@fb.com>
parents: 21661
diff changeset
    21
    if not obsolete.isenabled(repo, obsolete.exchangeopt):
17298
59c14bf5a48c pushkey: do not exchange obsole markers if feature is disabled
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17075
diff changeset
    22
        n.pop('obsolete')
11367
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
    return n
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
13353
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 11367
diff changeset
    25
_namespaces = {"namespaces": (lambda *x: False, _nslist),
15648
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 13353
diff changeset
    26
               "bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks),
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 13353
diff changeset
    27
               "phases": (phases.pushphase, phases.listphases),
17075
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 15648
diff changeset
    28
               "obsolete": (obsolete.pushmarker, obsolete.listmarkers),
15648
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 13353
diff changeset
    29
              }
11367
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    31
def register(namespace, pushkey, listkeys):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
    _namespaces[namespace] = (pushkey, listkeys)
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    33
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
def _get(namespace):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
    return _namespaces.get(namespace, (lambda *x: False, lambda *x: {}))
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
def push(repo, namespace, key, old, new):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
    '''should succeed iff value was old'''
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    39
    pk = _get(namespace)[0]
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    40
    return pk(repo, key, old, new)
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    41
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
def list(repo, namespace):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
    '''return a dict'''
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    44
    lk = _get(namespace)[1]
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
    return lk(repo)
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
21661
2f52a16f2bee pushkey: add an ``encode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21659
diff changeset
    47
encode = encoding.fromlocal
2f52a16f2bee pushkey: add an ``encode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21659
diff changeset
    48
21659
a319842539f5 pushkey: add a ``decode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21652
diff changeset
    49
decode = encoding.tolocal
a319842539f5 pushkey: add a ``decode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21652
diff changeset
    50
21650
a2c7ae21e8f4 pushkey: introduce an ``encodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 17298
diff changeset
    51
def encodekeys(keys):
a2c7ae21e8f4 pushkey: introduce an ``encodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 17298
diff changeset
    52
    """encode the content of a pushkey namespace for exchange over the wire"""
21661
2f52a16f2bee pushkey: add an ``encode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21659
diff changeset
    53
    return '\n'.join(['%s\t%s' % (encode(k), encode(v)) for k, v in keys])
21652
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    54
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    55
def decodekeys(data):
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    56
    """decode the content of a pushkey namespace from exchange over the wire"""
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    57
    result = {}
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    58
    for l in data.splitlines():
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    59
        k, v = l.split('\t')
21659
a319842539f5 pushkey: add a ``decode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21652
diff changeset
    60
        result[decode(k)] = decode(v)
21652
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    61
    return result