mercurial/tags.py
author Greg Ward <greg-hg@gerg.ca>
Thu, 16 Jul 2009 10:39:42 -0400
changeset 9151 f528d1a93491
parent 9149 abb7d4d43a5f
child 9152 4017291c4c48
permissions -rw-r--r--
tags: implement persistent tag caching (issue548). - rename findglobaltags() to findglobaltags1() (so the "no cache" implementation is still there if we need it) - add findglobaltags2() and make findglobaltags() an alias for it (disabling tag caching is a one-line patch) - factor out tagcache class with methods readcache() and writecache(); the expensive part of tag finding (iterate over heads and find .hgtags filenode) is now in tagcache.readcache()
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.'''
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    62
    (heads, tagfnode, shouldwrite) = _readtagcache(ui, repo)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    63
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    64
    _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
    65
           % (len(heads), map(short, reversed(heads))))
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    66
    seen = set()                    # set of fnode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    67
    fctx = None
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    68
    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
    69
        assert head in repo.changelog.nodemap, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    70
               "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
    71
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    72
        fnode = tagfnode.get(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    73
        if fnode and fnode not in seen:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    74
            seen.add(fnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    75
            if not fctx:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    76
                fctx = repo.filectx('.hgtags', fileid=fnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    77
            else:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    78
                fctx = fctx.filectx(fnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    79
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    80
            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
    81
            _updatetags(filetags, 'global', alltags, tagtypes)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    82
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    83
    # and update the cache (if necessary)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    84
    if shouldwrite:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    85
        _writetagcache(ui, repo, heads, tagfnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    86
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    87
# 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
    88
findglobaltags = findglobaltags2
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    89
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    90
def readlocaltags(ui, repo, alltags, tagtypes):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    91
    '''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
    92
    try:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    93
        data = encoding.fromlocal(repo.opener("localtags").read())
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    94
        # localtags are stored in the local character set
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    95
        # while the internal tag table is stored in UTF-8
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    96
        filetags = _readtags(
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    97
            ui, repo, data.splitlines(), "localtags")
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    98
        _updatetags(filetags, "local", alltags, tagtypes)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    99
    except IOError:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   100
        pass
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   101
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   102
def _readtags(ui, repo, lines, fn):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   103
    '''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
   104
    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
   105
    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
   106
    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
   107
    binary, not hex.'''
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   108
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   109
    filetags = {}               # map tag name to (node, hist)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   110
    count = 0
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   111
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   112
    def warn(msg):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   113
        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
   114
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   115
    for line in lines:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   116
        count += 1
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   117
        if not line:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   118
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   119
        try:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   120
            (nodehex, name) = line.split(" ", 1)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   121
        except ValueError:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   122
            warn(_("cannot parse entry"))
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   123
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   124
        name = encoding.tolocal(name.strip()) # stored in UTF-8
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   125
        try:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   126
            nodebin = bin(nodehex)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   127
        except TypeError:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   128
            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
   129
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   130
        if nodebin not in repo.changelog.nodemap:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   131
            # 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
   132
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   133
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   134
        # update filetags
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   135
        hist = []
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   136
        if name in filetags:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   137
            n, hist = filetags[name]
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   138
            hist.append(n)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   139
        filetags[name] = (nodebin, hist)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   140
    return filetags
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   141
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   142
def _updatetags(filetags, tagtype, alltags, tagtypes):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   143
    '''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
   144
    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
   145
    info (global across all heads plus local).'''
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   146
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   147
    for name, nodehist in filetags.iteritems():
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   148
        if name not in alltags:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   149
            alltags[name] = nodehist
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   150
            tagtypes[name] = tagtype
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   151
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   152
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   153
        # we prefer alltags[name] if:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   154
        #  it supercedes us OR
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   155
        #  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
   156
        # 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
   157
        anode, ahist = nodehist
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   158
        bnode, bhist = alltags[name]
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   159
        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
   160
            (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
   161
            anode = bnode
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   162
        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
   163
        alltags[name] = anode, ahist
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   164
        tagtypes[name] = tagtype
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   165
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   166
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   167
# 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
   168
# 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
   169
# 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
   170
# 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
   171
# 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
   172
# 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
   173
# the repo.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   174
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   175
def _readtagcache(ui, repo):
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   176
    '''Read the tag cache and return a tuple (heads, fnodes,
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   177
    shouldwrite).  heads is the list of all heads currently in the
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   178
    repository (ordered from tip to oldest) and fnodes is a mapping from
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   179
    head to .hgtags filenode.  Caller is responsible for reading tag
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   180
    info from each head.'''
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
    try:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   183
        cachefile = repo.opener('tags.cache', 'r')
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   184
        _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
   185
    except IOError:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   186
        cachefile = None
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   187
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   188
    # The cache file consists of lines like
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   189
    #   <headrev> <headnode> [<tagnode>]
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   190
    # 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
   191
    # 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
   192
    # 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
   193
    # 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
   194
    # 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
   195
    # that's required to ensure correct order).
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   196
    # 
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   197
    # 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
   198
    # 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
   199
    # manifest for each head.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   200
    cacherevs = []                      # list of headrev
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   201
    cacheheads = []                     # list of headnode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   202
    cachefnode = {}                     # map headnode to filenode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   203
    if cachefile:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   204
        for line in cachefile:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   205
            line = line.rstrip().split()
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   206
            cacherevs.append(int(line[0]))
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   207
            headnode = bin(line[1])
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   208
            cacheheads.append(headnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   209
            if len(line) == 3:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   210
                fnode = bin(line[2])
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   211
                cachefnode[headnode] = fnode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   212
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   213
        cachefile.close()
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   214
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   215
    tipnode = repo.changelog.tip()
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   216
    tiprev = len(repo.changelog) - 1
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   217
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   218
    # 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
   219
    # (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
   220
    # 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
   221
    # have been destroyed by strip or rollback.)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   222
    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
   223
        _debug(ui, "tag cache: tip unchanged\n")
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   224
        return (cacheheads, cachefnode, False)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   225
        
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   226
    repoheads = repo.heads()
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   227
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   228
    # 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
   229
    # writing an empty cache.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   230
    if repoheads == [nullid]:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   231
        return ([], {}, False)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   232
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   233
    # 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
   234
    if not cacheheads:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   235
        _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
   236
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   237
    # 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
   238
    # 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
   239
    # 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
   240
    # cache.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   241
    elif cacheheads and tiprev < cacherevs[0]:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   242
        _debug(ui,
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   243
               '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
   244
               'so we must be destroying nodes\n'
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   245
               % (cacherevs[0], tiprev))
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   246
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   247
    # 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
   248
    else:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   249
        _debug(ui,
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   250
               '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
   251
               % (tiprev, short(tipnode)))
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
    # 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
   254
    # 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
   255
    # 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
   256
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   257
    # 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
   258
    # exposed".
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   259
    newheads = [head
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   260
                for head in repoheads
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   261
                if head not in set(cacheheads)]
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   262
    _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
   263
           % (len(newheads), map(short, newheads)))
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   264
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   265
    # 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
   266
    # 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
   267
    # 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
   268
    # file, so newheads == repoheads.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   269
    for head in newheads:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   270
        cctx = repo[head]
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   271
        try:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   272
            fnode = cctx.filenode('.hgtags')
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   273
            cachefnode[head] = fnode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   274
        except error.LookupError:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   275
            # no .hgtags file on this head
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   276
            pass
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   277
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   278
    # 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
   279
    # cachefnode to get to each .hgtags revision quickly.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   280
    return (repoheads, cachefnode, True)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   281
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   282
def _writetagcache(ui, repo, heads, tagfnode):
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   283
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   284
    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
   285
    _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
   286
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   287
    realheads = repo.heads()            # for sanity checks below
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   288
    for head in heads:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   289
        # 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
   290
        # 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
   291
        assert head in repo.changelog.nodemap, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   292
               '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
   293
        assert head in realheads, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   294
               '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
   295
        assert head != nullid, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   296
               'trying to write nullid to tag cache'
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
        # 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
   299
        # 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
   300
        # and downgrade it to a warning.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   301
        rev = repo.changelog.rev(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   302
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   303
        fnode = tagfnode.get(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   304
        if fnode:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   305
            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
   306
        else:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   307
            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
   308
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   309
    cachefile.rename()
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   310
    cachefile.close()