mercurial/tags.py
author Greg Ward <greg@gerg.ca>
Thu, 25 Aug 2011 20:21:04 -0400
changeset 15057 774da7121fc9
parent 14662 2b30124c7d8a
child 16589 fe9a53726484
permissions -rw-r--r--
atomictempfile: make close() consistent with other file-like objects. The usual contract is that close() makes your writes permanent, so atomictempfile's use of close() to *discard* writes (and rename() to keep them) is rather unexpected. Thus, change it so close() makes things permanent and add a new discard() method to throw them away. discard() is only used internally, in __del__(), to ensure that writes are discarded when an atomictempfile object goes out of scope. I audited mercurial.*, hgext.*, and ~80 third-party extensions, and found no one using the existing semantics of close() to discard writes, so this should be safe.
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
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9678
diff changeset
     7
# GNU General Public License version 2 or any later version.
9149
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
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
    14
from i18n import _
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    15
import encoding
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    16
import error
14038
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
    17
import errno
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    18
11351
1cdc8b5e5729 tags: remove the old non-caching implementation of findglobaltags().
Greg Ward <greg-hg@gerg.ca>
parents: 11078
diff changeset
    19
def findglobaltags(ui, repo, alltags, tagtypes):
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    20
    '''Find global tags in repo by reading .hgtags from every head that
11351
1cdc8b5e5729 tags: remove the old non-caching implementation of findglobaltags().
Greg Ward <greg-hg@gerg.ca>
parents: 11078
diff changeset
    21
    has a distinct version of it, using a cache to avoid excess work.
1cdc8b5e5729 tags: remove the old non-caching implementation of findglobaltags().
Greg Ward <greg-hg@gerg.ca>
parents: 11078
diff changeset
    22
    Updates the dicts alltags, tagtypes in place: alltags maps tag name
1cdc8b5e5729 tags: remove the old non-caching implementation of findglobaltags().
Greg Ward <greg-hg@gerg.ca>
parents: 11078
diff changeset
    23
    to (node, hist) pair (see _readtags() below), and tagtypes maps tag
1cdc8b5e5729 tags: remove the old non-caching implementation of findglobaltags().
Greg Ward <greg-hg@gerg.ca>
parents: 11078
diff changeset
    24
    name to tag type ("global" in this case).'''
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    25
    # 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
    26
    # tags when we pass it to _writetagcache().
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    27
    assert len(alltags) == len(tagtypes) == 0, \
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    28
           "findglobaltags() should be called first"
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    29
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    30
    (heads, tagfnode, cachetags, shouldwrite) = _readtagcache(ui, repo)
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    31
    if cachetags is not None:
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    32
        assert not shouldwrite
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    33
        # 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
    34
        # 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
    35
        # because cachetags does not contain rank info?
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    36
        _updatetags(cachetags, 'global', alltags, tagtypes)
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    37
        return
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    38
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    39
    seen = set()                    # set of fnode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    40
    fctx = None
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    41
    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
    42
        assert head in repo.changelog.nodemap, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    43
               "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
    44
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    45
        fnode = tagfnode.get(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    46
        if fnode and fnode not in seen:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    47
            seen.add(fnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    48
            if not fctx:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    49
                fctx = repo.filectx('.hgtags', fileid=fnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    50
            else:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    51
                fctx = fctx.filectx(fnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    52
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    53
            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
    54
            _updatetags(filetags, 'global', alltags, tagtypes)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    55
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    56
    # and update the cache (if necessary)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    57
    if shouldwrite:
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    58
        _writetagcache(ui, repo, heads, tagfnode, alltags)
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
    59
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    60
def readlocaltags(ui, repo, alltags, tagtypes):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    61
    '''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
    62
    try:
14168
135e244776f0 prevent transient leaks of file handle by using new helper functions
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14038
diff changeset
    63
        data = repo.opener.read("localtags")
14038
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
    64
    except IOError, inst:
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
    65
        if inst.errno != errno.ENOENT:
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
    66
            raise
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
    67
        return
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
    68
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
    69
    # localtags is in the local encoding; re-encode to UTF-8 on
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
    70
    # input for consistency with the rest of this module.
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
    71
    filetags = _readtags(
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
    72
        ui, repo, data.splitlines(), "localtags",
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
    73
        recode=encoding.fromlocal)
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
    74
    _updatetags(filetags, "local", alltags, tagtypes)
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    75
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    76
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
    77
    '''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
    78
    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
    79
    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
    80
    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
    81
    binary, not hex.'''
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    82
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    83
    filetags = {}               # map tag name to (node, hist)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    84
    count = 0
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    85
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    86
    def warn(msg):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    87
        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
    88
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    89
    for line in lines:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    90
        count += 1
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    91
        if not line:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    92
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    93
        try:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    94
            (nodehex, name) = line.split(" ", 1)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    95
        except ValueError:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    96
            warn(_("cannot parse entry"))
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    97
            continue
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    98
        name = name.strip()
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    99
        if recode:
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   100
            name = recode(name)
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   101
        try:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   102
            nodebin = bin(nodehex)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   103
        except TypeError:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   104
            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
   105
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   106
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   107
        # update filetags
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   108
        hist = []
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   109
        if name in filetags:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   110
            n, hist = filetags[name]
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   111
            hist.append(n)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   112
        filetags[name] = (nodebin, hist)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   113
    return filetags
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
def _updatetags(filetags, tagtype, alltags, tagtypes):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   116
    '''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
   117
    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
   118
    info (global across all heads plus local).'''
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   119
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   120
    for name, nodehist in filetags.iteritems():
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   121
        if name not in alltags:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   122
            alltags[name] = nodehist
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   123
            tagtypes[name] = tagtype
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   124
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   125
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   126
        # we prefer alltags[name] if:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   127
        #  it supercedes us OR
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   128
        #  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
   129
        # 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
   130
        anode, ahist = nodehist
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   131
        bnode, bhist = alltags[name]
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   132
        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
   133
            (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
   134
            anode = bnode
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   135
        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
   136
        alltags[name] = anode, ahist
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   137
        tagtypes[name] = tagtype
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   138
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   139
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   140
# 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
   141
# 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
   142
# 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
   143
# 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
   144
# 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
   145
# 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
   146
# the repo.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   147
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   148
def _readtagcache(ui, repo):
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   149
    '''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
   150
    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
   151
    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
   152
    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
   153
    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
   154
    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
   155
    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
   156
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   157
    try:
13341
4e33ef68b1f8 remove pointless os.path.join calls when opening files in .hg/cache
Adrian Buehlmann <adrian@cadifra.com>
parents: 13272
diff changeset
   158
        cachefile = repo.opener('cache/tags', 'r')
11066
26abd91d9e84 static-http: mimic more closely localrepo (issue2164: allow clone -r )
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10263
diff changeset
   159
        # force reading the file for static-http
26abd91d9e84 static-http: mimic more closely localrepo (issue2164: allow clone -r )
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10263
diff changeset
   160
        cachelines = iter(cachefile)
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   161
    except IOError:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   162
        cachefile = None
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   163
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   164
    # The cache file consists of lines like
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   165
    #   <headrev> <headnode> [<tagnode>]
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   166
    # 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
   167
    # 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
   168
    # 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
   169
    # 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
   170
    # 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
   171
    # that's required to ensure correct order).
9312
c5f0825c1dbb kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9152
diff changeset
   172
    #
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   173
    # 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
   174
    # 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
   175
    # manifest for each head.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   176
    cacherevs = []                      # list of headrev
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   177
    cacheheads = []                     # list of headnode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   178
    cachefnode = {}                     # map headnode to filenode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   179
    if cachefile:
12758
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   180
        try:
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   181
            for line in cachelines:
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   182
                if line == "\n":
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   183
                    break
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   184
                line = line.rstrip().split()
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   185
                cacherevs.append(int(line[0]))
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   186
                headnode = bin(line[1])
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   187
                cacheheads.append(headnode)
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   188
                if len(line) == 3:
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   189
                    fnode = bin(line[2])
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   190
                    cachefnode[headnode] = fnode
14020
98f79a5c3086 tags: catch more corruption during cache parsing (issue2779)
Matt Mackall <mpm@selenic.com>
parents: 13341
diff changeset
   191
        except Exception:
13272
5ccdca7df211 move tags.cache and branchheads.cache to a collected cache folder .hg/cache/
jfh <jason@jasonfharris.com>
parents: 13257
diff changeset
   192
            # corruption of the tags cache, just recompute it
5ccdca7df211 move tags.cache and branchheads.cache to a collected cache folder .hg/cache/
jfh <jason@jasonfharris.com>
parents: 13257
diff changeset
   193
            ui.warn(_('.hg/cache/tags is corrupt, rebuilding it\n'))
12758
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   194
            cacheheads = []
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   195
            cacherevs = []
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   196
            cachefnode = {}
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   197
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   198
    tipnode = repo.changelog.tip()
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   199
    tiprev = len(repo.changelog) - 1
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   200
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   201
    # 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
   202
    # (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
   203
    # 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
   204
    # have been destroyed by strip or rollback.)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   205
    if cacheheads and cacheheads[0] == tipnode and cacherevs[0] == tiprev:
11066
26abd91d9e84 static-http: mimic more closely localrepo (issue2164: allow clone -r )
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10263
diff changeset
   206
        tags = _readtags(ui, repo, cachelines, cachefile.name)
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   207
        cachefile.close()
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   208
        return (None, None, tags, False)
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   209
    if cachefile:
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   210
        cachefile.close()               # ignore rest of file
9312
c5f0825c1dbb kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9152
diff changeset
   211
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   212
    repoheads = repo.heads()
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   213
    # 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
   214
    # writing an empty cache.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   215
    if repoheads == [nullid]:
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   216
        return ([], {}, {}, False)
9151
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 3 (uncommon): cache file missing or empty.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   219
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   220
    # 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
   221
    # 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
   222
    # 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
   223
    # cache.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   224
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   225
    # 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
   226
11352
b19067ee4507 tags: remove inactive debugging code.
Greg Ward <greg-hg@gerg.ca>
parents: 11351
diff changeset
   227
    # As it happens, the code to handle cases 3, 4, 5 is the same.
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   228
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   229
    # 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
   230
    # exposed".
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   231
    newheads = [head
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   232
                for head in repoheads
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   233
                if head not in set(cacheheads)]
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
    # 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
   236
    # 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
   237
    # 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
   238
    # file, so newheads == repoheads.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   239
    for head in newheads:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   240
        cctx = repo[head]
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   241
        try:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   242
            fnode = cctx.filenode('.hgtags')
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   243
            cachefnode[head] = fnode
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   244
        except error.LookupError:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   245
            # no .hgtags file on this head
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   246
            pass
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   247
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   248
    # 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
   249
    # 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
   250
    return (repoheads, cachefnode, None, True)
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   251
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   252
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
   253
9366
9ff178e7b627 tags: don't crash if unable to write tag cache
Greg Ward <greg-hg@gerg.ca>
parents: 9312
diff changeset
   254
    try:
13341
4e33ef68b1f8 remove pointless os.path.join calls when opening files in .hg/cache
Adrian Buehlmann <adrian@cadifra.com>
parents: 13272
diff changeset
   255
        cachefile = repo.opener('cache/tags', 'w', atomictemp=True)
9366
9ff178e7b627 tags: don't crash if unable to write tag cache
Greg Ward <greg-hg@gerg.ca>
parents: 9312
diff changeset
   256
    except (OSError, IOError):
9ff178e7b627 tags: don't crash if unable to write tag cache
Greg Ward <greg-hg@gerg.ca>
parents: 9312
diff changeset
   257
        return
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   258
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   259
    realheads = repo.heads()            # for sanity checks below
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   260
    for head in heads:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   261
        # 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
   262
        # 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
   263
        assert head in repo.changelog.nodemap, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   264
               '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
   265
        assert head in realheads, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   266
               '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
   267
        assert head != nullid, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   268
               'trying to write nullid to tag cache'
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   269
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   270
        # 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
   271
        # 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
   272
        # and downgrade it to a warning.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   273
        rev = repo.changelog.rev(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   274
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   275
        fnode = tagfnode.get(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   276
        if fnode:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   277
            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
   278
        else:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   279
            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
   280
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   281
    # 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
   282
    # 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
   283
    # 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
   284
    # the cache.
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   285
    cachefile.write('\n')
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   286
    for (name, (node, hist)) in cachetags.iteritems():
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   287
        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
   288
14662
2b30124c7d8a tags: don't allow environment errors to be raised from _writetagscache
Steve Borho <steve@borho.org>
parents: 14168
diff changeset
   289
    try:
15057
774da7121fc9 atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents: 14662
diff changeset
   290
        cachefile.close()
14662
2b30124c7d8a tags: don't allow environment errors to be raised from _writetagscache
Steve Borho <steve@borho.org>
parents: 14168
diff changeset
   291
    except (OSError, IOError):
2b30124c7d8a tags: don't allow environment errors to be raised from _writetagscache
Steve Borho <steve@borho.org>
parents: 14168
diff changeset
   292
        pass