mercurial/revlog.py
author Andrew Shadura <bugzilla@tut.by>
Tue, 16 Oct 2012 22:41:44 +0200
changeset 18808 962844e8dd8e
parent 18585 b280f3bfc8a0
child 18986 2f7186400a07
permissions -rw-r--r--
hgk: simplify tags parser As when hg tags is being called without -v option, it returns lines with two elements in each, we can just interate them as if it were a usual Tcl list using foreach and two variables. Line endings and whitespace don't matter when doing so, so we may keep them as is. When we're processing the lines, tag variable is assigned a tag name, and rev is a string in form of revision:hash which we can split on colon. As Tcl8.4 lacks lassign command, and using lindex makes code a bit less readable, we use foreach to iterate over two-element list.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8226
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     1
# revlog.py - storage back-end for mercurial
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     2
#
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     3
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     4
#
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     5
# 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: 10047
diff changeset
     6
# GNU General Public License version 2 or any later version.
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     7
8227
0a9542703300 turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents: 8226
diff changeset
     8
"""Storage back-end for Mercurial.
0a9542703300 turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents: 8226
diff changeset
     9
0a9542703300 turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents: 8226
diff changeset
    10
This provides efficient delta storage with O(1) retrieve and append
0a9542703300 turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents: 8226
diff changeset
    11
and O(changes) merge between branches.
0a9542703300 turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents: 8226
diff changeset
    12
"""
0a9542703300 turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents: 8226
diff changeset
    13
7873
4a4c7f6a5912 cleanup: drop unused imports
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7633
diff changeset
    14
# import stuff from node for others to import from revlog
14393
bdf44e63a94c revlog: stop exporting node.short
Matt Mackall <mpm@selenic.com>
parents: 14371
diff changeset
    15
from node import bin, hex, nullid, nullrev
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
    16
from i18n import _
14365
a8e3931e3fb5 revlog: linearize created changegroups in generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14334
diff changeset
    17
import ancestor, mdiff, parsers, error, util, dagutil
16834
cafd8a8fb713 util: subclass deque for Python 2.4 backwards compatibility
Bryan O'Sullivan <bryano@fb.com>
parents: 16803
diff changeset
    18
import struct, zlib, errno
36
da28286bf6b7 Add smart node lookup by substring or by rev number
mpm@selenic.com
parents: 26
diff changeset
    19
5007
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
    20
_pack = struct.pack
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
    21
_unpack = struct.unpack
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
    22
_compress = zlib.compress
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
    23
_decompress = zlib.decompress
6470
ac0bcd951c2c python 2.6 compatibility: compatibility wrappers for hash functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6264
diff changeset
    24
_sha = util.sha1
5007
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
    25
11746
46ac30b17978 revlog: add shallow header flag
Vishakh H <vsh426@gmail.com>
parents: 11745
diff changeset
    26
# revlog header flags
2072
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 2002
diff changeset
    27
REVLOGV0 = 0
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 2002
diff changeset
    28
REVLOGNG = 1
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
    29
REVLOGNGINLINEDATA = (1 << 16)
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
    30
REVLOGGENERALDELTA = (1 << 17)
2222
c9e264b115e6 Use revlogng and inlined data files by default
mason@suse.com
parents: 2177
diff changeset
    31
REVLOG_DEFAULT_FLAGS = REVLOGNGINLINEDATA
c9e264b115e6 Use revlogng and inlined data files by default
mason@suse.com
parents: 2177
diff changeset
    32
REVLOG_DEFAULT_FORMAT = REVLOGNG
c9e264b115e6 Use revlogng and inlined data files by default
mason@suse.com
parents: 2177
diff changeset
    33
REVLOG_DEFAULT_VERSION = REVLOG_DEFAULT_FORMAT | REVLOG_DEFAULT_FLAGS
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
    34
REVLOGNG_FLAGS = REVLOGNGINLINEDATA | REVLOGGENERALDELTA
11746
46ac30b17978 revlog: add shallow header flag
Vishakh H <vsh426@gmail.com>
parents: 11745
diff changeset
    35
46ac30b17978 revlog: add shallow header flag
Vishakh H <vsh426@gmail.com>
parents: 11745
diff changeset
    36
# revlog index flags
14196
e7483ec3c374 revlog: remove support for punched/shallow
Sune Foldager <cryo@cyanite.org>
parents: 14195
diff changeset
    37
REVIDX_KNOWN_FLAGS = 0
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
    38
10916
9c84395a338e add documentation for revlog._prereadsize
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10914
diff changeset
    39
# max size of revlog with inline data
9c84395a338e add documentation for revlog._prereadsize
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10914
diff changeset
    40
_maxinline = 131072
13253
61c9bc3da402 revlog: remove lazy index
Matt Mackall <mpm@selenic.com>
parents: 13239
diff changeset
    41
_chunksize = 1048576
10913
f2ecc5733c89 revlog: factor out _maxinline global.
Greg Ward <greg-hg@gerg.ca>
parents: 10404
diff changeset
    42
7633
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7365
diff changeset
    43
RevlogError = error.RevlogError
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7365
diff changeset
    44
LookupError = error.LookupError
6703
bacfee67c1a9 LookupError should have same __str__ as RevlogError
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6700
diff changeset
    45
4987
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    46
def getoffset(q):
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    47
    return int(q >> 16)
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    48
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    49
def gettype(q):
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    50
    return int(q & 0xFFFF)
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    51
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    52
def offset_type(offset, type):
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    53
    return long(long(offset) << 16 | type)
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    54
7883
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    55
nullhash = _sha(nullid)
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    56
1091
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    57
def hash(text, p1, p2):
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    58
    """generate a hash from the given text and its parent hashes
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    59
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    60
    This hash combines both the current file contents and its history
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    61
    in a manner that makes it easy to distinguish nodes with the same
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    62
    content in the revision graph.
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    63
    """
7883
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    64
    # As of now, if one of the parent node is null, p2 is null
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    65
    if p2 == nullid:
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    66
        # deep copy of a hash is faster than creating one
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    67
        s = nullhash.copy()
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    68
        s.update(p1)
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    69
    else:
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    70
        # none of the parent nodes are nullid
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    71
        l = [p1, p2]
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    72
        l.sort()
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    73
        s = _sha(l[0])
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    74
        s.update(l[1])
1091
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    75
    s.update(text)
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    76
    return s.digest()
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    77
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    78
def decompress(bin):
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
    79
    """ decompress the given input """
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    80
    if not bin:
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    81
        return bin
112
aea6562add6c Make compression more intelligent:
mpm@selenic.com
parents: 98
diff changeset
    82
    t = bin[0]
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    83
    if t == '\0':
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    84
        return bin
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    85
    if t == 'x':
16883
5e3a1b96dbb0 revlog: zlib.error sent to the user (issue3424)
Brad Hall <bhall@fb.com>
parents: 16834
diff changeset
    86
        try:
5e3a1b96dbb0 revlog: zlib.error sent to the user (issue3424)
Brad Hall <bhall@fb.com>
parents: 16834
diff changeset
    87
            return _decompress(bin)
5e3a1b96dbb0 revlog: zlib.error sent to the user (issue3424)
Brad Hall <bhall@fb.com>
parents: 16834
diff changeset
    88
        except zlib.error, e:
5e3a1b96dbb0 revlog: zlib.error sent to the user (issue3424)
Brad Hall <bhall@fb.com>
parents: 16834
diff changeset
    89
            raise RevlogError(_("revlog decompress error: %s") % str(e))
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    90
    if t == 'u':
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    91
        return bin[1:]
1853
5ac811b720de Fix some problems when working on broken repositories:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1784
diff changeset
    92
    raise RevlogError(_("unknown compression type %r") % t)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    93
18585
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
    94
# index v0:
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
    95
#  4 bytes: offset
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
    96
#  4 bytes: compressed length
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
    97
#  4 bytes: base rev
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
    98
#  4 bytes: link rev
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
    99
# 32 bytes: parent 1 nodeid
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
   100
# 32 bytes: parent 2 nodeid
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
   101
# 32 bytes: nodeid
4987
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   102
indexformatv0 = ">4l20s20s20s"
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   103
v0shaoffset = 56
4918
e017d3a82e1d revlog: raise offset/type helpers to global scope
Matt Mackall <mpm@selenic.com>
parents: 4746
diff changeset
   104
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   105
class revlogoldio(object):
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   106
    def __init__(self):
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   107
        self.size = struct.calcsize(indexformatv0)
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   108
13264
8439526fb407 revlog/parseindex: no need to pass the file around
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13259
diff changeset
   109
    def parseindex(self, data, inline):
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   110
        s = self.size
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   111
        index = []
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   112
        nodemap =  {nullid: nullrev}
4973
a386a6e4fe46 revlog: simplify the v0 parser
Matt Mackall <mpm@selenic.com>
parents: 4972
diff changeset
   113
        n = off = 0
a386a6e4fe46 revlog: simplify the v0 parser
Matt Mackall <mpm@selenic.com>
parents: 4972
diff changeset
   114
        l = len(data)
a386a6e4fe46 revlog: simplify the v0 parser
Matt Mackall <mpm@selenic.com>
parents: 4972
diff changeset
   115
        while off + s <= l:
a386a6e4fe46 revlog: simplify the v0 parser
Matt Mackall <mpm@selenic.com>
parents: 4972
diff changeset
   116
            cur = data[off:off + s]
a386a6e4fe46 revlog: simplify the v0 parser
Matt Mackall <mpm@selenic.com>
parents: 4972
diff changeset
   117
            off += s
5007
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
   118
            e = _unpack(indexformatv0, cur)
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   119
            # transform to revlogv1 format
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   120
            e2 = (offset_type(e[0], 0), e[1], -1, e[2], e[3],
5544
686899a7de5b revlog: make revlogv0 loading more robust against corruption
Matt Mackall <mpm@selenic.com>
parents: 5453
diff changeset
   121
                  nodemap.get(e[4], nullrev), nodemap.get(e[5], nullrev), e[6])
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   122
            index.append(e2)
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   123
            nodemap[e[6]] = n
4973
a386a6e4fe46 revlog: simplify the v0 parser
Matt Mackall <mpm@selenic.com>
parents: 4972
diff changeset
   124
            n += 1
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   125
13265
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   126
        # add the magic null revision at -1
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   127
        index.append((0, 0, 0, -1, -1, -1, -1, nullid))
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   128
4983
4dbcfc6e359e revlog: pull chunkcache back into revlog
Matt Mackall <mpm@selenic.com>
parents: 4982
diff changeset
   129
        return index, nodemap, None
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   130
5338
f87685355c9c revlog: fix revlogio.packentry corner case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5325
diff changeset
   131
    def packentry(self, entry, node, version, rev):
10395
ea52a2d4f42c revlog: don't silently discard revlog flags on revlogv0
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10329
diff changeset
   132
        if gettype(entry[0]):
ea52a2d4f42c revlog: don't silently discard revlog flags on revlogv0
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10329
diff changeset
   133
            raise RevlogError(_("index entry flags need RevlogNG"))
4986
58cc017ec7e0 revlog: abstract out index entry packing
Matt Mackall <mpm@selenic.com>
parents: 4985
diff changeset
   134
        e2 = (getoffset(entry[0]), entry[1], entry[3], entry[4],
58cc017ec7e0 revlog: abstract out index entry packing
Matt Mackall <mpm@selenic.com>
parents: 4985
diff changeset
   135
              node(entry[5]), node(entry[6]), entry[7])
5007
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
   136
        return _pack(indexformatv0, *e2)
4986
58cc017ec7e0 revlog: abstract out index entry packing
Matt Mackall <mpm@selenic.com>
parents: 4985
diff changeset
   137
4987
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   138
# index ng:
11323
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   139
#  6 bytes: offset
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   140
#  2 bytes: flags
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   141
#  4 bytes: compressed length
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   142
#  4 bytes: uncompressed length
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   143
#  4 bytes: base rev
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   144
#  4 bytes: link rev
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   145
#  4 bytes: parent 1 rev
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   146
#  4 bytes: parent 2 rev
4987
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   147
# 32 bytes: nodeid
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   148
indexformatng = ">Qiiiiii20s12x"
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   149
ngshaoffset = 32
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   150
versionformat = ">I"
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   151
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   152
class revlogio(object):
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   153
    def __init__(self):
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   154
        self.size = struct.calcsize(indexformatng)
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   155
13264
8439526fb407 revlog/parseindex: no need to pass the file around
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13259
diff changeset
   156
    def parseindex(self, data, inline):
7109
528b7fc1216c use the new parseindex implementation C in parsers
Bernhard Leiner <bleiner@gmail.com>
parents: 7089
diff changeset
   157
        # call the C implementation to parse the index data
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 13253
diff changeset
   158
        index, cache = parsers.parse_index2(data, inline)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   159
        return index, getattr(index, 'nodemap', None), cache
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   160
5338
f87685355c9c revlog: fix revlogio.packentry corner case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5325
diff changeset
   161
    def packentry(self, entry, node, version, rev):
5007
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
   162
        p = _pack(indexformatng, *entry)
5338
f87685355c9c revlog: fix revlogio.packentry corner case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5325
diff changeset
   163
        if rev == 0:
5007
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
   164
            p = _pack(versionformat, version) + p[4:]
4986
58cc017ec7e0 revlog: abstract out index entry packing
Matt Mackall <mpm@selenic.com>
parents: 4985
diff changeset
   165
        return p
58cc017ec7e0 revlog: abstract out index entry packing
Matt Mackall <mpm@selenic.com>
parents: 4985
diff changeset
   166
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1551
diff changeset
   167
class revlog(object):
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   168
    """
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   169
    the underlying revision storage object
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   170
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   171
    A revlog consists of two parts, an index and the revision data.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   172
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   173
    The index is a file with a fixed record size containing
6912
b92baef99ebf Fixed docstring typos
Martin Geisler <mg@daimi.au.dk>
parents: 6891
diff changeset
   174
    information on each revision, including its nodeid (hash), the
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   175
    nodeids of its parents, the position and offset of its data within
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   176
    the data file, and the revision it's based on. Finally, each entry
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   177
    contains a linkrev entry that can serve as a pointer to external
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   178
    data.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   179
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   180
    The revision data itself is a linear collection of data chunks.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   181
    Each chunk represents a revision and is usually represented as a
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   182
    delta against the previous chunk. To bound lookup time, runs of
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   183
    deltas are limited to about 2 times the length of the original
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   184
    version data. This makes retrieval of a version proportional to
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   185
    its size, or O(1) relative to the number of revisions.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   186
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   187
    Both pieces of the revlog are written to in an append-only
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   188
    fashion, which means we never need to rewrite a file to insert or
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   189
    remove data, and can use some simple techniques to avoid the need
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   190
    for locking while reading.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   191
    """
14251
258fbccf22f5 revlog: remove the last bits of punched/shallow
Sune Foldager <cryo@cyanite.org>
parents: 14219
diff changeset
   192
    def __init__(self, opener, indexfile):
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   193
        """
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   194
        create a revlog object
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   195
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   196
        opener is a function that abstracts the file opening operation
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   197
        and can be used to implement COW semantics or the like.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   198
        """
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   199
        self.indexfile = indexfile
4257
1b5c38e9d7aa revlog: don't pass datafile as an argument
Matt Mackall <mpm@selenic.com>
parents: 4224
diff changeset
   200
        self.datafile = indexfile[:-2] + ".d"
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   201
        self.opener = opener
4984
b4066fcbd6ba revlog: mark cache private
Matt Mackall <mpm@selenic.com>
parents: 4983
diff changeset
   202
        self._cache = None
14296
62e25c63fb3a revlog: fix bug in chainbase cache
Sune Foldager <cryo@cyanite.org>
parents: 14292
diff changeset
   203
        self._basecache = (0, 0)
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   204
        self._chunkcache = (0, '')
4985
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   205
        self.index = []
13258
c2661863f16f revlog: introduce a cache for partial lookups
Matt Mackall <mpm@selenic.com>
parents: 13254
diff changeset
   206
        self._pcache = {}
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   207
        self._nodecache = {nullid: nullrev}
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   208
        self._nodepos = None
4985
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   209
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   210
        v = REVLOG_DEFAULT_VERSION
14960
497819817307 revlog: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14549
diff changeset
   211
        opts = getattr(opener, 'options', None)
497819817307 revlog: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14549
diff changeset
   212
        if opts is not None:
497819817307 revlog: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14549
diff changeset
   213
            if 'revlogv1' in opts:
497819817307 revlog: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14549
diff changeset
   214
                if 'generaldelta' in opts:
14333
31a5973fcf96 revlog: get rid of defversion
Sune Foldager <cryo@cyanite.org>
parents: 14325
diff changeset
   215
                    v |= REVLOGGENERALDELTA
31a5973fcf96 revlog: get rid of defversion
Sune Foldager <cryo@cyanite.org>
parents: 14325
diff changeset
   216
            else:
31a5973fcf96 revlog: get rid of defversion
Sune Foldager <cryo@cyanite.org>
parents: 14325
diff changeset
   217
                v = 0
11928
b69899dbad40 revlog: parentdelta flags for revlog index
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11759
diff changeset
   218
8314
57a41c08feab revlog: preread revlog .i file
Matt Mackall <mpm@selenic.com>
parents: 8312
diff changeset
   219
        i = ''
14334
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14333
diff changeset
   220
        self._initempty = True
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   221
        try:
1784
2e0a288ca93e revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1749
diff changeset
   222
            f = self.opener(self.indexfile)
13253
61c9bc3da402 revlog: remove lazy index
Matt Mackall <mpm@selenic.com>
parents: 13239
diff changeset
   223
            i = f.read()
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13284
diff changeset
   224
            f.close()
4918
e017d3a82e1d revlog: raise offset/type helpers to global scope
Matt Mackall <mpm@selenic.com>
parents: 4746
diff changeset
   225
            if len(i) > 0:
8314
57a41c08feab revlog: preread revlog .i file
Matt Mackall <mpm@selenic.com>
parents: 8312
diff changeset
   226
                v = struct.unpack(versionformat, i[:4])[0]
14334
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14333
diff changeset
   227
                self._initempty = False
1322
b3d44e9b3092 Make revlog constructor more discerning in its treatment of errors.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1232
diff changeset
   228
        except IOError, inst:
b3d44e9b3092 Make revlog constructor more discerning in its treatment of errors.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1232
diff changeset
   229
            if inst.errno != errno.ENOENT:
b3d44e9b3092 Make revlog constructor more discerning in its treatment of errors.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1232
diff changeset
   230
                raise
4985
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   231
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   232
        self.version = v
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   233
        self._inline = v & REVLOGNGINLINEDATA
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
   234
        self._generaldelta = v & REVLOGGENERALDELTA
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
   235
        flags = v & ~0xFFFF
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
   236
        fmt = v & 0xFFFF
4985
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   237
        if fmt == REVLOGV0 and flags:
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   238
            raise RevlogError(_("index %s unknown flags %#04x for format v0")
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   239
                              % (self.indexfile, flags >> 16))
11746
46ac30b17978 revlog: add shallow header flag
Vishakh H <vsh426@gmail.com>
parents: 11745
diff changeset
   240
        elif fmt == REVLOGNG and flags & ~REVLOGNG_FLAGS:
4985
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   241
            raise RevlogError(_("index %s unknown flags %#04x for revlogng")
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   242
                              % (self.indexfile, flags >> 16))
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   243
        elif fmt > REVLOGNG:
3743
3a099154b110 Make revlog error slightly less scary
Matt Mackall <mpm@selenic.com>
parents: 3683
diff changeset
   244
            raise RevlogError(_("index %s unknown format %d")
3680
69cf255a55a1 Indentation cleanups for 2956948b81f3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3679
diff changeset
   245
                              % (self.indexfile, fmt))
4985
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   246
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   247
        self._io = revlogio()
4971
3e6dae278c99 revlog: regroup parsing code
Matt Mackall <mpm@selenic.com>
parents: 4920
diff changeset
   248
        if self.version == REVLOGV0:
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   249
            self._io = revlogoldio()
13265
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   250
        try:
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   251
            d = self._io.parseindex(i, self._inline)
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   252
        except (ValueError, IndexError):
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   253
            raise RevlogError(_("index %s is corrupted") % (self.indexfile))
13268
fff12b3d953a revlog: explicit test and explicit variable names
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13267
diff changeset
   254
        self.index, nodemap, self._chunkcache = d
fff12b3d953a revlog: explicit test and explicit variable names
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13267
diff changeset
   255
        if nodemap is not None:
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   256
            self.nodemap = self._nodecache = nodemap
13265
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   257
        if not self._chunkcache:
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   258
            self._chunkclear()
116
e484cd5ec282 Only use lazy indexing for big indices and avoid the overhead of the
mpm@selenic.com
parents: 115
diff changeset
   259
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   260
    def tip(self):
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   261
        return self.node(len(self.index) - 2)
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   262
    def __len__(self):
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   263
        return len(self.index) - 1
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   264
    def __iter__(self):
17951
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17674
diff changeset
   265
        return iter(xrange(len(self)))
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   266
    def revs(self, start=0, stop=None):
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   267
        """iterate over all rev in this revlog (from start to stop)"""
17975
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   268
        step = 1
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   269
        if stop is not None:
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   270
            if start > stop:
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   271
                step = -1
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   272
            stop += step
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   273
        else:
17975
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   274
            stop = len(self)
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   275
        return xrange(start, stop, step)
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   276
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   277
    @util.propertycache
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   278
    def nodemap(self):
14064
e4bfb9c337f3 remove unused imports and variables
Alexander Solovyov <alexander@solovyov.net>
parents: 13831
diff changeset
   279
        self.rev(self.node(0))
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   280
        return self._nodecache
13259
3b616dfa4b17 revlog: do revlog node->rev mapping by scanning
Matt Mackall <mpm@selenic.com>
parents: 13258
diff changeset
   281
16374
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   282
    def hasnode(self, node):
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   283
        try:
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   284
            self.rev(node)
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   285
            return True
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   286
        except KeyError:
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   287
            return False
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   288
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   289
    def clearcaches(self):
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   290
        try:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   291
            self._nodecache.clearcaches()
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   292
        except AttributeError:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   293
            self._nodecache = {nullid: nullrev}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   294
            self._nodepos = None
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   295
13259
3b616dfa4b17 revlog: do revlog node->rev mapping by scanning
Matt Mackall <mpm@selenic.com>
parents: 13258
diff changeset
   296
    def rev(self, node):
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   297
        try:
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   298
            return self._nodecache[node]
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   299
        except RevlogError:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   300
            # parsers.c radix tree lookup failed
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   301
            raise LookupError(node, self.indexfile, _('no node'))
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   302
        except KeyError:
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   303
            # pure python cache lookup failed
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   304
            n = self._nodecache
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   305
            i = self.index
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   306
            p = self._nodepos
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   307
            if p is None:
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   308
                p = len(i) - 2
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   309
            for r in xrange(p, -1, -1):
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   310
                v = i[r][7]
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   311
                n[v] = r
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   312
                if v == node:
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   313
                    self._nodepos = r - 1
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   314
                    return r
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   315
            raise LookupError(node, self.indexfile, _('no node'))
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   316
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   317
    def node(self, rev):
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   318
        return self.index[rev][7]
7361
9fe97eea5510 linkrev: take a revision number rather than a hash
Matt Mackall <mpm@selenic.com>
parents: 7233
diff changeset
   319
    def linkrev(self, rev):
9fe97eea5510 linkrev: take a revision number rather than a hash
Matt Mackall <mpm@selenic.com>
parents: 7233
diff changeset
   320
        return self.index[rev][4]
2
ecf3fd948051 Handle nullid better for ancestor
mpm@selenic.com
parents: 0
diff changeset
   321
    def parents(self, node):
7363
9d28ff207030 revlog: speed up parents()
Matt Mackall <mpm@selenic.com>
parents: 7362
diff changeset
   322
        i = self.index
9d28ff207030 revlog: speed up parents()
Matt Mackall <mpm@selenic.com>
parents: 7362
diff changeset
   323
        d = i[self.rev(node)]
9d28ff207030 revlog: speed up parents()
Matt Mackall <mpm@selenic.com>
parents: 7362
diff changeset
   324
        return i[d[5]][7], i[d[6]][7] # map revisions to nodes inline
2489
568e58eed096 Add revlog.parentrevs function.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2354
diff changeset
   325
    def parentrevs(self, rev):
4979
06abdaf78788 revlog: add a magic null revision to our index
Matt Mackall <mpm@selenic.com>
parents: 4978
diff changeset
   326
        return self.index[rev][5:7]
2072
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 2002
diff changeset
   327
    def start(self, rev):
5006
c2febf5420e9 revlog: minor chunk speed-up
Matt Mackall <mpm@selenic.com>
parents: 5005
diff changeset
   328
        return int(self.index[rev][0] >> 16)
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   329
    def end(self, rev):
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   330
        return self.start(rev) + self.length(rev)
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   331
    def length(self, rev):
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   332
        return self.index[rev][1]
14252
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   333
    def chainbase(self, rev):
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   334
        index = self.index
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   335
        base = index[rev][3]
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   336
        while base != rev:
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   337
            rev = base
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   338
            base = index[rev][3]
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   339
        return base
11693
ff33f937a7da revlog: add a flags method that returns revision flags
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11670
diff changeset
   340
    def flags(self, rev):
ff33f937a7da revlog: add a flags method that returns revision flags
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11670
diff changeset
   341
        return self.index[rev][0] & 0xFFFF
12024
56a7721ee3ec revlog: add rawsize(), identical to size() but not subclassed by filelog
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12023
diff changeset
   342
    def rawsize(self, rev):
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   343
        """return the length of the uncompressed text for a given revision"""
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   344
        l = self.index[rev][2]
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   345
        if l >= 0:
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   346
            return l
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   347
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   348
        t = self.revision(self.node(rev))
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   349
        return len(t)
12024
56a7721ee3ec revlog: add rawsize(), identical to size() but not subclassed by filelog
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12023
diff changeset
   350
    size = rawsize
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   351
18081
f88c60e740a1 revlog.ancestors: add support for including revs
Siddharth Agarwal <sid0@fb.com>
parents: 17975
diff changeset
   352
    def ancestors(self, revs, stoprev=0, inclusive=False):
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   353
        """Generate the ancestors of 'revs' in reverse topological order.
16868
eb88ed4269c5 revlog: add optional stoprev arg to revlog.ancestors()
Joshua Redstone <joshua.redstone@fb.com>
parents: 16867
diff changeset
   354
        Does not generate revs lower than stoprev.
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   355
18090
9abc55ef85b5 revlog: move ancestor generation out to a new class
Siddharth Agarwal <sid0@fb.com>
parents: 18083
diff changeset
   356
        See the documentation for ancestor.lazyancestors for more details."""
18081
f88c60e740a1 revlog.ancestors: add support for including revs
Siddharth Agarwal <sid0@fb.com>
parents: 17975
diff changeset
   357
18090
9abc55ef85b5 revlog: move ancestor generation out to a new class
Siddharth Agarwal <sid0@fb.com>
parents: 18083
diff changeset
   358
        return ancestor.lazyancestors(self, revs, stoprev=stoprev,
9abc55ef85b5 revlog: move ancestor generation out to a new class
Siddharth Agarwal <sid0@fb.com>
parents: 18083
diff changeset
   359
                                      inclusive=inclusive)
6872
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   360
16867
1093ad1e8903 revlog: descendants(*revs) becomes descendants(revs) (API)
Bryan O'Sullivan <bryano@fb.com>
parents: 16866
diff changeset
   361
    def descendants(self, revs):
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   362
        """Generate the descendants of 'revs' in revision order.
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   363
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   364
        Yield a sequence of revision numbers starting with a child of
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   365
        some rev in revs, i.e., each revision is *not* considered a
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   366
        descendant of itself.  Results are ordered by revision number (a
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   367
        topological sort)."""
12950
2405b4a5964a revlog: fix descendants() if nullrev is in revs
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12949
diff changeset
   368
        first = min(revs)
2405b4a5964a revlog: fix descendants() if nullrev is in revs
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12949
diff changeset
   369
        if first == nullrev:
2405b4a5964a revlog: fix descendants() if nullrev is in revs
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12949
diff changeset
   370
            for i in self:
2405b4a5964a revlog: fix descendants() if nullrev is in revs
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12949
diff changeset
   371
                yield i
2405b4a5964a revlog: fix descendants() if nullrev is in revs
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12949
diff changeset
   372
            return
2405b4a5964a revlog: fix descendants() if nullrev is in revs
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12949
diff changeset
   373
8150
bbc24c0753a0 util: use built-in set and frozenset
Martin Geisler <mg@lazybytes.net>
parents: 8073
diff changeset
   374
        seen = set(revs)
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   375
        for i in self.revs(start=first + 1):
6872
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   376
            for x in self.parentrevs(i):
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   377
                if x != nullrev and x in seen:
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   378
                    seen.add(i)
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   379
                    yield i
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   380
                    break
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   381
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   382
    def findcommonmissing(self, common=None, heads=None):
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   383
        """Return a tuple of the ancestors of common and the ancestors of heads
15835
fa15869bf95c revlog: improve docstring for findcommonmissing
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15827
diff changeset
   384
        that are not ancestors of common. In revset terminology, we return the
fa15869bf95c revlog: improve docstring for findcommonmissing
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15827
diff changeset
   385
        tuple:
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   386
15835
fa15869bf95c revlog: improve docstring for findcommonmissing
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15827
diff changeset
   387
          ::common, (::heads) - (::common)
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   388
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   389
        The list is sorted by revision number, meaning it is
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   390
        topologically sorted.
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   391
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   392
        'heads' and 'common' are both lists of node IDs.  If heads is
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   393
        not supplied, uses all of the revlog's heads.  If common is not
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   394
        supplied, uses nullid."""
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   395
        if common is None:
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   396
            common = [nullid]
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   397
        if heads is None:
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   398
            heads = self.heads()
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   399
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   400
        common = [self.rev(n) for n in common]
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   401
        heads = [self.rev(n) for n in heads]
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   402
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   403
        # we want the ancestors, but inclusive
16866
91f3ac205816 revlog: ancestors(*revs) becomes ancestors(revs) (API)
Bryan O'Sullivan <bryano@fb.com>
parents: 16834
diff changeset
   404
        has = set(self.ancestors(common))
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8150
diff changeset
   405
        has.add(nullrev)
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8150
diff changeset
   406
        has.update(common)
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   407
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   408
        # take all ancestors from heads that aren't in has
8453
d1ca637b0773 revlog.missing(): use sets instead of a dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8391
diff changeset
   409
        missing = set()
16834
cafd8a8fb713 util: subclass deque for Python 2.4 backwards compatibility
Bryan O'Sullivan <bryano@fb.com>
parents: 16803
diff changeset
   410
        visit = util.deque(r for r in heads if r not in has)
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   411
        while visit:
16803
107a3270a24a cleanup: use the deque type where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   412
            r = visit.popleft()
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   413
            if r in missing:
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   414
                continue
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   415
            else:
8453
d1ca637b0773 revlog.missing(): use sets instead of a dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8391
diff changeset
   416
                missing.add(r)
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   417
                for p in self.parentrevs(r):
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   418
                    if p not in has:
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   419
                        visit.append(p)
8453
d1ca637b0773 revlog.missing(): use sets instead of a dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8391
diff changeset
   420
        missing = list(missing)
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   421
        missing.sort()
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   422
        return has, [self.node(r) for r in missing]
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   423
17972
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   424
    def findmissingrevs(self, common=None, heads=None):
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   425
        """Return the revision numbers of the ancestors of heads that
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   426
        are not ancestors of common.
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   427
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   428
        More specifically, return a list of revision numbers corresponding to
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   429
        nodes N such that every N satisfies the following constraints:
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   430
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   431
          1. N is an ancestor of some node in 'heads'
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   432
          2. N is not an ancestor of any node in 'common'
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   433
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   434
        The list is sorted by revision number, meaning it is
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   435
        topologically sorted.
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   436
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   437
        'heads' and 'common' are both lists of revision numbers.  If heads is
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   438
        not supplied, uses all of the revlog's heads.  If common is not
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   439
        supplied, uses nullid."""
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   440
        if common is None:
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   441
            common = [nullrev]
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   442
        if heads is None:
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   443
            heads = self.headrevs()
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   444
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   445
        return ancestor.missingancestors(heads, common, self.parentrevs)
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   446
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   447
    def findmissing(self, common=None, heads=None):
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   448
        """Return the ancestors of heads that are not ancestors of common.
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   449
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   450
        More specifically, return a list of nodes N such that every N
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   451
        satisfies the following constraints:
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   452
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   453
          1. N is an ancestor of some node in 'heads'
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   454
          2. N is not an ancestor of any node in 'common'
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   455
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   456
        The list is sorted by revision number, meaning it is
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   457
        topologically sorted.
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   458
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   459
        'heads' and 'common' are both lists of node IDs.  If heads is
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   460
        not supplied, uses all of the revlog's heads.  If common is not
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   461
        supplied, uses nullid."""
17971
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   462
        if common is None:
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   463
            common = [nullid]
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   464
        if heads is None:
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   465
            heads = self.heads()
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   466
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   467
        common = [self.rev(n) for n in common]
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   468
        heads = [self.rev(n) for n in heads]
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   469
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   470
        return [self.node(r) for r in
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   471
                ancestor.missingancestors(heads, common, self.parentrevs)]
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   472
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   473
    def nodesbetween(self, roots=None, heads=None):
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   474
        """Return a topological path from 'roots' to 'heads'.
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   475
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   476
        Return a tuple (nodes, outroots, outheads) where 'nodes' is a
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   477
        topologically sorted list of all nodes N that satisfy both of
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   478
        these constraints:
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   479
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   480
          1. N is a descendant of some node in 'roots'
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   481
          2. N is an ancestor of some node in 'heads'
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   482
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   483
        Every node is considered to be both a descendant and an ancestor
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   484
        of itself, so every reachable node in 'roots' and 'heads' will be
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   485
        included in 'nodes'.
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   486
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   487
        'outroots' is the list of reachable nodes in 'roots', i.e., the
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   488
        subset of 'roots' that is returned in 'nodes'.  Likewise,
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   489
        'outheads' is the subset of 'heads' that is also in 'nodes'.
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   490
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   491
        'roots' and 'heads' are both lists of node IDs.  If 'roots' is
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   492
        unspecified, uses nullid as the only root.  If 'heads' is
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   493
        unspecified, uses list of all of the revlog's heads."""
1463
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   494
        nonodes = ([], [], [])
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   495
        if roots is not None:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   496
            roots = list(roots)
1463
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   497
            if not roots:
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   498
                return nonodes
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   499
            lowestrev = min([self.rev(n) for n in roots])
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   500
        else:
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   501
            roots = [nullid] # Everybody's a descendant of nullid
3578
3b4e00cba57a Define and use nullrev (revision of nullid) instead of -1.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3508
diff changeset
   502
            lowestrev = nullrev
3b4e00cba57a Define and use nullrev (revision of nullid) instead of -1.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3508
diff changeset
   503
        if (lowestrev == nullrev) and (heads is None):
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   504
            # We want _all_ the nodes!
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   505
            return ([self.node(r) for r in self], [nullid], list(self.heads()))
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   506
        if heads is None:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   507
            # All nodes are ancestors, so the latest ancestor is the last
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   508
            # node.
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   509
            highestrev = len(self) - 1
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   510
            # Set ancestors to None to signal that every node is an ancestor.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   511
            ancestors = None
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   512
            # Set heads to an empty dictionary for later discovery of heads
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   513
            heads = {}
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   514
        else:
1463
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   515
            heads = list(heads)
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   516
            if not heads:
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   517
                return nonodes
8464
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   518
            ancestors = set()
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   519
            # Turn heads into a dictionary so we can remove 'fake' heads.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   520
            # Also, later we will be using it to filter out the heads we can't
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   521
            # find from roots.
14219
c33427080671 revlog: use real Booleans instead of 0/1 in nodesbetween
Martin Geisler <mg@aragost.com>
parents: 14208
diff changeset
   522
            heads = dict.fromkeys(heads, False)
3360
ef8307585b41 nodesbetween: fix a bug with duplicate heads
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3335
diff changeset
   523
            # Start at the top and keep marking parents until we're done.
8163
62d7287fe6b0 rebase, revlog: use set(x) instead of set(x.keys())
Martin Geisler <mg@lazybytes.net>
parents: 8153
diff changeset
   524
            nodestotag = set(heads)
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   525
            # Remember where the top was so we can use it as a limit later.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   526
            highestrev = max([self.rev(n) for n in nodestotag])
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   527
            while nodestotag:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   528
                # grab a node to tag
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   529
                n = nodestotag.pop()
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   530
                # Never tag nullid
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   531
                if n == nullid:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   532
                    continue
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   533
                # A node's revision number represents its place in a
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   534
                # topologically sorted list of nodes.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   535
                r = self.rev(n)
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   536
                if r >= lowestrev:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   537
                    if n not in ancestors:
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   538
                        # If we are possibly a descendant of one of the roots
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   539
                        # and we haven't already been marked as an ancestor
8464
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   540
                        ancestors.add(n) # Mark as ancestor
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   541
                        # Add non-nullid parents to list of nodes to tag.
8153
616f20e1004a revlog: let nodestotag be a set instead of a list
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
   542
                        nodestotag.update([p for p in self.parents(n) if
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   543
                                           p != nullid])
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   544
                    elif n in heads: # We've seen it before, is it a fake head?
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   545
                        # So it is, real heads should not be the ancestors of
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   546
                        # any other heads.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   547
                        heads.pop(n)
1459
106fdec8e1fb Fix small bug in nodesbetween if heads is [nullid].
Eric Hopper <hopper@omnifarious.org>
parents: 1458
diff changeset
   548
            if not ancestors:
1463
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   549
                return nonodes
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   550
            # Now that we have our set of ancestors, we want to remove any
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   551
            # roots that are not ancestors.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   552
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   553
            # If one of the roots was nullid, everything is included anyway.
3578
3b4e00cba57a Define and use nullrev (revision of nullid) instead of -1.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3508
diff changeset
   554
            if lowestrev > nullrev:
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   555
                # But, since we weren't, let's recompute the lowest rev to not
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   556
                # include roots that aren't ancestors.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   557
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   558
                # Filter out roots that aren't ancestors of heads
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   559
                roots = [n for n in roots if n in ancestors]
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   560
                # Recompute the lowest revision
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   561
                if roots:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   562
                    lowestrev = min([self.rev(n) for n in roots])
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   563
                else:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   564
                    # No more roots?  Return empty list
1463
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   565
                    return nonodes
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   566
            else:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   567
                # We are descending from nullid, and don't need to care about
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   568
                # any other roots.
3578
3b4e00cba57a Define and use nullrev (revision of nullid) instead of -1.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3508
diff changeset
   569
                lowestrev = nullrev
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   570
                roots = [nullid]
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8150
diff changeset
   571
        # Transform our roots list into a set.
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   572
        descendants = set(roots)
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   573
        # Also, keep the original roots so we can filter out roots that aren't
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   574
        # 'real' roots (i.e. are descended from other roots).
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   575
        roots = descendants.copy()
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   576
        # Our topologically sorted list of output nodes.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   577
        orderedout = []
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   578
        # Don't start at nullid since we don't want nullid in our output list,
17483
fe3b26048140 spelling: descendants
timeless@mozdev.org
parents: 17150
diff changeset
   579
        # and if nullid shows up in descendants, empty parents will look like
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   580
        # they're descendants.
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   581
        for r in self.revs(start=max(lowestrev, 0), stop=highestrev + 1):
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   582
            n = self.node(r)
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   583
            isdescendant = False
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   584
            if lowestrev == nullrev:  # Everybody is a descendant of nullid
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   585
                isdescendant = True
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   586
            elif n in descendants:
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   587
                # n is already a descendant
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   588
                isdescendant = True
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   589
                # This check only needs to be done here because all the roots
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   590
                # will start being marked is descendants before the loop.
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   591
                if n in roots:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   592
                    # If n was a root, check if it's a 'real' root.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   593
                    p = tuple(self.parents(n))
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   594
                    # If any of its parents are descendants, it's not a root.
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   595
                    if (p[0] in descendants) or (p[1] in descendants):
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8150
diff changeset
   596
                        roots.remove(n)
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   597
            else:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   598
                p = tuple(self.parents(n))
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   599
                # A node is a descendant if either of its parents are
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   600
                # descendants.  (We seeded the dependents list with the roots
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   601
                # up there, remember?)
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   602
                if (p[0] in descendants) or (p[1] in descendants):
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   603
                    descendants.add(n)
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   604
                    isdescendant = True
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   605
            if isdescendant and ((ancestors is None) or (n in ancestors)):
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   606
                # Only include nodes that are both descendants and ancestors.
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   607
                orderedout.append(n)
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   608
                if (ancestors is not None) and (n in heads):
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   609
                    # We're trying to figure out which heads are reachable
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   610
                    # from roots.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   611
                    # Mark this head as having been reached
14219
c33427080671 revlog: use real Booleans instead of 0/1 in nodesbetween
Martin Geisler <mg@aragost.com>
parents: 14208
diff changeset
   612
                    heads[n] = True
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   613
                elif ancestors is None:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   614
                    # Otherwise, we're trying to discover the heads.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   615
                    # Assume this is a head because if it isn't, the next step
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   616
                    # will eventually remove it.
14219
c33427080671 revlog: use real Booleans instead of 0/1 in nodesbetween
Martin Geisler <mg@aragost.com>
parents: 14208
diff changeset
   617
                    heads[n] = True
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   618
                    # But, obviously its parents aren't.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   619
                    for p in self.parents(n):
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   620
                        heads.pop(p, None)
14219
c33427080671 revlog: use real Booleans instead of 0/1 in nodesbetween
Martin Geisler <mg@aragost.com>
parents: 14208
diff changeset
   621
        heads = [n for n, flag in heads.iteritems() if flag]
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8150
diff changeset
   622
        roots = list(roots)
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   623
        assert orderedout
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   624
        assert roots
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   625
        assert heads
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   626
        return (orderedout, roots, heads)
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   627
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   628
    def headrevs(self):
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16762
diff changeset
   629
        try:
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16762
diff changeset
   630
            return self.index.headrevs()
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16762
diff changeset
   631
        except AttributeError:
17674
e69274f8d444 clfilter: split `revlog.headrevs` C call from python code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17673
diff changeset
   632
            return self._headrevs()
e69274f8d444 clfilter: split `revlog.headrevs` C call from python code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17673
diff changeset
   633
e69274f8d444 clfilter: split `revlog.headrevs` C call from python code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17673
diff changeset
   634
    def _headrevs(self):
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   635
        count = len(self)
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   636
        if not count:
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   637
            return [nullrev]
17673
d686c6876ef6 clfilter: handle non contiguous iteration in `revlov.headrevs`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17672
diff changeset
   638
        # we won't iter over filtered rev so nobody is a head at start
d686c6876ef6 clfilter: handle non contiguous iteration in `revlov.headrevs`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17672
diff changeset
   639
        ishead = [0] * (count + 1)
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   640
        index = self.index
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   641
        for r in self:
17673
d686c6876ef6 clfilter: handle non contiguous iteration in `revlov.headrevs`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17672
diff changeset
   642
            ishead[r] = 1  # I may be an head
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   643
            e = index[r]
17673
d686c6876ef6 clfilter: handle non contiguous iteration in `revlov.headrevs`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17672
diff changeset
   644
            ishead[e[5]] = ishead[e[6]] = 0  # my parent are not
d686c6876ef6 clfilter: handle non contiguous iteration in `revlov.headrevs`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17672
diff changeset
   645
        return [r for r, val in enumerate(ishead) if val]
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   646
3923
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   647
    def heads(self, start=None, stop=None):
1550
ccb9b62de892 add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1535
diff changeset
   648
        """return the list of all nodes that have no children
1551
e793cbc8be00 Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1550
diff changeset
   649
e793cbc8be00 Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1550
diff changeset
   650
        if start is specified, only heads that are descendants of
e793cbc8be00 Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1550
diff changeset
   651
        start will be returned
3923
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   652
        if stop is specified, it will consider all the revs from stop
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   653
        as if they had no children
1551
e793cbc8be00 Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1550
diff changeset
   654
        """
4991
9c8c42bcf17a revlog: implement a fast path for heads
Matt Mackall <mpm@selenic.com>
parents: 4990
diff changeset
   655
        if start is None and stop is None:
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   656
            if not len(self):
4991
9c8c42bcf17a revlog: implement a fast path for heads
Matt Mackall <mpm@selenic.com>
parents: 4990
diff changeset
   657
                return [nullid]
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   658
            return [self.node(r) for r in self.headrevs()]
4991
9c8c42bcf17a revlog: implement a fast path for heads
Matt Mackall <mpm@selenic.com>
parents: 4990
diff changeset
   659
1551
e793cbc8be00 Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1550
diff changeset
   660
        if start is None:
e793cbc8be00 Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1550
diff changeset
   661
            start = nullid
3923
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   662
        if stop is None:
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   663
            stop = []
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8150
diff changeset
   664
        stoprevs = set([self.rev(n) for n in stop])
1550
ccb9b62de892 add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1535
diff changeset
   665
        startrev = self.rev(start)
8464
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   666
        reachable = set((startrev,))
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   667
        heads = set((startrev,))
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   668
2490
6ff82ec1f4b8 Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2489
diff changeset
   669
        parentrevs = self.parentrevs
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   670
        for r in self.revs(start=startrev + 1):
2490
6ff82ec1f4b8 Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2489
diff changeset
   671
            for p in parentrevs(r):
6ff82ec1f4b8 Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2489
diff changeset
   672
                if p in reachable:
3923
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   673
                    if r not in stoprevs:
8464
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   674
                        reachable.add(r)
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   675
                    heads.add(r)
3923
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   676
                if p in heads and p not in stoprevs:
8464
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   677
                    heads.remove(p)
3923
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   678
2490
6ff82ec1f4b8 Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2489
diff changeset
   679
        return [self.node(r) for r in heads]
370
c90385d82aec revlog: add a children function
mpm@selenic.com
parents: 330
diff changeset
   680
c90385d82aec revlog: add a children function
mpm@selenic.com
parents: 330
diff changeset
   681
    def children(self, node):
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   682
        """find the children of a given node"""
370
c90385d82aec revlog: add a children function
mpm@selenic.com
parents: 330
diff changeset
   683
        c = []
c90385d82aec revlog: add a children function
mpm@selenic.com
parents: 330
diff changeset
   684
        p = self.rev(node)
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   685
        for r in self.revs(start=p + 1):
4746
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   686
            prevs = [pr for pr in self.parentrevs(r) if pr != nullrev]
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   687
            if prevs:
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   688
                for pr in prevs:
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   689
                    if pr == p:
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   690
                        c.append(self.node(r))
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   691
            elif p == nullrev:
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   692
                c.append(self.node(r))
370
c90385d82aec revlog: add a children function
mpm@selenic.com
parents: 330
diff changeset
   693
        return c
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 484
diff changeset
   694
10897
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   695
    def descendant(self, start, end):
12949
6878eaa5a40d revlog: if start is nullrev, end is always a descendant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12890
diff changeset
   696
        if start == nullrev:
6878eaa5a40d revlog: if start is nullrev, end is always a descendant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12890
diff changeset
   697
            return True
16867
1093ad1e8903 revlog: descendants(*revs) becomes descendants(revs) (API)
Bryan O'Sullivan <bryano@fb.com>
parents: 16866
diff changeset
   698
        for i in self.descendants([start]):
10897
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   699
            if i == end:
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   700
                return True
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   701
            elif i > end:
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   702
                break
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   703
        return False
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   704
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   705
    def ancestor(self, a, b):
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   706
        """calculate the least common ancestor of nodes a and b"""
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   707
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   708
        # fast path, check if it is a descendant
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   709
        a, b = self.rev(a), self.rev(b)
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   710
        start, end = sorted((a, b))
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   711
        if self.descendant(start, end):
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   712
            return self.node(start)
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   713
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   714
        def parents(rev):
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   715
            return [p for p in self.parentrevs(rev) if p != nullrev]
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   716
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   717
        c = ancestor.ancestor(a, b, parents)
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   718
        if c is None:
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   719
            return nullid
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   720
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   721
        return self.node(c)
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   722
3453
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   723
    def _match(self, id):
16762
93f8b9565257 revlog: don't handle long for revision matching
Matt Mackall <mpm@selenic.com>
parents: 16686
diff changeset
   724
        if isinstance(id, int):
3156
d01e4cb2f5f2 cleanups in revlog.lookup
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3139
diff changeset
   725
            # rev
2641
156fb1feab62 lookup should allow -1 to represent nullid (if passed an int as arg)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2600
diff changeset
   726
            return self.node(id)
3438
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   727
        if len(id) == 20:
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   728
            # possibly a binary node
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   729
            # odds of a binary node being all hex in ASCII are 1 in 10**25
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   730
            try:
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   731
                node = id
7874
d812029cda85 cleanup: drop variables for unused return values
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7873
diff changeset
   732
                self.rev(node) # quick search the index
3438
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   733
                return node
3930
01d98d68d697 Add revlog.LookupError exception, and use it instead of RevlogError.
Brendan Cully <brendan@kublai.com>
parents: 3928
diff changeset
   734
            except LookupError:
3438
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   735
                pass # may be partial hex id
36
da28286bf6b7 Add smart node lookup by substring or by rev number
mpm@selenic.com
parents: 26
diff changeset
   736
        try:
3156
d01e4cb2f5f2 cleanups in revlog.lookup
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3139
diff changeset
   737
            # str(rev)
36
da28286bf6b7 Add smart node lookup by substring or by rev number
mpm@selenic.com
parents: 26
diff changeset
   738
            rev = int(id)
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   739
            if str(rev) != id:
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   740
                raise ValueError
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   741
            if rev < 0:
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   742
                rev = len(self) + rev
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   743
            if rev < 0 or rev >= len(self):
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   744
                raise ValueError
36
da28286bf6b7 Add smart node lookup by substring or by rev number
mpm@selenic.com
parents: 26
diff changeset
   745
            return self.node(rev)
469
e205194ca7ef Various node id lookup tweaks
mpm@selenic.com
parents: 451
diff changeset
   746
        except (ValueError, OverflowError):
3156
d01e4cb2f5f2 cleanups in revlog.lookup
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3139
diff changeset
   747
            pass
3453
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   748
        if len(id) == 40:
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   749
            try:
3438
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   750
                # a full hex nodeid?
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   751
                node = bin(id)
7874
d812029cda85 cleanup: drop variables for unused return values
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7873
diff changeset
   752
                self.rev(node)
3157
4fe41a9e4591 optimize revlog.lookup when passed hex(node)[:...]
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3156
diff changeset
   753
                return node
7062
efc579fdaf69 provide nicer feedback when an unknown node id is passed to a command
Sune Foldager <cryo@cyanite.org>
parents: 6912
diff changeset
   754
            except (TypeError, LookupError):
3453
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   755
                pass
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   756
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   757
    def _partialmatch(self, id):
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   758
        try:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   759
            return self.index.partialmatch(id)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   760
        except RevlogError:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   761
            # parsers.c radix tree lookup gave multiple matches
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   762
            raise LookupError(id, self.indexfile, _("ambiguous identifier"))
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   763
        except (AttributeError, ValueError):
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   764
            # we are pure python, or key was too short to search radix tree
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   765
            pass
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   766
13258
c2661863f16f revlog: introduce a cache for partial lookups
Matt Mackall <mpm@selenic.com>
parents: 13254
diff changeset
   767
        if id in self._pcache:
c2661863f16f revlog: introduce a cache for partial lookups
Matt Mackall <mpm@selenic.com>
parents: 13254
diff changeset
   768
            return self._pcache[id]
c2661863f16f revlog: introduce a cache for partial lookups
Matt Mackall <mpm@selenic.com>
parents: 13254
diff changeset
   769
3453
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   770
        if len(id) < 40:
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   771
            try:
3438
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   772
                # hex(node)[:...]
9029
0001e49f1c11 compat: use // for integer division
Alejandro Santos <alejolp@alejolp.com>
parents: 8658
diff changeset
   773
                l = len(id) // 2  # grab an even number of digits
13259
3b616dfa4b17 revlog: do revlog node->rev mapping by scanning
Matt Mackall <mpm@selenic.com>
parents: 13258
diff changeset
   774
                prefix = bin(id[:l * 2])
3b616dfa4b17 revlog: do revlog node->rev mapping by scanning
Matt Mackall <mpm@selenic.com>
parents: 13258
diff changeset
   775
                nl = [e[7] for e in self.index if e[7].startswith(prefix)]
7365
ec3aafa84d44 lookup: speed up partial lookup
Matt Mackall <mpm@selenic.com>
parents: 7363
diff changeset
   776
                nl = [n for n in nl if hex(n).startswith(id)]
ec3aafa84d44 lookup: speed up partial lookup
Matt Mackall <mpm@selenic.com>
parents: 7363
diff changeset
   777
                if len(nl) > 0:
ec3aafa84d44 lookup: speed up partial lookup
Matt Mackall <mpm@selenic.com>
parents: 7363
diff changeset
   778
                    if len(nl) == 1:
13258
c2661863f16f revlog: introduce a cache for partial lookups
Matt Mackall <mpm@selenic.com>
parents: 13254
diff changeset
   779
                        self._pcache[id] = nl[0]
7365
ec3aafa84d44 lookup: speed up partial lookup
Matt Mackall <mpm@selenic.com>
parents: 7363
diff changeset
   780
                        return nl[0]
ec3aafa84d44 lookup: speed up partial lookup
Matt Mackall <mpm@selenic.com>
parents: 7363
diff changeset
   781
                    raise LookupError(id, self.indexfile,
ec3aafa84d44 lookup: speed up partial lookup
Matt Mackall <mpm@selenic.com>
parents: 7363
diff changeset
   782
                                      _('ambiguous identifier'))
ec3aafa84d44 lookup: speed up partial lookup
Matt Mackall <mpm@selenic.com>
parents: 7363
diff changeset
   783
                return None
3453
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   784
            except TypeError:
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   785
                pass
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   786
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   787
    def lookup(self, id):
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   788
        """locate a node based on:
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   789
            - revision number or str(revision number)
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   790
            - nodeid or subset of hex nodeid
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   791
        """
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   792
        n = self._match(id)
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   793
        if n is not None:
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   794
            return n
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   795
        n = self._partialmatch(id)
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   796
        if n:
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   797
            return n
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 484
diff changeset
   798
6228
c0c4c7b1e8d3 revlog: report node and file when lookup fails
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
   799
        raise LookupError(id, self.indexfile, _('no match found'))
36
da28286bf6b7 Add smart node lookup by substring or by rev number
mpm@selenic.com
parents: 26
diff changeset
   800
2890
5df3e5cf16bc Move cmp bits from filelog to revlog
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
   801
    def cmp(self, node, text):
11539
a463e3c50212 cmp: document the fact that we return True if content is different
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11323
diff changeset
   802
        """compare text with a given file revision
a463e3c50212 cmp: document the fact that we return True if content is different
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11323
diff changeset
   803
a463e3c50212 cmp: document the fact that we return True if content is different
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11323
diff changeset
   804
        returns True if text is different than what is stored.
a463e3c50212 cmp: document the fact that we return True if content is different
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11323
diff changeset
   805
        """
2890
5df3e5cf16bc Move cmp bits from filelog to revlog
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
   806
        p1, p2 = self.parents(node)
5df3e5cf16bc Move cmp bits from filelog to revlog
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
   807
        return hash(text, p1, p2) != node
5df3e5cf16bc Move cmp bits from filelog to revlog
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
   808
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   809
    def _addchunk(self, offset, data):
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   810
        o, d = self._chunkcache
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   811
        # try to add to existing cache
13253
61c9bc3da402 revlog: remove lazy index
Matt Mackall <mpm@selenic.com>
parents: 13239
diff changeset
   812
        if o + len(d) == offset and len(d) + len(data) < _chunksize:
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   813
            self._chunkcache = o, d + data
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   814
        else:
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   815
            self._chunkcache = offset, data
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   816
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   817
    def _loadchunk(self, offset, length):
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   818
        if self._inline:
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   819
            df = self.opener(self.indexfile)
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   820
        else:
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   821
            df = self.opener(self.datafile)
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   822
16533
95698ee29181 revlog: backout e5750c6716eb
Matt Mackall <mpm@selenic.com>
parents: 16435
diff changeset
   823
        readahead = max(65536, length)
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   824
        df.seek(offset)
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   825
        d = df.read(readahead)
15407
ee112eb69d2a misc: adding missing file close() calls
Matt Mackall <mpm@selenic.com>
parents: 15057
diff changeset
   826
        df.close()
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   827
        self._addchunk(offset, d)
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   828
        if readahead > length:
16423
a150923b49ba revlog: avoid an expensive string copy
Bryan O'Sullivan <bryano@fb.com>
parents: 16418
diff changeset
   829
            return util.buffer(d, 0, length)
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   830
        return d
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   831
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   832
    def _getchunk(self, offset, length):
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   833
        o, d = self._chunkcache
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   834
        l = len(d)
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   835
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   836
        # is it in the cache?
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   837
        cachestart = offset - o
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   838
        cacheend = cachestart + length
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   839
        if cachestart >= 0 and cacheend <= l:
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   840
            if cachestart == 0 and cacheend == l:
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   841
                return d # avoid a copy
16423
a150923b49ba revlog: avoid an expensive string copy
Bryan O'Sullivan <bryano@fb.com>
parents: 16418
diff changeset
   842
            return util.buffer(d, cachestart, cacheend - cachestart)
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   843
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   844
        return self._loadchunk(offset, length)
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   845
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   846
    def _chunkraw(self, startrev, endrev):
8318
6b8513f8274a revlog: add cache priming for reconstructing delta chains
Matt Mackall <mpm@selenic.com>
parents: 8317
diff changeset
   847
        start = self.start(startrev)
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   848
        length = self.end(endrev) - start
8318
6b8513f8274a revlog: add cache priming for reconstructing delta chains
Matt Mackall <mpm@selenic.com>
parents: 8317
diff changeset
   849
        if self._inline:
6b8513f8274a revlog: add cache priming for reconstructing delta chains
Matt Mackall <mpm@selenic.com>
parents: 8317
diff changeset
   850
            start += (startrev + 1) * self._io.size
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   851
        return self._getchunk(start, length)
8318
6b8513f8274a revlog: add cache priming for reconstructing delta chains
Matt Mackall <mpm@selenic.com>
parents: 8317
diff changeset
   852
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   853
    def _chunk(self, rev):
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   854
        return decompress(self._chunkraw(rev, rev))
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   855
14075
bc101902a68d revlog: introduce _chunkbase to allow filelog to override
Sune Foldager <cryo@cyanite.org>
parents: 14064
diff changeset
   856
    def _chunkbase(self, rev):
bc101902a68d revlog: introduce _chunkbase to allow filelog to override
Sune Foldager <cryo@cyanite.org>
parents: 14064
diff changeset
   857
        return self._chunk(rev)
bc101902a68d revlog: introduce _chunkbase to allow filelog to override
Sune Foldager <cryo@cyanite.org>
parents: 14064
diff changeset
   858
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   859
    def _chunkclear(self):
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   860
        self._chunkcache = (0, '')
1598
14d1f1868bf6 cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
   861
11929
1839a7518b0d revlog: deltachain() returns chain of revs need to construct a revision
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11928
diff changeset
   862
    def deltaparent(self, rev):
14195
0013d3eeb826 revlog: remove support for parentdelta
Sune Foldager <cryo@cyanite.org>
parents: 14164
diff changeset
   863
        """return deltaparent of the given revision"""
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
   864
        base = self.index[rev][3]
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
   865
        if base == rev:
14208
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 14196
diff changeset
   866
            return nullrev
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
   867
        elif self._generaldelta:
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
   868
            return base
14208
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 14196
diff changeset
   869
        else:
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 14196
diff changeset
   870
            return rev - 1
11929
1839a7518b0d revlog: deltachain() returns chain of revs need to construct a revision
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11928
diff changeset
   871
1941
7518823709a2 revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1853
diff changeset
   872
    def revdiff(self, rev1, rev2):
7518823709a2 revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1853
diff changeset
   873
        """return or calculate a delta between two revisions"""
14208
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 14196
diff changeset
   874
        if rev1 != nullrev and self.deltaparent(rev2) == rev1:
16423
a150923b49ba revlog: avoid an expensive string copy
Bryan O'Sullivan <bryano@fb.com>
parents: 16418
diff changeset
   875
            return str(self._chunk(rev2))
5005
72082bfced9a revlog: minor revdiff reorganization
Matt Mackall <mpm@selenic.com>
parents: 5004
diff changeset
   876
16424
ff63d71ac8ab revlog: drop some unneeded rev.node calls in revdiff
Matt Mackall <mpm@selenic.com>
parents: 16423
diff changeset
   877
        return mdiff.textdiff(self.revision(rev1),
ff63d71ac8ab revlog: drop some unneeded rev.node calls in revdiff
Matt Mackall <mpm@selenic.com>
parents: 16423
diff changeset
   878
                              self.revision(rev2))
119
c7a66f9752a4 Add code to retrieve or construct a revlog delta
mpm@selenic.com
parents: 117
diff changeset
   879
16375
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
   880
    def revision(self, nodeorrev):
16435
df347129305d revlog: fix partial revision() docstring (from d7d64b89a65c)
Patrick Mezard <patrick@mezard.eu>
parents: 16424
diff changeset
   881
        """return an uncompressed revision of a given node or revision
df347129305d revlog: fix partial revision() docstring (from d7d64b89a65c)
Patrick Mezard <patrick@mezard.eu>
parents: 16424
diff changeset
   882
        number.
df347129305d revlog: fix partial revision() docstring (from d7d64b89a65c)
Patrick Mezard <patrick@mezard.eu>
parents: 16424
diff changeset
   883
        """
16375
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
   884
        if isinstance(nodeorrev, int):
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
   885
            rev = nodeorrev
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
   886
            node = self.node(rev)
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
   887
        else:
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
   888
            node = nodeorrev
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
   889
            rev = None
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
   890
11996
3195cf01dfb9 revlog.revision(): don't use nullrev as the default value for the cache
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11995
diff changeset
   891
        cachedrev = None
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   892
        if node == nullid:
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   893
            return ""
11930
12547cedc264 revlog: teach revlog to construct a revision from parentdeltas
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11929
diff changeset
   894
        if self._cache:
12547cedc264 revlog: teach revlog to construct a revision from parentdeltas
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11929
diff changeset
   895
            if self._cache[0] == node:
12547cedc264 revlog: teach revlog to construct a revision from parentdeltas
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11929
diff changeset
   896
                return self._cache[2]
11995
ff84cd2bdfaf revlog.revision(): minor cleanup
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11963
diff changeset
   897
            cachedrev = self._cache[1]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   898
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   899
        # look up what we need to read
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   900
        text = None
16375
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
   901
        if rev is None:
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
   902
            rev = self.rev(node)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   903
5004
825516d16b25 revlog: move flag checking out of the offset fastpath
Matt Mackall <mpm@selenic.com>
parents: 4996
diff changeset
   904
        # check rev flags
11745
138c055ec57d revlog: add punched revision flag
Vishakh H <vsh426@gmail.com>
parents: 11693
diff changeset
   905
        if self.flags(rev) & ~REVIDX_KNOWN_FLAGS:
5312
fb070713ff36 revlog: more robust for damaged indexes
Matt Mackall <mpm@selenic.com>
parents: 5007
diff changeset
   906
            raise RevlogError(_('incompatible revision flag %x') %
11745
138c055ec57d revlog: add punched revision flag
Vishakh H <vsh426@gmail.com>
parents: 11693
diff changeset
   907
                              (self.flags(rev) & ~REVIDX_KNOWN_FLAGS))
5004
825516d16b25 revlog: move flag checking out of the offset fastpath
Matt Mackall <mpm@selenic.com>
parents: 4996
diff changeset
   908
11995
ff84cd2bdfaf revlog.revision(): minor cleanup
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11963
diff changeset
   909
        # build delta chain
11998
e789a811c21d revlog.revision(): inline deltachain computation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11997
diff changeset
   910
        chain = []
14252
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   911
        index = self.index # for performance
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
   912
        generaldelta = self._generaldelta
11998
e789a811c21d revlog.revision(): inline deltachain computation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11997
diff changeset
   913
        iterrev = rev
14252
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   914
        e = index[iterrev]
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   915
        while iterrev != e[3] and iterrev != cachedrev:
11998
e789a811c21d revlog.revision(): inline deltachain computation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11997
diff changeset
   916
            chain.append(iterrev)
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
   917
            if generaldelta:
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
   918
                iterrev = e[3]
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
   919
            else:
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
   920
                iterrev -= 1
14252
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   921
            e = index[iterrev]
11998
e789a811c21d revlog.revision(): inline deltachain computation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11997
diff changeset
   922
        chain.reverse()
e789a811c21d revlog.revision(): inline deltachain computation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11997
diff changeset
   923
        base = iterrev
11995
ff84cd2bdfaf revlog.revision(): minor cleanup
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11963
diff changeset
   924
11998
e789a811c21d revlog.revision(): inline deltachain computation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11997
diff changeset
   925
        if iterrev == cachedrev:
e789a811c21d revlog.revision(): inline deltachain computation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11997
diff changeset
   926
            # cache hit
9420
d0db168136dc manifest/revlog: do not let the revlog cache mutable objects
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9029
diff changeset
   927
            text = self._cache[2]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   928
11754
6ccd130eab0e revlog: drop cache after use to save memory footprint
Matt Mackall <mpm@selenic.com>
parents: 11539
diff changeset
   929
        # drop cache to save memory
6ccd130eab0e revlog: drop cache after use to save memory footprint
Matt Mackall <mpm@selenic.com>
parents: 11539
diff changeset
   930
        self._cache = None
6ccd130eab0e revlog: drop cache after use to save memory footprint
Matt Mackall <mpm@selenic.com>
parents: 11539
diff changeset
   931
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   932
        self._chunkraw(base, rev)
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   933
        if text is None:
16423
a150923b49ba revlog: avoid an expensive string copy
Bryan O'Sullivan <bryano@fb.com>
parents: 16418
diff changeset
   934
            text = str(self._chunkbase(base))
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   935
11930
12547cedc264 revlog: teach revlog to construct a revision from parentdeltas
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11929
diff changeset
   936
        bins = [self._chunk(r) for r in chain]
4989
1aaed3d69772 revlog: eliminate diff and patches functions
Matt Mackall <mpm@selenic.com>
parents: 4988
diff changeset
   937
        text = mdiff.patches(text, bins)
13239
12ed25f39d0b revlog: break hash checking into subfunction
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   938
13276
ba6a63339f7c revlog: pass rev to _checkhash
Matt Mackall <mpm@selenic.com>
parents: 13275
diff changeset
   939
        text = self._checkhash(text, node, rev)
13239
12ed25f39d0b revlog: break hash checking into subfunction
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   940
12ed25f39d0b revlog: break hash checking into subfunction
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   941
        self._cache = (node, rev, text)
12ed25f39d0b revlog: break hash checking into subfunction
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   942
        return text
12ed25f39d0b revlog: break hash checking into subfunction
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   943
13276
ba6a63339f7c revlog: pass rev to _checkhash
Matt Mackall <mpm@selenic.com>
parents: 13275
diff changeset
   944
    def _checkhash(self, text, node, rev):
1598
14d1f1868bf6 cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
   945
        p1, p2 = self.parents(node)
14196
e7483ec3c374 revlog: remove support for punched/shallow
Sune Foldager <cryo@cyanite.org>
parents: 14195
diff changeset
   946
        if node != hash(text, p1, p2):
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
   947
            raise RevlogError(_("integrity check failed on %s:%d")
8643
648af8a6aa41 revlog: report indexfile rather than datafile for integrity check
Matt Mackall <mpm@selenic.com>
parents: 8641
diff changeset
   948
                              % (self.indexfile, rev))
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 484
diff changeset
   949
        return text
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   950
2075
343aeefb553b Make the appendfile class inline-data index friendly
mason@suse.com
parents: 2073
diff changeset
   951
    def checkinlinesize(self, tr, fp=None):
10913
f2ecc5733c89 revlog: factor out _maxinline global.
Greg Ward <greg-hg@gerg.ca>
parents: 10404
diff changeset
   952
        if not self._inline or (self.start(-2) + self.length(-2)) < _maxinline:
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
   953
            return
8315
c8493310ad9b revlog: use index to find index size
Matt Mackall <mpm@selenic.com>
parents: 8314
diff changeset
   954
2084
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
   955
        trinfo = tr.find(self.indexfile)
8527
f9a80054dd3c use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents: 8464
diff changeset
   956
        if trinfo is None:
3680
69cf255a55a1 Indentation cleanups for 2956948b81f3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3679
diff changeset
   957
            raise RevlogError(_("%s not found in the transaction")
69cf255a55a1 Indentation cleanups for 2956948b81f3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3679
diff changeset
   958
                              % self.indexfile)
2084
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
   959
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
   960
        trindex = trinfo[2]
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
   961
        dataoff = self.start(trindex)
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
   962
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
   963
        tr.add(self.datafile, dataoff)
8315
c8493310ad9b revlog: use index to find index size
Matt Mackall <mpm@selenic.com>
parents: 8314
diff changeset
   964
8317
5cdf4067857a revlog: use chunk cache to avoid rereading when splitting inline files
Matt Mackall <mpm@selenic.com>
parents: 8316
diff changeset
   965
        if fp:
5cdf4067857a revlog: use chunk cache to avoid rereading when splitting inline files
Matt Mackall <mpm@selenic.com>
parents: 8316
diff changeset
   966
            fp.flush()
5cdf4067857a revlog: use chunk cache to avoid rereading when splitting inline files
Matt Mackall <mpm@selenic.com>
parents: 8316
diff changeset
   967
            fp.close()
8315
c8493310ad9b revlog: use index to find index size
Matt Mackall <mpm@selenic.com>
parents: 8314
diff changeset
   968
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
   969
        df = self.opener(self.datafile, 'w')
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
   970
        try:
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   971
            for r in self:
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   972
                df.write(self._chunkraw(r, r))
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
   973
        finally:
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
   974
            df.close()
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
   975
2076
d007df6daf8e Create an atomic opener that does not automatically rename on close
mason@suse.com
parents: 2075
diff changeset
   976
        fp = self.opener(self.indexfile, 'w', atomictemp=True)
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
   977
        self.version &= ~(REVLOGNGINLINEDATA)
4982
9672e3c42b0c revlog: change _inline from a function to a variable
Matt Mackall <mpm@selenic.com>
parents: 4981
diff changeset
   978
        self._inline = False
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   979
        for i in self:
5338
f87685355c9c revlog: fix revlogio.packentry corner case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5325
diff changeset
   980
            e = self._io.packentry(self.index[i], self.node, self.version, i)
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
   981
            fp.write(e)
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
   982
15057
774da7121fc9 atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents: 14960
diff changeset
   983
        # if we don't call close, the temp file will never replace the
2076
d007df6daf8e Create an atomic opener that does not automatically rename on close
mason@suse.com
parents: 2075
diff changeset
   984
        # real index
15057
774da7121fc9 atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents: 14960
diff changeset
   985
        fp.close()
2084
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
   986
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   987
        tr.replace(self.indexfile, trindex * self._io.size)
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   988
        self._chunkclear()
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
   989
11962
5f7ee3db3dd8 revlog._addrevision(): make the parent of the cached delta explicit
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11935
diff changeset
   990
    def addrevision(self, text, transaction, link, p1, p2, cachedelta=None):
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   991
        """add a revision to the log
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   992
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   993
        text - the revision data to add
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   994
        transaction - the transaction object used for rollback
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   995
        link - the linkrev data to add
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   996
        p1, p2 - the parent nodeids of the revision
12012
bade7a9c5c07 revlog: fix docstring
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12011
diff changeset
   997
        cachedelta - an optional precomputed delta
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   998
        """
12023
44c22dc193a4 revlog.addrevision(): move computation of nodeid in addrevision()
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12012
diff changeset
   999
        node = hash(text, p1, p2)
14196
e7483ec3c374 revlog: remove support for punched/shallow
Sune Foldager <cryo@cyanite.org>
parents: 14195
diff changeset
  1000
        if node in self.nodemap:
12023
44c22dc193a4 revlog.addrevision(): move computation of nodeid in addrevision()
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12012
diff changeset
  1001
            return node
44c22dc193a4 revlog.addrevision(): move computation of nodeid in addrevision()
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12012
diff changeset
  1002
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1003
        dfh = None
4982
9672e3c42b0c revlog: change _inline from a function to a variable
Matt Mackall <mpm@selenic.com>
parents: 4981
diff changeset
  1004
        if not self._inline:
3390
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1005
            dfh = self.opener(self.datafile, "a")
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1006
        ifh = self.opener(self.indexfile, "a+")
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1007
        try:
12023
44c22dc193a4 revlog.addrevision(): move computation of nodeid in addrevision()
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12012
diff changeset
  1008
            return self._addrevision(node, text, transaction, link, p1, p2,
11962
5f7ee3db3dd8 revlog._addrevision(): make the parent of the cached delta explicit
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11935
diff changeset
  1009
                                     cachedelta, ifh, dfh)
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1010
        finally:
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1011
            if dfh:
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1012
                dfh.close()
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1013
            ifh.close()
3390
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1014
17128
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1015
    def compress(self, text):
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1016
        """ generate a possibly-compressed representation of text """
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1017
        if not text:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1018
            return ("", text)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1019
        l = len(text)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1020
        bin = None
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1021
        if l < 44:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1022
            pass
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1023
        elif l > 1000000:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1024
            # zlib makes an internal copy, thus doubling memory usage for
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1025
            # large files, so lets do this in pieces
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1026
            z = zlib.compressobj()
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1027
            p = []
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1028
            pos = 0
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1029
            while pos < l:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1030
                pos2 = pos + 2**20
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1031
                p.append(z.compress(text[pos:pos2]))
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1032
                pos = pos2
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1033
            p.append(z.flush())
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1034
            if sum(map(len, p)) < l:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1035
                bin = "".join(p)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1036
        else:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1037
            bin = _compress(text)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1038
        if bin is None or len(bin) > l:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1039
            if text[0] == '\0':
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1040
                return ("", text)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1041
            return ('u', text)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1042
        return ("", bin)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1043
12023
44c22dc193a4 revlog.addrevision(): move computation of nodeid in addrevision()
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12012
diff changeset
  1044
    def _addrevision(self, node, text, transaction, link, p1, p2,
11962
5f7ee3db3dd8 revlog._addrevision(): make the parent of the cached delta explicit
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11935
diff changeset
  1045
                     cachedelta, ifh, dfh):
14292
c97d8485b5fa revlog: add docstring to _addrevision
Sune Foldager <cryo@cyanite.org>
parents: 14270
diff changeset
  1046
        """internal function to add revisions to the log
12623
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1047
14292
c97d8485b5fa revlog: add docstring to _addrevision
Sune Foldager <cryo@cyanite.org>
parents: 14270
diff changeset
  1048
        see addrevision for argument descriptions.
c97d8485b5fa revlog: add docstring to _addrevision
Sune Foldager <cryo@cyanite.org>
parents: 14270
diff changeset
  1049
        invariants:
c97d8485b5fa revlog: add docstring to _addrevision
Sune Foldager <cryo@cyanite.org>
parents: 14270
diff changeset
  1050
        - text is optional (can be None); if not set, cachedelta must be set.
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17150
diff changeset
  1051
          if both are set, they must correspond to each other.
14292
c97d8485b5fa revlog: add docstring to _addrevision
Sune Foldager <cryo@cyanite.org>
parents: 14270
diff changeset
  1052
        """
12886
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1053
        btext = [text]
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1054
        def buildtext():
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1055
            if btext[0] is not None:
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1056
                return btext[0]
12623
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1057
            # flush any pending writes here so we can read it in revision
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1058
            if dfh:
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1059
                dfh.flush()
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1060
            ifh.flush()
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1061
            basetext = self.revision(self.node(cachedelta[0]))
12886
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1062
            btext[0] = mdiff.patch(basetext, cachedelta[1])
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1063
            chk = hash(btext[0], p1, p2)
12623
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1064
            if chk != node:
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1065
                raise RevlogError(_("consistency error in delta"))
12886
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1066
            return btext[0]
12623
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1067
12888
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1068
        def builddelta(rev):
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1069
            # can we use the cached delta?
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1070
            if cachedelta and cachedelta[0] == rev:
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1071
                delta = cachedelta[1]
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1072
            else:
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1073
                t = buildtext()
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1074
                ptext = self.revision(self.node(rev))
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1075
                delta = mdiff.textdiff(ptext, t)
17128
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1076
            data = self.compress(delta)
12888
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1077
            l = len(data[1]) + len(data[0])
14296
62e25c63fb3a revlog: fix bug in chainbase cache
Sune Foldager <cryo@cyanite.org>
parents: 14292
diff changeset
  1078
            if basecache[0] == rev:
14270
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1079
                chainbase = basecache[1]
14252
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
  1080
            else:
14270
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1081
                chainbase = self.chainbase(rev)
17150
3ac9592b7ab4 backout e7167007c083
Matt Mackall <mpm@selenic.com>
parents: 17139
diff changeset
  1082
            dist = l + offset - self.start(chainbase)
14270
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1083
            if self._generaldelta:
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1084
                base = rev
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1085
            else:
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1086
                base = chainbase
14296
62e25c63fb3a revlog: fix bug in chainbase cache
Sune Foldager <cryo@cyanite.org>
parents: 14292
diff changeset
  1087
            return dist, l, data, base, chainbase
12888
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1088
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1089
        curr = len(self)
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1090
        prev = curr - 1
14296
62e25c63fb3a revlog: fix bug in chainbase cache
Sune Foldager <cryo@cyanite.org>
parents: 14292
diff changeset
  1091
        base = chainbase = curr
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1092
        offset = self.end(prev)
11931
6051db1327f8 revlog: append delta against p1
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11930
diff changeset
  1093
        flags = 0
11962
5f7ee3db3dd8 revlog._addrevision(): make the parent of the cached delta explicit
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11935
diff changeset
  1094
        d = None
14296
62e25c63fb3a revlog: fix bug in chainbase cache
Sune Foldager <cryo@cyanite.org>
parents: 14292
diff changeset
  1095
        basecache = self._basecache
12889
5482c6b826f4 revlog: precalculate p1 and p2 revisions
Matt Mackall <mpm@selenic.com>
parents: 12888
diff changeset
  1096
        p1r, p2r = self.rev(p1), self.rev(p2)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1097
11963
7c3aa579d98a parendelta: fix computation of base rev (fixes issue2337)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11962
diff changeset
  1098
        # should we try to build a delta?
12890
b1c839659140 revlog: choose best delta for parentdelta (issue2466)
Matt Mackall <mpm@selenic.com>
parents: 12889
diff changeset
  1099
        if prev != nullrev:
14270
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1100
            if self._generaldelta:
14301
f94993769c87 revlog: improve delta generation heuristics for generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14296
diff changeset
  1101
                if p1r >= basecache[1]:
f94993769c87 revlog: improve delta generation heuristics for generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14296
diff changeset
  1102
                    d = builddelta(p1r)
f94993769c87 revlog: improve delta generation heuristics for generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14296
diff changeset
  1103
                elif p2r >= basecache[1]:
f94993769c87 revlog: improve delta generation heuristics for generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14296
diff changeset
  1104
                    d = builddelta(p2r)
f94993769c87 revlog: improve delta generation heuristics for generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14296
diff changeset
  1105
                else:
f94993769c87 revlog: improve delta generation heuristics for generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14296
diff changeset
  1106
                    d = builddelta(prev)
14270
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1107
            else:
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1108
                d = builddelta(prev)
14296
62e25c63fb3a revlog: fix bug in chainbase cache
Sune Foldager <cryo@cyanite.org>
parents: 14292
diff changeset
  1109
            dist, l, data, base, chainbase = d
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1110
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1111
        # full versions are inserted when the needed deltas
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1112
        # become comparable to the uncompressed text
12623
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1113
        if text is None:
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1114
            textlen = mdiff.patchedsize(self.rawsize(cachedelta[0]),
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1115
                                        cachedelta[1])
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1116
        else:
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1117
            textlen = len(text)
14196
e7483ec3c374 revlog: remove support for punched/shallow
Sune Foldager <cryo@cyanite.org>
parents: 14195
diff changeset
  1118
        if d is None or dist > textlen * 2:
12886
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1119
            text = buildtext()
17128
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1120
            data = self.compress(text)
1533
3d11f81c9145 Reduce string duplication in compression code
mason@suse.com
parents: 1509
diff changeset
  1121
            l = len(data[1]) + len(data[0])
14296
62e25c63fb3a revlog: fix bug in chainbase cache
Sune Foldager <cryo@cyanite.org>
parents: 14292
diff changeset
  1122
            base = chainbase = curr
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1123
12623
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1124
        e = (offset_type(offset, flags), l, textlen,
12889
5482c6b826f4 revlog: precalculate p1 and p2 revisions
Matt Mackall <mpm@selenic.com>
parents: 12888
diff changeset
  1125
             base, link, p1r, p2r, node)
4979
06abdaf78788 revlog: add a magic null revision to our index
Matt Mackall <mpm@selenic.com>
parents: 4978
diff changeset
  1126
        self.index.insert(-1, e)
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1127
        self.nodemap[node] = curr
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
  1128
5338
f87685355c9c revlog: fix revlogio.packentry corner case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5325
diff changeset
  1129
        entry = self._io.packentry(e, self.node, self.version, curr)
4982
9672e3c42b0c revlog: change _inline from a function to a variable
Matt Mackall <mpm@selenic.com>
parents: 4981
diff changeset
  1130
        if not self._inline:
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1131
            transaction.add(self.datafile, offset)
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1132
            transaction.add(self.indexfile, curr * len(entry))
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1133
            if data[0]:
3390
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1134
                dfh.write(data[0])
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1135
            dfh.write(data[1])
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1136
            dfh.flush()
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1137
            ifh.write(entry)
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1138
        else:
4996
a0d37976cd5b revlog: avoid some unnecessary seek/tell syscalls
Matt Mackall <mpm@selenic.com>
parents: 4994
diff changeset
  1139
            offset += curr * self._io.size
5324
8409a2e3a78d revlog: fix inlined revision transaction extra data (issue 749)
Patrick Mezard <pmezard@gmail.com>
parents: 5007
diff changeset
  1140
            transaction.add(self.indexfile, offset, curr)
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1141
            ifh.write(entry)
3390
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1142
            ifh.write(data[0])
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1143
            ifh.write(data[1])
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1144
            self.checkinlinesize(transaction, ifh)
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1145
9420
d0db168136dc manifest/revlog: do not let the revlog cache mutable objects
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9029
diff changeset
  1146
        if type(text) == str: # only accept immutable objects
d0db168136dc manifest/revlog: do not let the revlog cache mutable objects
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9029
diff changeset
  1147
            self._cache = (node, curr, text)
14296
62e25c63fb3a revlog: fix bug in chainbase cache
Sune Foldager <cryo@cyanite.org>
parents: 14292
diff changeset
  1148
        self._basecache = (curr, chainbase)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1149
        return node
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1150
14365
a8e3931e3fb5 revlog: linearize created changegroups in generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14334
diff changeset
  1151
    def group(self, nodelist, bundler, reorder=None):
9437
1c4e4004f3a6 Improve some docstrings relating to changegroups and prepush().
Greg Ward <greg-hg@gerg.ca>
parents: 9420
diff changeset
  1152
        """Calculate a delta group, yielding a sequence of changegroup chunks
1c4e4004f3a6 Improve some docstrings relating to changegroups and prepush().
Greg Ward <greg-hg@gerg.ca>
parents: 9420
diff changeset
  1153
        (strings).
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1154
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1155
        Given a list of changeset revs, return a set of deltas and
11999
62e2bbf523f2 revlog: generate full revisions when parent node is missing
Vishakh H <vsh426@gmail.com>
parents: 11998
diff changeset
  1156
        metadata corresponding to nodes. The first delta is
62e2bbf523f2 revlog: generate full revisions when parent node is missing
Vishakh H <vsh426@gmail.com>
parents: 11998
diff changeset
  1157
        first parent(nodelist[0]) -> nodelist[0], the receiver is
62e2bbf523f2 revlog: generate full revisions when parent node is missing
Vishakh H <vsh426@gmail.com>
parents: 11998
diff changeset
  1158
        guaranteed to have this parent as it has all history before
62e2bbf523f2 revlog: generate full revisions when parent node is missing
Vishakh H <vsh426@gmail.com>
parents: 11998
diff changeset
  1159
        these changesets. In the case firstparent is nullrev the
62e2bbf523f2 revlog: generate full revisions when parent node is missing
Vishakh H <vsh426@gmail.com>
parents: 11998
diff changeset
  1160
        changegroup starts with a full revision.
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1161
        """
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1162
14523
b4175b72bbd8 revlog: bail out earlier in group when we have no chunks
Sune Foldager <cryo@cyanite.org>
parents: 14494
diff changeset
  1163
        # if we don't have any revisions touched by these changesets, bail
b4175b72bbd8 revlog: bail out earlier in group when we have no chunks
Sune Foldager <cryo@cyanite.org>
parents: 14494
diff changeset
  1164
        if len(nodelist) == 0:
b4175b72bbd8 revlog: bail out earlier in group when we have no chunks
Sune Foldager <cryo@cyanite.org>
parents: 14494
diff changeset
  1165
            yield bundler.close()
b4175b72bbd8 revlog: bail out earlier in group when we have no chunks
Sune Foldager <cryo@cyanite.org>
parents: 14494
diff changeset
  1166
            return
b4175b72bbd8 revlog: bail out earlier in group when we have no chunks
Sune Foldager <cryo@cyanite.org>
parents: 14494
diff changeset
  1167
14365
a8e3931e3fb5 revlog: linearize created changegroups in generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14334
diff changeset
  1168
        # for generaldelta revlogs, we linearize the revs; this will both be
a8e3931e3fb5 revlog: linearize created changegroups in generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14334
diff changeset
  1169
        # much quicker and generate a much smaller bundle
a8e3931e3fb5 revlog: linearize created changegroups in generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14334
diff changeset
  1170
        if (self._generaldelta and reorder is not False) or reorder:
a8e3931e3fb5 revlog: linearize created changegroups in generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14334
diff changeset
  1171
            dag = dagutil.revlogdag(self)
a8e3931e3fb5 revlog: linearize created changegroups in generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14334
diff changeset
  1172
            revs = set(self.rev(n) for n in nodelist)
a8e3931e3fb5 revlog: linearize created changegroups in generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14334
diff changeset
  1173
            revs = dag.linearize(revs)
a8e3931e3fb5 revlog: linearize created changegroups in generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14334
diff changeset
  1174
        else:
a8e3931e3fb5 revlog: linearize created changegroups in generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14334
diff changeset
  1175
            revs = sorted([self.rev(n) for n in nodelist])
8634
7659eecd9da2 changegroup: the node list might be an empty generator (fix issue1678)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8624
diff changeset
  1176
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1177
        # add the parent of the first rev
8391
27bffd81d265 revlog: slightly tune group() by not going rev->node->rev
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8318
diff changeset
  1178
        p = self.parentrevs(revs[0])[0]
27bffd81d265 revlog: slightly tune group() by not going rev->node->rev
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8318
diff changeset
  1179
        revs.insert(0, p)
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1180
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1181
        # build deltas
13768
10aea25fb519 revlog: change variable name to avoid reuse
Matt Mackall <mpm@selenic.com>
parents: 13741
diff changeset
  1182
        for r in xrange(len(revs) - 1):
14143
da635d3c5620 changegroup: new bundler API
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14141
diff changeset
  1183
            prev, curr = revs[r], revs[r + 1]
da635d3c5620 changegroup: new bundler API
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14141
diff changeset
  1184
            for c in bundler.revchunk(self, curr, prev):
13831
d69c9510d648 changegroup: introduce bundler objects
Matt Mackall <mpm@selenic.com>
parents: 13785
diff changeset
  1185
                yield c
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1186
13831
d69c9510d648 changegroup: introduce bundler objects
Matt Mackall <mpm@selenic.com>
parents: 13785
diff changeset
  1187
        yield bundler.close()
192
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 155
diff changeset
  1188
12335
e21fe9c5fb25 bundle: get rid of chunkiter
Matt Mackall <mpm@selenic.com>
parents: 12025
diff changeset
  1189
    def addgroup(self, bundle, linkmapper, transaction):
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1190
        """
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1191
        add a delta group
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1192
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1193
        given a set of deltas, add them to the revision log. the
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1194
        first delta is against its parent, which should be in our
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1195
        log, the rest are against the previous delta.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1196
        """
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1197
12624
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1198
        # track the base of the current delta log
15890
e234eda20984 revlog: make addgroup returns a list of node contained in the added source
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15835
diff changeset
  1199
        content = []
2002
4aab906517c6 Calling revlog.addgroup with an empty changegroup now raises RevlogError.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1981
diff changeset
  1200
        node = None
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 484
diff changeset
  1201
12624
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1202
        r = len(self)
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1203
        end = 0
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1204
        if r:
12624
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1205
            end = self.end(r - 1)
2072
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 2002
diff changeset
  1206
        ifh = self.opener(self.indexfile, "a+")
4996
a0d37976cd5b revlog: avoid some unnecessary seek/tell syscalls
Matt Mackall <mpm@selenic.com>
parents: 4994
diff changeset
  1207
        isize = r * self._io.size
4982
9672e3c42b0c revlog: change _inline from a function to a variable
Matt Mackall <mpm@selenic.com>
parents: 4981
diff changeset
  1208
        if self._inline:
4996
a0d37976cd5b revlog: avoid some unnecessary seek/tell syscalls
Matt Mackall <mpm@selenic.com>
parents: 4994
diff changeset
  1209
            transaction.add(self.indexfile, end + isize, r)
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1210
            dfh = None
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1211
        else:
4996
a0d37976cd5b revlog: avoid some unnecessary seek/tell syscalls
Matt Mackall <mpm@selenic.com>
parents: 4994
diff changeset
  1212
            transaction.add(self.indexfile, isize, r)
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1213
            transaction.add(self.datafile, end)
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1214
            dfh = self.opener(self.datafile, "a")
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1215
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1216
        try:
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1217
            # loop through our set of deltas
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1218
            chain = None
14494
1ffeeb91c55d check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents: 14393
diff changeset
  1219
            while True:
14144
3c3c53d8343a unbundler: separate delta and header parsing
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14143
diff changeset
  1220
                chunkdata = bundle.deltachunk(chain)
12336
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
  1221
                if not chunkdata:
12335
e21fe9c5fb25 bundle: get rid of chunkiter
Matt Mackall <mpm@selenic.com>
parents: 12025
diff changeset
  1222
                    break
12336
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
  1223
                node = chunkdata['node']
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
  1224
                p1 = chunkdata['p1']
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
  1225
                p2 = chunkdata['p2']
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
  1226
                cs = chunkdata['cs']
14141
bd1cbfe5db5c bundler: make parsechunk return the base revision of the delta
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14075
diff changeset
  1227
                deltabase = chunkdata['deltabase']
bd1cbfe5db5c bundler: make parsechunk return the base revision of the delta
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14075
diff changeset
  1228
                delta = chunkdata['delta']
12336
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
  1229
15890
e234eda20984 revlog: make addgroup returns a list of node contained in the added source
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15835
diff changeset
  1230
                content.append(node)
e234eda20984 revlog: make addgroup returns a list of node contained in the added source
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15835
diff changeset
  1231
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1232
                link = linkmapper(cs)
14196
e7483ec3c374 revlog: remove support for punched/shallow
Sune Foldager <cryo@cyanite.org>
parents: 14195
diff changeset
  1233
                if node in self.nodemap:
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1234
                    # this can happen if two branches make the same change
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1235
                    chain = node
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1236
                    continue
192
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 155
diff changeset
  1237
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1238
                for p in (p1, p2):
16686
67964cda8701 cleanup: "not x in y" -> "x not in y"
Brodie Rao <brodie@sf.io>
parents: 16665
diff changeset
  1239
                    if p not in self.nodemap:
14196
e7483ec3c374 revlog: remove support for punched/shallow
Sune Foldager <cryo@cyanite.org>
parents: 14195
diff changeset
  1240
                        raise LookupError(p, self.indexfile,
e7483ec3c374 revlog: remove support for punched/shallow
Sune Foldager <cryo@cyanite.org>
parents: 14195
diff changeset
  1241
                                          _('unknown parent'))
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1242
14141
bd1cbfe5db5c bundler: make parsechunk return the base revision of the delta
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14075
diff changeset
  1243
                if deltabase not in self.nodemap:
bd1cbfe5db5c bundler: make parsechunk return the base revision of the delta
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14075
diff changeset
  1244
                    raise LookupError(deltabase, self.indexfile,
bd1cbfe5db5c bundler: make parsechunk return the base revision of the delta
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14075
diff changeset
  1245
                                      _('unknown delta base'))
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1246
14141
bd1cbfe5db5c bundler: make parsechunk return the base revision of the delta
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14075
diff changeset
  1247
                baserev = self.rev(deltabase)
12624
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1248
                chain = self._addrevision(node, None, transaction, link,
14141
bd1cbfe5db5c bundler: make parsechunk return the base revision of the delta
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14075
diff changeset
  1249
                                          p1, p2, (baserev, delta), ifh, dfh)
12624
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1250
                if not dfh and not self._inline:
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1251
                    # addrevision switched from inline to conventional
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1252
                    # reopen the index
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13284
diff changeset
  1253
                    ifh.close()
12624
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1254
                    dfh = self.opener(self.datafile, "a")
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1255
                    ifh = self.opener(self.indexfile, "a")
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1256
        finally:
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1257
            if dfh:
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1258
                dfh.close()
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1259
            ifh.close()
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1260
15890
e234eda20984 revlog: make addgroup returns a list of node contained in the added source
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15835
diff changeset
  1261
        return content
1493
1a216cb4ee64 verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents: 1469
diff changeset
  1262
8073
e8a28556a0a8 strip: make repair.strip transactional to avoid repository corruption
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8017
diff changeset
  1263
    def strip(self, minlink, transaction):
5910
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1264
        """truncate the revlog on the first revision with a linkrev >= minlink
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1265
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1266
        This function is called when we're stripping revision minlink and
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1267
        its descendants from the repository.
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1268
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1269
        We have to remove all revisions with linkrev >= minlink, because
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1270
        the equivalent changelog revisions will be renumbered after the
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1271
        strip.
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1272
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1273
        So we truncate the revlog on the first of these revisions, and
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1274
        trust that the caller has saved the revisions that shouldn't be
15827
1dacf7672556 revlog: clarify strip docstring "readd" -> "re-add"
Steven Brown <StevenGBrown@gmail.com>
parents: 15407
diff changeset
  1275
        removed and that it'll re-add them after this truncation.
5910
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1276
        """
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1277
        if len(self) == 0:
1535
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1278
            return
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1279
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1280
        for rev in self:
5909
f45f7390c1c5 strip: calculate list of extra nodes to save and pass it to changegroupsubset
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5659
diff changeset
  1281
            if self.index[rev][4] >= minlink:
f45f7390c1c5 strip: calculate list of extra nodes to save and pass it to changegroupsubset
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5659
diff changeset
  1282
                break
f45f7390c1c5 strip: calculate list of extra nodes to save and pass it to changegroupsubset
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5659
diff changeset
  1283
        else:
f45f7390c1c5 strip: calculate list of extra nodes to save and pass it to changegroupsubset
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5659
diff changeset
  1284
            return
1535
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1285
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1286
        # first truncate the files on disk
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1287
        end = self.start(rev)
4982
9672e3c42b0c revlog: change _inline from a function to a variable
Matt Mackall <mpm@selenic.com>
parents: 4981
diff changeset
  1288
        if not self._inline:
8073
e8a28556a0a8 strip: make repair.strip transactional to avoid repository corruption
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8017
diff changeset
  1289
            transaction.add(self.datafile, end)
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
  1290
            end = rev * self._io.size
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1291
        else:
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
  1292
            end += rev * self._io.size
2072
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 2002
diff changeset
  1293
8073
e8a28556a0a8 strip: make repair.strip transactional to avoid repository corruption
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8017
diff changeset
  1294
        transaction.add(self.indexfile, end)
1535
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1295
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1296
        # then reset internal state in memory to forget those revisions
4984
b4066fcbd6ba revlog: mark cache private
Matt Mackall <mpm@selenic.com>
parents: 4983
diff changeset
  1297
        self._cache = None
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
  1298
        self._chunkclear()
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1299
        for x in xrange(rev, len(self)):
2072
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 2002
diff changeset
  1300
            del self.nodemap[self.node(x)]
1535
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1301
4979
06abdaf78788 revlog: add a magic null revision to our index
Matt Mackall <mpm@selenic.com>
parents: 4978
diff changeset
  1302
        del self.index[rev:-1]
1535
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1303
1493
1a216cb4ee64 verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents: 1469
diff changeset
  1304
    def checksize(self):
1a216cb4ee64 verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents: 1469
diff changeset
  1305
        expected = 0
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1306
        if len(self):
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1307
            expected = max(0, self.end(len(self) - 1))
1667
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1308
1494
249ca10d37f4 Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents: 1493
diff changeset
  1309
        try:
249ca10d37f4 Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents: 1493
diff changeset
  1310
            f = self.opener(self.datafile)
249ca10d37f4 Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents: 1493
diff changeset
  1311
            f.seek(0, 2)
249ca10d37f4 Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents: 1493
diff changeset
  1312
            actual = f.tell()
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13284
diff changeset
  1313
            f.close()
1667
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1314
            dd = actual - expected
1494
249ca10d37f4 Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents: 1493
diff changeset
  1315
        except IOError, inst:
1667
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1316
            if inst.errno != errno.ENOENT:
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1317
                raise
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1318
            dd = 0
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1319
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1320
        try:
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1321
            f = self.opener(self.indexfile)
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1322
            f.seek(0, 2)
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1323
            actual = f.tell()
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13284
diff changeset
  1324
            f.close()
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
  1325
            s = self._io.size
9029
0001e49f1c11 compat: use // for integer division
Alejandro Santos <alejolp@alejolp.com>
parents: 8658
diff changeset
  1326
            i = max(0, actual // s)
1667
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1327
            di = actual - (i * s)
4982
9672e3c42b0c revlog: change _inline from a function to a variable
Matt Mackall <mpm@selenic.com>
parents: 4981
diff changeset
  1328
            if self._inline:
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1329
                databytes = 0
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1330
                for r in self:
5312
fb070713ff36 revlog: more robust for damaged indexes
Matt Mackall <mpm@selenic.com>
parents: 5007
diff changeset
  1331
                    databytes += max(0, self.length(r))
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1332
                dd = 0
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1333
                di = actual - len(self) * s - databytes
1667
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1334
        except IOError, inst:
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1335
            if inst.errno != errno.ENOENT:
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1336
                raise
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1337
            di = 0
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1338
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1339
        return (dd, di)
6891
22cb82433842 revlog: add files method
Adrian Buehlmann <adrian@cadifra.com>
parents: 6872
diff changeset
  1340
22cb82433842 revlog: add files method
Adrian Buehlmann <adrian@cadifra.com>
parents: 6872
diff changeset
  1341
    def files(self):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
  1342
        res = [self.indexfile]
6891
22cb82433842 revlog: add files method
Adrian Buehlmann <adrian@cadifra.com>
parents: 6872
diff changeset
  1343
        if not self._inline:
22cb82433842 revlog: add files method
Adrian Buehlmann <adrian@cadifra.com>
parents: 6872
diff changeset
  1344
            res.append(self.datafile)
22cb82433842 revlog: add files method
Adrian Buehlmann <adrian@cadifra.com>
parents: 6872
diff changeset
  1345
        return res