mercurial/tags.py
author Dirkjan Ochtman <dirkjan@ochtman.nl>
Wed, 05 Aug 2009 17:08:28 +0200
changeset 9312 c5f0825c1dbb
parent 9152 4017291c4c48
child 9366 9ff178e7b627
permissions -rw-r--r--
kill trailing whitespace
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
     1
# tags.py - read tag info from local repository
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
     2
#
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
     3
# Copyright 2009 Matt Mackall <mpm@selenic.com>
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
     4
# Copyright 2009 Greg Ward <greg@gerg.ca>
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
     5
#
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
     6
# This software may be used and distributed according to the terms of the
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
     7
# GNU General Public License version 2, incorporated herein by reference.
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
     8
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
     9
# Currently this module only deals with reading and caching tags.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    10
# Eventually, it could take care of updating (adding/removing/moving)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    11
# tags too.
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    12
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    13
import os
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    14
from node import nullid, bin, hex, short
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    15
from i18n import _
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    16
import encoding
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    17
import error
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    18
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    19
def _debugalways(ui, *msg):
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    20
    ui.write(*msg)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    21
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    22
def _debugconditional(ui, *msg):
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    23
    ui.debug(*msg)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    24
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    25
def _debugnever(ui, *msg):
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    26
    pass
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    27
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    28
_debug = _debugalways
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    29
_debug = _debugnever
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    30
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    31
def findglobaltags1(ui, repo, alltags, tagtypes):
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    32
    '''Find global tags in repo by reading .hgtags from every head that
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    33
    has a distinct version of it.  Updates the dicts alltags, tagtypes
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    34
    in place: alltags maps tag name to (node, hist) pair (see _readtags()
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    35
    below), and tagtypes maps tag name to tag type ('global' in this
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    36
    case).'''
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    37
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    38
    seen = set()
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    39
    fctx = None
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    40
    ctxs = []                       # list of filectx
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    41
    for node in repo.heads():
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    42
        try:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    43
            fnode = repo[node].filenode('.hgtags')
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    44
        except error.LookupError:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    45
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    46
        if fnode not in seen:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    47
            seen.add(fnode)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    48
            if not fctx:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    49
                fctx = repo.filectx('.hgtags', fileid=fnode)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    50
            else:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    51
                fctx = fctx.filectx(fnode)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    52
            ctxs.append(fctx)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    53
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    54
    # read the tags file from each head, ending with the tip
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    55
    for fctx in reversed(ctxs):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    56
        filetags = _readtags(
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    57
            ui, repo, fctx.data().splitlines(), fctx)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    58
        _updatetags(filetags, "global", alltags, tagtypes)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    59
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    60
def findglobaltags2(ui, repo, alltags, tagtypes):
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    61
    '''Same as findglobaltags1(), but with caching.'''
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    62
    # This is so we can be lazy and assume alltags contains only global
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    63
    # tags when we pass it to _writetagcache().
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    64
    assert len(alltags) == len(tagtypes) == 0, \
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    65
           "findglobaltags() should be called first"
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    66
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    67
    (heads, tagfnode, cachetags, shouldwrite) = _readtagcache(ui, repo)
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    68
    if cachetags is not None:
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    69
        assert not shouldwrite
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    70
        # XXX is this really 100% correct?  are there oddball special
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    71
        # cases where a global tag should outrank a local tag but won't,
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    72
        # because cachetags does not contain rank info?
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    73
        _updatetags(cachetags, 'global', alltags, tagtypes)
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    74
        return
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    75
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    76
    _debug(ui, "reading tags from %d head(s): %s\n"
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    77
           % (len(heads), map(short, reversed(heads))))
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    78
    seen = set()                    # set of fnode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    79
    fctx = None
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    80
    for head in reversed(heads):        # oldest to newest
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    81
        assert head in repo.changelog.nodemap, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    82
               "tag cache returned bogus head %s" % short(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    83
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    84
        fnode = tagfnode.get(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    85
        if fnode and fnode not in seen:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    86
            seen.add(fnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    87
            if not fctx:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    88
                fctx = repo.filectx('.hgtags', fileid=fnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    89
            else:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    90
                fctx = fctx.filectx(fnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    91
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    92
            filetags = _readtags(ui, repo, fctx.data().splitlines(), fctx)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    93
            _updatetags(filetags, 'global', alltags, tagtypes)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    94
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    95
    # and update the cache (if necessary)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    96
    if shouldwrite:
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    97
        _writetagcache(ui, repo, heads, tagfnode, alltags)
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    98
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    99
# Set this to findglobaltags1 to disable tag caching.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   100
findglobaltags = findglobaltags2
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   101
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   102
def readlocaltags(ui, repo, alltags, tagtypes):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   103
    '''Read local tags in repo.  Update alltags and tagtypes.'''
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   104
    try:
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   105
        # localtags is in the local encoding; re-encode to UTF-8 on
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   106
        # input for consistency with the rest of this module.
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   107
        data = repo.opener("localtags").read()
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   108
        filetags = _readtags(
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   109
            ui, repo, data.splitlines(), "localtags",
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   110
            recode=encoding.fromlocal)
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   111
        _updatetags(filetags, "local", alltags, tagtypes)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   112
    except IOError:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   113
        pass
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   114
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   115
def _readtags(ui, repo, lines, fn, recode=None):
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   116
    '''Read tag definitions from a file (or any source of lines).
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   117
    Return a mapping from tag name to (node, hist): node is the node id
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   118
    from the last line read for that name, and hist is the list of node
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   119
    ids previously associated with it (in file order).  All node ids are
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   120
    binary, not hex.'''
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   121
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   122
    filetags = {}               # map tag name to (node, hist)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   123
    count = 0
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   124
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   125
    def warn(msg):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   126
        ui.warn(_("%s, line %s: %s\n") % (fn, count, msg))
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   127
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   128
    for line in lines:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   129
        count += 1
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   130
        if not line:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   131
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   132
        try:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   133
            (nodehex, name) = line.split(" ", 1)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   134
        except ValueError:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   135
            warn(_("cannot parse entry"))
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   136
            continue
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   137
        name = name.strip()
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   138
        if recode:
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   139
            name = recode(name)
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   140
        try:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   141
            nodebin = bin(nodehex)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   142
        except TypeError:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   143
            warn(_("node '%s' is not well formed") % nodehex)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   144
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   145
        if nodebin not in repo.changelog.nodemap:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   146
            # silently ignore as pull -r might cause this
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   147
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   148
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   149
        # update filetags
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   150
        hist = []
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   151
        if name in filetags:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   152
            n, hist = filetags[name]
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   153
            hist.append(n)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   154
        filetags[name] = (nodebin, hist)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   155
    return filetags
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   156
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   157
def _updatetags(filetags, tagtype, alltags, tagtypes):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   158
    '''Incorporate the tag info read from one file into the two
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   159
    dictionaries, alltags and tagtypes, that contain all tag
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   160
    info (global across all heads plus local).'''
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   161
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   162
    for name, nodehist in filetags.iteritems():
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   163
        if name not in alltags:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   164
            alltags[name] = nodehist
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   165
            tagtypes[name] = tagtype
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   166
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   167
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   168
        # we prefer alltags[name] if:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   169
        #  it supercedes us OR
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   170
        #  mutual supercedes and it has a higher rank
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   171
        # otherwise we win because we're tip-most
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   172
        anode, ahist = nodehist
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   173
        bnode, bhist = alltags[name]
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   174
        if (bnode != anode and anode in bhist and
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   175
            (bnode not in ahist or len(bhist) > len(ahist))):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   176
            anode = bnode
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   177
        ahist.extend([n for n in bhist if n not in ahist])
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   178
        alltags[name] = anode, ahist
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   179
        tagtypes[name] = tagtype
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   180
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   181
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   182
# The tag cache only stores info about heads, not the tag contents
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   183
# from each head.  I.e. it doesn't try to squeeze out the maximum
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   184
# performance, but is simpler has a better chance of actually
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   185
# working correctly.  And this gives the biggest performance win: it
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   186
# avoids looking up .hgtags in the manifest for every head, and it
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   187
# can avoid calling heads() at all if there have been no changes to
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   188
# the repo.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   189
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   190
def _readtagcache(ui, repo):
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   191
    '''Read the tag cache and return a tuple (heads, fnodes, cachetags,
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   192
    shouldwrite).  If the cache is completely up-to-date, cachetags is a
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   193
    dict of the form returned by _readtags(); otherwise, it is None and
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   194
    heads and fnodes are set.  In that case, heads is the list of all
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   195
    heads currently in the repository (ordered from tip to oldest) and
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   196
    fnodes is a mapping from head to .hgtags filenode.  If those two are
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   197
    set, caller is responsible for reading tag info from each head.'''
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   198
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   199
    try:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   200
        cachefile = repo.opener('tags.cache', 'r')
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   201
        _debug(ui, 'reading tag cache from %s\n' % cachefile.name)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   202
    except IOError:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   203
        cachefile = None
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   204
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   205
    # The cache file consists of lines like
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   206
    #   <headrev> <headnode> [<tagnode>]
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   207
    # where <headrev> and <headnode> redundantly identify a repository
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   208
    # head from the time the cache was written, and <tagnode> is the
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   209
    # filenode of .hgtags on that head.  Heads with no .hgtags file will
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   210
    # have no <tagnode>.  The cache is ordered from tip to oldest (which
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   211
    # is part of why <headrev> is there: a quick visual check is all
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   212
    # that's required to ensure correct order).
9312
c5f0825c1dbb kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9152
diff changeset
   213
    #
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   214
    # This information is enough to let us avoid the most expensive part
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   215
    # of finding global tags, which is looking up <tagnode> in the
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   216
    # manifest for each head.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   217
    cacherevs = []                      # list of headrev
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   218
    cacheheads = []                     # list of headnode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   219
    cachefnode = {}                     # map headnode to filenode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   220
    if cachefile:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   221
        for line in cachefile:
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   222
            if line == "\n":
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   223
                break
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   224
            line = line.rstrip().split()
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   225
            cacherevs.append(int(line[0]))
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   226
            headnode = bin(line[1])
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   227
            cacheheads.append(headnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   228
            if len(line) == 3:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   229
                fnode = bin(line[2])
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   230
                cachefnode[headnode] = fnode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   231
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   232
    tipnode = repo.changelog.tip()
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   233
    tiprev = len(repo.changelog) - 1
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   234
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   235
    # Case 1 (common): tip is the same, so nothing has changed.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   236
    # (Unchanged tip trivially means no changesets have been added.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   237
    # But, thanks to localrepository.destroyed(), it also means none
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   238
    # have been destroyed by strip or rollback.)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   239
    if cacheheads and cacheheads[0] == tipnode and cacherevs[0] == tiprev:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   240
        _debug(ui, "tag cache: tip unchanged\n")
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   241
        tags = _readtags(ui, repo, cachefile, cachefile.name)
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   242
        cachefile.close()
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   243
        return (None, None, tags, False)
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   244
    if cachefile:
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   245
        cachefile.close()               # ignore rest of file
9312
c5f0825c1dbb kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9152
diff changeset
   246
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   247
    repoheads = repo.heads()
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   248
    # Case 2 (uncommon): empty repo; get out quickly and don't bother
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   249
    # writing an empty cache.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   250
    if repoheads == [nullid]:
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   251
        return ([], {}, {}, False)
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   252
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   253
    # Case 3 (uncommon): cache file missing or empty.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   254
    if not cacheheads:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   255
        _debug(ui, 'tag cache: cache file missing or empty\n')
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   256
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   257
    # Case 4 (uncommon): tip rev decreased.  This should only happen
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   258
    # when we're called from localrepository.destroyed().  Refresh the
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   259
    # cache so future invocations will not see disappeared heads in the
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   260
    # cache.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   261
    elif cacheheads and tiprev < cacherevs[0]:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   262
        _debug(ui,
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   263
               'tag cache: tip rev decremented (from %d to %d), '
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   264
               'so we must be destroying nodes\n'
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   265
               % (cacherevs[0], tiprev))
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   266
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   267
    # Case 5 (common): tip has changed, so we've added/replaced heads.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   268
    else:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   269
        _debug(ui,
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   270
               'tag cache: tip has changed (%d:%s); must find new heads\n'
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   271
               % (tiprev, short(tipnode)))
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   272
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   273
    # Luckily, the code to handle cases 3, 4, 5 is the same.  So the
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   274
    # above if/elif/else can disappear once we're confident this thing
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   275
    # actually works and we don't need the debug output.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   276
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   277
    # N.B. in case 4 (nodes destroyed), "new head" really means "newly
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   278
    # exposed".
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   279
    newheads = [head
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   280
                for head in repoheads
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   281
                if head not in set(cacheheads)]
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   282
    _debug(ui, 'tag cache: found %d head(s) not in cache: %s\n'
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   283
           % (len(newheads), map(short, newheads)))
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   284
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   285
    # Now we have to lookup the .hgtags filenode for every new head.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   286
    # This is the most expensive part of finding tags, so performance
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   287
    # depends primarily on the size of newheads.  Worst case: no cache
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   288
    # file, so newheads == repoheads.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   289
    for head in newheads:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   290
        cctx = repo[head]
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   291
        try:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   292
            fnode = cctx.filenode('.hgtags')
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   293
            cachefnode[head] = fnode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   294
        except error.LookupError:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   295
            # no .hgtags file on this head
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   296
            pass
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   297
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   298
    # Caller has to iterate over all heads, but can use the filenodes in
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   299
    # cachefnode to get to each .hgtags revision quickly.
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   300
    return (repoheads, cachefnode, None, True)
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   301
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   302
def _writetagcache(ui, repo, heads, tagfnode, cachetags):
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   303
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   304
    cachefile = repo.opener('tags.cache', 'w', atomictemp=True)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   305
    _debug(ui, 'writing cache file %s\n' % cachefile.name)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   306
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   307
    realheads = repo.heads()            # for sanity checks below
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   308
    for head in heads:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   309
        # temporary sanity checks; these can probably be removed
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   310
        # once this code has been in crew for a few weeks
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   311
        assert head in repo.changelog.nodemap, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   312
               'trying to write non-existent node %s to tag cache' % short(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   313
        assert head in realheads, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   314
               'trying to write non-head %s to tag cache' % short(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   315
        assert head != nullid, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   316
               'trying to write nullid to tag cache'
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   317
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   318
        # This can't fail because of the first assert above.  When/if we
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   319
        # remove that assert, we might want to catch LookupError here
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   320
        # and downgrade it to a warning.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   321
        rev = repo.changelog.rev(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   322
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   323
        fnode = tagfnode.get(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   324
        if fnode:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   325
            cachefile.write('%d %s %s\n' % (rev, hex(head), hex(fnode)))
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   326
        else:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   327
            cachefile.write('%d %s\n' % (rev, hex(head)))
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   328
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   329
    # Tag names in the cache are in UTF-8 -- which is the whole reason
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   330
    # we keep them in UTF-8 throughout this module.  If we converted
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   331
    # them local encoding on input, we would lose info writing them to
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   332
    # the cache.
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   333
    cachefile.write('\n')
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   334
    for (name, (node, hist)) in cachetags.iteritems():
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   335
        cachefile.write("%s %s\n" % (hex(node), name))
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   336
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   337
    cachefile.rename()
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   338
    cachefile.close()