mercurial/tags.py
author Gregory Szorc <gregory.szorc@gmail.com>
Thu, 16 Apr 2015 10:12:44 -0400
changeset 24759 d082c6ef9ec3
parent 24737 b061a2049662
child 24760 410f3856196f
permissions -rw-r--r--
tags: don't read .hgtags fnodes from tags cache files Now that we have a standalone and shared cache for .hgtags fnodes, the .hgtags fnodes stored in the tags cache files are redundant. Upcoming patches will change the format of the tags cache files to remove this data and to improve the validation. To prepare for this, we change the tags reading code to ignore all but the tip .hgtags fnodes entries in existing tags cache files. All fnodes lookups now go through our new shared cache, which is why test output changed. Format of tags cache files has not yet changed.
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 _
21814
5125856a28cf tags: read tag info into a sorted dict (rather than into a regular dict)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21030
diff changeset
    15
import util
9149
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
24735
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    18
from array import array
14038
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
    19
import errno
21030
9ea132aee96c tags: log events related to tags cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 19646
diff changeset
    20
import time
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    21
24735
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    22
# Tags computation can be expensive and caches exist to make it fast in
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    23
# the common case.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    24
#
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    25
# The "hgtagsfnodes1" cache file caches the .hgtags filenode values for
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    26
# each revision in the repository. The file is effectively an array of
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    27
# fixed length records. Read the docs for "hgtagsfnodescache" for technical
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    28
# details.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    29
#
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    30
# The .hgtags filenode cache grows in proportion to the length of the
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    31
# changelog. The file is truncated when the # changelog is stripped.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    32
#
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    33
# The purpose of the filenode cache is to avoid the most expensive part
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    34
# of finding global tags, which is looking up the .hgtags filenode in the
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    35
# manifest for each head. This can take dozens or over 100ms for
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    36
# repositories with very large manifests. Multiplied by dozens or even
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    37
# hundreds of heads and there is a significant performance concern.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    38
#
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    39
# The "tags" cache stores information about heads and the history of tags.
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    40
#
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    41
# The cache file consists of two parts. The first part maps head nodes
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    42
# to .hgtags filenodes. The second part is a history of tags. The two
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    43
# parts are separated by an empty line.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    44
#
24735
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    45
# The filenodes part of "tags" has effectively been superseded by
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    46
# "hgtagsfnodes1." It is being kept around for backwards compatbility.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
    47
#
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    48
# The first part consists of lines of the form:
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    49
#
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    50
#   <headrev> <headnode> [<hgtagsnode>]
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    51
#
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    52
# <headrev> is an integer revision and <headnode> is a 40 character hex
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    53
# node for that changeset. These redundantly identify a repository
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    54
# head from the time the cache was written.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    55
#
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    56
# <tagnode> is the filenode of .hgtags on that head. Heads with no .hgtags
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    57
# file will have no <hgtagsnode> (just 2 values per line).
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    58
#
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    59
# The filenode cache is ordered from tip to oldest (which is part of why
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    60
# <headrev> is there: a quick check of the tip from when the cache was
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    61
# written against the current tip is all that is needed to check whether
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    62
# the cache is up to date).
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    63
#
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    64
# The second part of the tags cache consists of lines of the form:
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    65
#
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    66
#   <node> <tag>
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    67
#
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    68
# (This format is identical to that of .hgtags files.)
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    69
#
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    70
# <tag> is the tag name and <node> is the 40 character hex changeset
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    71
# the tag is associated with.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    72
#
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    73
# Tags are written sorted by tag name.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    74
#
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    75
# Tags associated with multiple changesets have an entry for each changeset.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    76
# The most recent changeset (in terms of revlog ordering for the head
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    77
# setting it) for each tag is last.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    78
11351
1cdc8b5e5729 tags: remove the old non-caching implementation of findglobaltags().
Greg Ward <greg-hg@gerg.ca>
parents: 11078
diff changeset
    79
def findglobaltags(ui, repo, alltags, tagtypes):
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    80
    '''Find global tags in a repo.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    81
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    82
    "alltags" maps tag name to (node, hist) 2-tuples.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    83
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    84
    "tagtypes" maps tag name to tag type. Global tags always have the
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    85
    "global" tag type.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    86
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    87
    The "alltags" and "tagtypes" dicts are updated in place. Empty dicts
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    88
    should be passed in.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    89
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    90
    The tags cache is read and updated as a side-effect of calling.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
    91
    '''
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    92
    # 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
    93
    # tags when we pass it to _writetagcache().
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    94
    assert len(alltags) == len(tagtypes) == 0, \
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    95
           "findglobaltags() should be called first"
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    96
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    97
    (heads, tagfnode, cachetags, shouldwrite) = _readtagcache(ui, repo)
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    98
    if cachetags is not None:
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
    99
        assert not shouldwrite
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   100
        # 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
   101
        # 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
   102
        # because cachetags does not contain rank info?
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   103
        _updatetags(cachetags, 'global', alltags, tagtypes)
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   104
        return
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   105
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   106
    seen = set()  # set of fnode
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   107
    fctx = None
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   108
    for head in reversed(heads):  # oldest to newest
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   109
        assert head in repo.changelog.nodemap, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   110
               "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
   111
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   112
        fnode = tagfnode.get(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   113
        if fnode and fnode not in seen:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   114
            seen.add(fnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   115
            if not fctx:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   116
                fctx = repo.filectx('.hgtags', fileid=fnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   117
            else:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   118
                fctx = fctx.filectx(fnode)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   119
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   120
            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
   121
            _updatetags(filetags, 'global', alltags, tagtypes)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   122
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   123
    # and update the cache (if necessary)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   124
    if shouldwrite:
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   125
        _writetagcache(ui, repo, heads, tagfnode, alltags)
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   126
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   127
def readlocaltags(ui, repo, alltags, tagtypes):
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   128
    '''Read local tags in repo. Update alltags and tagtypes.'''
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   129
    try:
23877
7cc77030c557 localrepo: remove all external users of localrepo.opener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 23139
diff changeset
   130
        data = repo.vfs.read("localtags")
14038
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
   131
    except IOError, inst:
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
   132
        if inst.errno != errno.ENOENT:
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
   133
            raise
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
   134
        return
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
   135
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
   136
    # 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
   137
    # 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
   138
    filetags = _readtags(
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
   139
        ui, repo, data.splitlines(), "localtags",
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
   140
        recode=encoding.fromlocal)
21823
925d1bb9a971 repoview: do not crash when localtags refers to non existing revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21030
diff changeset
   141
925d1bb9a971 repoview: do not crash when localtags refers to non existing revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21030
diff changeset
   142
    # remove tags pointing to invalid nodes
925d1bb9a971 repoview: do not crash when localtags refers to non existing revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21030
diff changeset
   143
    cl = repo.changelog
925d1bb9a971 repoview: do not crash when localtags refers to non existing revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21030
diff changeset
   144
    for t in filetags.keys():
925d1bb9a971 repoview: do not crash when localtags refers to non existing revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21030
diff changeset
   145
        try:
925d1bb9a971 repoview: do not crash when localtags refers to non existing revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21030
diff changeset
   146
            cl.rev(filetags[t][0])
925d1bb9a971 repoview: do not crash when localtags refers to non existing revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21030
diff changeset
   147
        except (LookupError, ValueError):
925d1bb9a971 repoview: do not crash when localtags refers to non existing revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21030
diff changeset
   148
            del filetags[t]
925d1bb9a971 repoview: do not crash when localtags refers to non existing revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21030
diff changeset
   149
14038
0e6f622f31ca tags: loosen IOError filtering when reading localtags
Idan Kamara <idankk86@gmail.com>
parents: 14020
diff changeset
   150
    _updatetags(filetags, "local", alltags, tagtypes)
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   151
21892
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   152
def _readtaghist(ui, repo, lines, fn, recode=None, calcnodelines=False):
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   153
    '''Read tag definitions from a file (or any source of lines).
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   154
21892
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   155
    This function returns two sortdicts with similar information:
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   156
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 21892
diff changeset
   157
    - the first dict, bintaghist, contains the tag information as expected by
21892
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   158
      the _readtags function, i.e. a mapping from tag name to (node, hist):
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   159
        - node is the node id from the last line read for that name,
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   160
        - hist is the list of node ids previously associated with it (in file
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   161
          order). All node ids are binary, not hex.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   162
21892
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   163
    - the second dict, hextaglines, is a mapping from tag name to a list of
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   164
      [hexnode, line number] pairs, ordered from the oldest to the newest node.
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   165
21892
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   166
    When calcnodelines is False the hextaglines dict is not calculated (an
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   167
    empty dict is returned). This is done to improve this function's
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   168
    performance in cases where the line numbers are not needed.
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   169
    '''
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   170
21892
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   171
    bintaghist = util.sortdict()
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   172
    hextaglines = util.sortdict()
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   173
    count = 0
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   174
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   175
    def warn(msg):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   176
        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
   177
21892
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   178
    for nline, line in enumerate(lines):
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   179
        count += 1
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   180
        if not line:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   181
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   182
        try:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   183
            (nodehex, name) = line.split(" ", 1)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   184
        except ValueError:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   185
            warn(_("cannot parse entry"))
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   186
            continue
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   187
        name = name.strip()
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   188
        if recode:
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   189
            name = recode(name)
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   190
        try:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   191
            nodebin = bin(nodehex)
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   192
        except TypeError:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   193
            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
   194
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   195
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   196
        # update filetags
21892
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   197
        if calcnodelines:
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   198
            # map tag name to a list of line numbers
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   199
            if name not in hextaglines:
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   200
                hextaglines[name] = []
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   201
            hextaglines[name].append([nodehex, nline])
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   202
            continue
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   203
        # map tag name to (node, hist)
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   204
        if name not in bintaghist:
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   205
            bintaghist[name] = []
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   206
        bintaghist[name].append(nodebin)
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   207
    return bintaghist, hextaglines
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   208
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   209
def _readtags(ui, repo, lines, fn, recode=None, calcnodelines=False):
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   210
    '''Read tag definitions from a file (or any source of lines).
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   211
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   212
    Returns a mapping from tag name to (node, hist).
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   213
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   214
    "node" is the node id from the last line read for that name. "hist"
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   215
    is the list of node ids previously associated with it (in file order).
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   216
    All node ids are binary, not hex.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   217
    '''
21892
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   218
    filetags, nodelines = _readtaghist(ui, repo, lines, fn, recode=recode,
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   219
                                       calcnodelines=calcnodelines)
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   220
    for tag, taghist in filetags.items():
89cdebc31cda tags: introduce _readtaghist function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21832
diff changeset
   221
        filetags[tag] = (taghist[-1], taghist[:-1])
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   222
    return filetags
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   223
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   224
def _updatetags(filetags, tagtype, alltags, tagtypes):
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   225
    '''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
   226
    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
   227
    info (global across all heads plus local).'''
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   228
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   229
    for name, nodehist in filetags.iteritems():
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   230
        if name not in alltags:
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   231
            alltags[name] = nodehist
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   232
            tagtypes[name] = tagtype
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   233
            continue
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   234
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   235
        # we prefer alltags[name] if:
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17256
diff changeset
   236
        #  it supersedes us OR
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17256
diff changeset
   237
        #  mutual supersedes and it has a higher rank
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   238
        # 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
   239
        anode, ahist = nodehist
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   240
        bnode, bhist = alltags[name]
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   241
        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
   242
            (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
   243
            anode = bnode
19108
cb95716da5fe tags: update tag type only if tag node is updated (issue3911)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17424
diff changeset
   244
        else:
cb95716da5fe tags: update tag type only if tag node is updated (issue3911)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17424
diff changeset
   245
            tagtypes[name] = tagtype
9149
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   246
        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
   247
        alltags[name] = anode, ahist
abb7d4d43a5f Factor tags module out of localrepo (issue548).
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   248
24737
b061a2049662 tags: have a different cache file per filter level
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24735
diff changeset
   249
def _filename(repo):
b061a2049662 tags: have a different cache file per filter level
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24735
diff changeset
   250
    """name of a tagcache file for a given repo or repoview"""
b061a2049662 tags: have a different cache file per filter level
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24735
diff changeset
   251
    filename = 'cache/tags'
b061a2049662 tags: have a different cache file per filter level
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24735
diff changeset
   252
    if repo.filtername:
b061a2049662 tags: have a different cache file per filter level
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24735
diff changeset
   253
        filename = '%s-%s' % (filename, repo.filtername)
b061a2049662 tags: have a different cache file per filter level
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24735
diff changeset
   254
    return filename
b061a2049662 tags: have a different cache file per filter level
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24735
diff changeset
   255
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   256
def _readtagcache(ui, repo):
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   257
    '''Read the tag cache.
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   258
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   259
    Returns a tuple (heads, fnodes, cachetags, shouldwrite).
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   260
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   261
    If the cache is completely up-to-date, "cachetags" is a dict of the
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   262
    form returned by _readtags() and "heads" and "fnodes" are None and
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   263
    "shouldwrite" is False.
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   264
24445
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   265
    If the cache is not up to date, "cachetags" is None. "heads" is a list
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   266
    of all heads currently in the repository, ordered from tip to oldest.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   267
    "fnodes" is a mapping from head to .hgtags filenode. "shouldwrite" is
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   268
    True.
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   269
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   270
    If the cache is not up to date, the caller is responsible for reading tag
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   271
    info from each returned head. (See findglobaltags().)
c71edbafe603 tags: improve documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24143
diff changeset
   272
    '''
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   273
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   274
    try:
24737
b061a2049662 tags: have a different cache file per filter level
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24735
diff changeset
   275
        cachefile = repo.vfs(_filename(repo), 'r')
11066
26abd91d9e84 static-http: mimic more closely localrepo (issue2164: allow clone -r )
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10263
diff changeset
   276
        # 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
   277
        cachelines = iter(cachefile)
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   278
    except IOError:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   279
        cachefile = None
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   280
24759
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   281
    cachetiprev = None
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   282
    cachetipnode = None
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   283
    if cachefile:
12758
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   284
        try:
24759
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   285
            for i, line in enumerate(cachelines):
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   286
                # Getting the first line and consuming all fnode lines.
12758
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   287
                if line == "\n":
2d754eae430c tags: do not fail if tags.cache is corrupted (issue2444)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11352
diff changeset
   288
                    break
24759
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   289
                if i != 0:
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   290
                    continue
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   291
16589
fe9a53726484 tags: line.rstrip().split() can be replaced with line.split()
Martin Geisler <mg@aragost.com>
parents: 15057
diff changeset
   292
                line = line.split()
24759
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   293
                cachetiprev = int(line[0])
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   294
                cachetipnode = bin(line[1])
14020
98f79a5c3086 tags: catch more corruption during cache parsing (issue2779)
Matt Mackall <mpm@selenic.com>
parents: 13341
diff changeset
   295
        except Exception:
24759
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   296
            # corruption of the cache, just recompute it.
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   297
            pass
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   298
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   299
    tipnode = repo.changelog.tip()
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   300
    tiprev = len(repo.changelog) - 1
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   301
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   302
    # 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
   303
    # (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
   304
    # 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
   305
    # have been destroyed by strip or rollback.)
24759
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   306
    if (cachetiprev is not None
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   307
            and cachetiprev == tiprev
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   308
            and cachetipnode == tipnode):
11066
26abd91d9e84 static-http: mimic more closely localrepo (issue2164: allow clone -r )
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10263
diff changeset
   309
        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
   310
        cachefile.close()
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   311
        return (None, None, tags, False)
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   312
    if cachefile:
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   313
        cachefile.close()               # ignore rest of file
9312
c5f0825c1dbb kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9152
diff changeset
   314
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   315
    repoheads = repo.heads()
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   316
    # 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
   317
    # writing an empty cache.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   318
    if repoheads == [nullid]:
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   319
        return ([], {}, {}, False)
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   320
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   321
    # 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
   322
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   323
    # 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
   324
    # 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
   325
    # 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
   326
    # cache.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   327
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   328
    # 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
   329
11352
b19067ee4507 tags: remove inactive debugging code.
Greg Ward <greg-hg@gerg.ca>
parents: 11351
diff changeset
   330
    # 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
   331
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   332
    # 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
   333
    # exposed".
16730
dd4ce44ff53c tags: short-circuit if no tags have ever been committed
Bryan O'Sullivan <bryano@fb.com>
parents: 16589
diff changeset
   334
    if not len(repo.file('.hgtags')):
dd4ce44ff53c tags: short-circuit if no tags have ever been committed
Bryan O'Sullivan <bryano@fb.com>
parents: 16589
diff changeset
   335
        # No tags have ever been committed, so we can avoid a
dd4ce44ff53c tags: short-circuit if no tags have ever been committed
Bryan O'Sullivan <bryano@fb.com>
parents: 16589
diff changeset
   336
        # potentially expensive search.
24759
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   337
        return (repoheads, {}, None, True)
16730
dd4ce44ff53c tags: short-circuit if no tags have ever been committed
Bryan O'Sullivan <bryano@fb.com>
parents: 16589
diff changeset
   338
21030
9ea132aee96c tags: log events related to tags cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 19646
diff changeset
   339
    starttime = time.time()
9ea132aee96c tags: log events related to tags cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 19646
diff changeset
   340
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   341
    # 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
   342
    # 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
   343
    # 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
   344
    # file, so newheads == repoheads.
24735
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   345
    fnodescache = hgtagsfnodescache(repo.unfiltered())
24759
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   346
    cachefnode = {}
d082c6ef9ec3 tags: don't read .hgtags fnodes from tags cache files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24737
diff changeset
   347
    for head in reversed(repoheads):
24735
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   348
        fnode = fnodescache.getfnode(head)
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   349
        if fnode != nullid:
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   350
            cachefnode[head] = fnode
24735
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   351
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   352
    fnodescache.write()
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   353
21030
9ea132aee96c tags: log events related to tags cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 19646
diff changeset
   354
    duration = time.time() - starttime
9ea132aee96c tags: log events related to tags cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 19646
diff changeset
   355
    ui.log('tagscache',
24735
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   356
           '%d/%d cache hits/lookups in %0.4f '
21030
9ea132aee96c tags: log events related to tags cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 19646
diff changeset
   357
           'seconds\n',
24735
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   358
           fnodescache.hitcount, fnodescache.lookupcount, duration)
21030
9ea132aee96c tags: log events related to tags cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 19646
diff changeset
   359
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   360
    # 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
   361
    # 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
   362
    return (repoheads, cachefnode, None, True)
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   363
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   364
def _writetagcache(ui, repo, heads, tagfnode, cachetags):
9366
9ff178e7b627 tags: don't crash if unable to write tag cache
Greg Ward <greg-hg@gerg.ca>
parents: 9312
diff changeset
   365
    try:
24737
b061a2049662 tags: have a different cache file per filter level
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24735
diff changeset
   366
        cachefile = repo.vfs(_filename(repo), '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
   367
    except (OSError, IOError):
9ff178e7b627 tags: don't crash if unable to write tag cache
Greg Ward <greg-hg@gerg.ca>
parents: 9312
diff changeset
   368
        return
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   369
21030
9ea132aee96c tags: log events related to tags cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 19646
diff changeset
   370
    ui.log('tagscache', 'writing tags cache file with %d heads and %d tags\n',
9ea132aee96c tags: log events related to tags cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 19646
diff changeset
   371
            len(heads), len(cachetags))
9ea132aee96c tags: log events related to tags cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 19646
diff changeset
   372
9151
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   373
    realheads = repo.heads()            # for sanity checks below
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   374
    for head in heads:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   375
        # 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
   376
        # 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
   377
        assert head in repo.changelog.nodemap, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   378
               '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
   379
        assert head in realheads, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   380
               '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
   381
        assert head != nullid, \
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   382
               'trying to write nullid to tag cache'
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   383
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   384
        # 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
   385
        # 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
   386
        # and downgrade it to a warning.
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   387
        rev = repo.changelog.rev(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   388
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   389
        fnode = tagfnode.get(head)
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   390
        if fnode:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   391
            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
   392
        else:
f528d1a93491 tags: implement persistent tag caching (issue548).
Greg Ward <greg-hg@gerg.ca>
parents: 9149
diff changeset
   393
            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
   394
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   395
    # 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
   396
    # 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
   397
    # 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
   398
    # the cache.
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   399
    cachefile.write('\n')
24143
7b09dbbbd502 tags: write tags cache deterministically
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23877
diff changeset
   400
    for (name, (node, hist)) in sorted(cachetags.iteritems()):
19646
335a558f81dc tags: write tag overwriting history also into tag cache file (issue3911)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19108
diff changeset
   401
        for n in hist:
335a558f81dc tags: write tag overwriting history also into tag cache file (issue3911)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19108
diff changeset
   402
            cachefile.write("%s %s\n" % (hex(n), name))
9152
4017291c4c48 tags: support 'instant' tag retrieval (issue548)
Greg Ward <greg-hg@gerg.ca>
parents: 9151
diff changeset
   403
        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
   404
14662
2b30124c7d8a tags: don't allow environment errors to be raised from _writetagscache
Steve Borho <steve@borho.org>
parents: 14168
diff changeset
   405
    try:
15057
774da7121fc9 atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents: 14662
diff changeset
   406
        cachefile.close()
14662
2b30124c7d8a tags: don't allow environment errors to be raised from _writetagscache
Steve Borho <steve@borho.org>
parents: 14168
diff changeset
   407
    except (OSError, IOError):
2b30124c7d8a tags: don't allow environment errors to be raised from _writetagscache
Steve Borho <steve@borho.org>
parents: 14168
diff changeset
   408
        pass
24735
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   409
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   410
_fnodescachefile = 'cache/hgtagsfnodes1'
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   411
_fnodesrecsize = 4 + 20 # changeset fragment + filenode
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   412
_fnodesmissingrec = '\xff' * 24
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   413
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   414
class hgtagsfnodescache(object):
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   415
    """Persistent cache mapping revisions to .hgtags filenodes.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   416
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   417
    The cache is an array of records. Each item in the array corresponds to
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   418
    a changelog revision. Values in the array contain the first 4 bytes of
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   419
    the node hash and the 20 bytes .hgtags filenode for that revision.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   420
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   421
    The first 4 bytes are present as a form of verification. Repository
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   422
    stripping and rewriting may change the node at a numeric revision in the
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   423
    changelog. The changeset fragment serves as a verifier to detect
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   424
    rewriting. This logic is shared with the rev branch cache (see
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   425
    branchmap.py).
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   426
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   427
    The instance holds in memory the full cache content but entries are
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   428
    only parsed on read.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   429
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   430
    Instances behave like lists. ``c[i]`` works where i is a rev or
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   431
    changeset node. Missing indexes are populated automatically on access.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   432
    """
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   433
    def __init__(self, repo):
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   434
        assert repo.filtername is None
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   435
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   436
        self._repo = repo
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   437
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   438
        # Only for reporting purposes.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   439
        self.lookupcount = 0
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   440
        self.hitcount = 0
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   441
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   442
        self._raw = array('c')
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   443
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   444
        data = repo.vfs.tryread(_fnodescachefile)
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   445
        self._raw.fromstring(data)
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   446
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   447
        # The end state of self._raw is an array that is of the exact length
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   448
        # required to hold a record for every revision in the repository.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   449
        # We truncate or extend the array as necessary. self._dirtyoffset is
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   450
        # defined to be the start offset at which we need to write the output
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   451
        # file. This offset is also adjusted when new entries are calculated
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   452
        # for array members.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   453
        cllen = len(repo.changelog)
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   454
        wantedlen = cllen * _fnodesrecsize
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   455
        rawlen = len(self._raw)
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   456
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   457
        self._dirtyoffset = None
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   458
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   459
        if rawlen < wantedlen:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   460
            self._dirtyoffset = rawlen
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   461
            self._raw.extend('\xff' * (wantedlen - rawlen))
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   462
        elif rawlen > wantedlen:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   463
            # There's no easy way to truncate array instances. This seems
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   464
            # slightly less evil than copying a potentially large array slice.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   465
            for i in range(rawlen - wantedlen):
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   466
                self._raw.pop()
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   467
            self._dirtyoffset = len(self._raw)
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   468
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   469
    def getfnode(self, node):
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   470
        """Obtain the filenode of the .hgtags file at a specified revision.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   471
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   472
        If the value is in the cache, the entry will be validated and returned.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   473
        Otherwise, the filenode will be computed and returned.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   474
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   475
        If an .hgtags does not exist at the specified revision, nullid is
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   476
        returned.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   477
        """
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   478
        ctx = self._repo[node]
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   479
        rev = ctx.rev()
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   480
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   481
        self.lookupcount += 1
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   482
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   483
        offset = rev * _fnodesrecsize
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   484
        record = self._raw[offset:offset + _fnodesrecsize].tostring()
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   485
        properprefix = node[0:4]
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   486
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   487
        # Validate and return existing entry.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   488
        if record != _fnodesmissingrec:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   489
            fileprefix = record[0:4]
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   490
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   491
            if fileprefix == properprefix:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   492
                self.hitcount += 1
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   493
                return record[4:]
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   494
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   495
            # Fall through.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   496
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   497
        # If we get here, the entry is either missing or invalid. Populate it.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   498
        try:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   499
            fnode = ctx.filenode('.hgtags')
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   500
        except error.LookupError:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   501
            # No .hgtags file on this revision.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   502
            fnode = nullid
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   503
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   504
        # Slices on array instances only accept other array.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   505
        entry = array('c', properprefix + fnode)
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   506
        self._raw[offset:offset + _fnodesrecsize] = entry
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   507
        # self._dirtyoffset could be None.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   508
        self._dirtyoffset = min(self._dirtyoffset, offset) or 0
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   509
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   510
        return fnode
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   511
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   512
    def write(self):
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   513
        """Perform all necessary writes to cache file.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   514
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   515
        This may no-op if no writes are needed or if a write lock could
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   516
        not be obtained.
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   517
        """
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   518
        if self._dirtyoffset is None:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   519
            return
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   520
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   521
        data = self._raw[self._dirtyoffset:]
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   522
        if not data:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   523
            return
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   524
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   525
        repo = self._repo
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   526
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   527
        try:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   528
            lock = repo.wlock(wait=False)
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   529
        except error.LockHeld:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   530
            repo.ui.log('tagscache',
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   531
                        'not writing .hg/%s because lock held\n' %
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   532
                        (_fnodescachefile))
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   533
            return
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   534
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   535
        try:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   536
            try:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   537
                f = repo.vfs.open(_fnodescachefile, 'ab')
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   538
                try:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   539
                    # if the file has been truncated
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   540
                    actualoffset = f.tell()
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   541
                    if actualoffset < self._dirtyoffset:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   542
                        self._dirtyoffset = actualoffset
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   543
                        data = self._raw[self._dirtyoffset:]
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   544
                    f.seek(self._dirtyoffset)
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   545
                    f.truncate()
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   546
                    repo.ui.log('tagscache',
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   547
                                'writing %d bytes to %s\n' % (
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   548
                                len(data), _fnodescachefile))
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   549
                    f.write(data)
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   550
                    self._dirtyoffset = None
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   551
                finally:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   552
                    f.close()
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   553
            except (IOError, OSError), inst:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   554
                repo.ui.log('tagscache',
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   555
                            "couldn't write %s: %s\n" % (
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   556
                            _fnodescachefile, inst))
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   557
        finally:
07200e3332a1 tags: extract .hgtags filenodes cache to a standalone file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24532
diff changeset
   558
            lock.release()