mercurial/manifest.py
author mason@suse.com
Fri, 11 Nov 2005 18:20:24 -0800
changeset 1535 7ae0ce7a3dc4
parent 1534 80a3d6a0af71
child 1541 bf4e7ef08741
permissions -rw-r--r--
Add revlog.strip to truncate away revisions. This updates the revlog data structures for index and nodemap in place so the .d and .i files don't need to be reread after stripping away a revision.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
     1
# manifest.py - manifest revision class for mercurial
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     2
#
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     3
# Copyright 2005 Matt Mackall <mpm@selenic.com>
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     4
#
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     7
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
     8
import sys, struct
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
     9
from revlog import *
1400
cf9a1233738a i18n first part: make '_' available for files who need it
Benoit Boissinot <benoit.boissinot@ens-lyon.org
parents: 1098
diff changeset
    10
from i18n import gettext as _
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
    11
from demandload import *
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    12
demandload(globals(), "bisect array")
79
837d473d54d5 Add basic annotation support
mpm@selenic.com
parents: 78
diff changeset
    13
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    14
class manifest(revlog):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    15
    def __init__(self, opener):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    16
        self.mapcache = None
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    17
        self.listcache = None
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    18
        revlog.__init__(self, opener, "00manifest.i", "00manifest.d")
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    19
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    20
    def read(self, node):
313
e75ea4662d81 Minor caching improvement for manifest
mpm@selenic.com
parents: 312
diff changeset
    21
        if node == nullid: return {} # don't upset local cache
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    22
        if self.mapcache and self.mapcache[0] == node:
561
cdddf4652aec Fix dodiff/changes
mpm@selenic.com
parents: 557
diff changeset
    23
            return self.mapcache[1]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    24
        text = self.revision(node)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    25
        map = {}
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
    26
        flag = {}
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    27
        self.listcache = array.array('c', text)
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    28
        lines = text.splitlines(1)
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    29
        for l in lines:
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    30
            (f, n) = l.split('\0')
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    31
            map[f] = bin(n[:40])
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
    32
            flag[f] = (n[40:-1] == "x")
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
    33
        self.mapcache = (node, map, flag)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    34
        return map
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    35
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
    36
    def readflags(self, node):
313
e75ea4662d81 Minor caching improvement for manifest
mpm@selenic.com
parents: 312
diff changeset
    37
        if node == nullid: return {} # don't upset local cache
358
9f4077d7ef6f [PATCH] manifest.readflags performance buglet
mpm@selenic.com
parents: 350
diff changeset
    38
        if not self.mapcache or self.mapcache[0] != node:
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
    39
            self.read(node)
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
    40
        return self.mapcache[2]
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
    41
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    42
    def diff(self, a, b):
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    43
        return mdiff.textdiff(str(a), str(b))
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    44
741
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
    45
    def add(self, map, flags, transaction, link, p1=None, p2=None,
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
    46
            changed=None):
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    47
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    48
        # returns a tuple (start, end).  If the string is found
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    49
        # m[start:end] are the line containing that string.  If start == end
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    50
        # the string was not found and they indicate the proper sorted 
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    51
        # insertion point.  This was taken from bisect_left, and modified
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    52
        # to find line start/end as it goes along.
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    53
        #
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    54
        # m should be a buffer or a string
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    55
        # s is a string
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    56
        #
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    57
        def manifestsearch(m, s, lo=0, hi=None):
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    58
            def advance(i, c):
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    59
                while i < lenm and m[i] != c:
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    60
                    i += 1
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    61
                return i
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    62
            lenm = len(m)
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    63
            if not hi:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    64
                hi = lenm
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    65
            while lo < hi:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    66
                mid = (lo + hi) // 2
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    67
                start = mid
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    68
                while start > 0 and m[start-1] != '\n':
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    69
                    start -= 1
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    70
                end = advance(start, '\0')
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    71
                if m[start:end] < s:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    72
                    # we know that after the null there are 40 bytes of sha1
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    73
                    # this translates to the bisect lo = mid + 1
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    74
                    lo = advance(end + 40, '\n') + 1
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    75
                else:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    76
                    # this translates to the bisect hi = mid
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    77
                    hi = start
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    78
            end = advance(lo, '\0')
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    79
            found = m[lo:end]
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    80
            if cmp(s, found) == 0: 
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    81
                # we know that after the null there are 40 bytes of sha1
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    82
                end = advance(end + 40, '\n')
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    83
                return (lo, end+1)
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    84
            else:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    85
                return (lo, lo)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    86
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    87
        # apply the changes collected during the bisect loop to our addlist
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    88
        # return a delta suitable for addrevision
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    89
        def addlistdelta(addlist, x):
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    90
            # start from the bottom up
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    91
            # so changes to the offsets don't mess things up.
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    92
            i = len(x)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    93
            while i > 0:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    94
                i -= 1
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    95
                start = x[i][0]
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    96
                end = x[i][1]
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    97
                if x[i][2]:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
    98
                    addlist[start:end] = array.array('c', x[i][2])
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    99
                else:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   100
                    del addlist[start:end]
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   101
            return "".join([struct.pack(">lll", d[0], d[1], len(d[2])) + d[2] \
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   102
                            for d in x ])
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   103
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   104
        # if we're using the listcache, make sure it is valid and
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   105
        # parented by the same node we're diffing against
741
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
   106
        if not changed or not self.listcache or not p1 or \
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
   107
               self.mapcache[0] != p1:
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   108
            files = map.keys()
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   109
            files.sort()
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   110
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   111
            text = ["%s\000%s%s\n" %
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   112
                            (f, hex(map[f]), flags[f] and "x" or '')
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   113
                            for f in files]
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   114
            self.listcache = array.array('c', "".join(text))
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   115
            cachedelta = None
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   116
        else:
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   117
            addlist = self.listcache
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   118
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   119
            # combine the changed lists into one list for sorting
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   120
            work = [[x, 0] for x in changed[0]]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   121
            work[len(work):] = [[x, 1] for x in changed[1]]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   122
            work.sort()
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   123
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   124
            delta = []
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   125
            dstart = None
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   126
            dend = None
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   127
            dline = [""]
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   128
            start = 0
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   129
            # zero copy representation of addlist as a buffer
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   130
            addbuf = buffer(addlist)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   131
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   132
            # start with a readonly loop that finds the offset of
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   133
            # each line and creates the deltas
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   134
            for w in work:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   135
                f = w[0]
741
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
   136
                # bs will either be the index of the item or the insert point
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   137
                start, end = manifestsearch(addbuf, f, start)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   138
                if w[1] == 0:
741
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
   139
                    l = "%s\000%s%s\n" % (f, hex(map[f]),
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
   140
                                          flags[f] and "x" or '')
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   141
                else:
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   142
                    l = ""
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   143
                if start == end and w[1] == 1:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   144
                    # item we want to delete was not found, error out
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   145
                    raise AssertionError(
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
   146
                            _("failed to remove %s from manifest\n") % f)
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   147
                if dstart != None and dstart <= start and dend >= start:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   148
                    if dend < end:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   149
                        dend = end
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   150
                    if l:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   151
                        dline.append(l)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   152
                else:
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   153
                    if dstart != None:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   154
                        delta.append([dstart, dend, "".join(dline)])
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   155
                    dstart = start
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   156
                    dend = end
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   157
                    dline = [l]
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   158
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   159
            if dstart != None:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   160
                delta.append([dstart, dend, "".join(dline)])
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   161
            # apply the delta to the addlist, and get a delta for addrevision
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   162
            cachedelta = addlistdelta(addlist, delta)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   163
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   164
            # the delta is only valid if we've been processing the tip revision
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   165
            if self.mapcache[0] != self.tip():
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   166
                cachedelta = None
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   167
            self.listcache = addlist
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   168
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   169
        n = self.addrevision(buffer(self.listcache), transaction, link, p1,  \
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   170
                             p2, cachedelta)
302
498fb0fa2795 various fixups for git import
mpm@selenic.com
parents: 299
diff changeset
   171
        self.mapcache = (n, map, flags)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   172
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   173
        return n