mercurial/manifest.py
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Wed, 02 Nov 2005 15:46:31 -0800
changeset 1487 2bc6cd62a29c
parent 1451 54e4b187f69c
child 1534 80a3d6a0af71
permissions -rw-r--r--
fix handling of files of unsupported type in the walk code if a file was of unsupported type, it was considered as 'seen' while walking. this way it was possible to have file in the dirstate not yielded by the walk function.
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 *
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
    12
demandload(globals(), "bisect")
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
        self.addlist = None
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    19
        revlog.__init__(self, opener, "00manifest.i", "00manifest.d")
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    20
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    21
    def read(self, node):
313
e75ea4662d81 Minor caching improvement for manifest
mpm@selenic.com
parents: 312
diff changeset
    22
        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
    23
        if self.mapcache and self.mapcache[0] == node:
561
cdddf4652aec Fix dodiff/changes
mpm@selenic.com
parents: 557
diff changeset
    24
            return self.mapcache[1]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    25
        text = self.revision(node)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    26
        map = {}
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
    27
        flag = {}
25
daa724b27300 Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents: 20
diff changeset
    28
        self.listcache = (text, text.splitlines(1))
daa724b27300 Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents: 20
diff changeset
    29
        for l in self.listcache[1]:
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
741
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
    42
    def add(self, map, flags, transaction, link, p1=None, p2=None,
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
    43
            changed=None):
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    44
        # directly generate the mdiff delta from the data collected during
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    45
        # the bisect loop below
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    46
        def gendelta(delta):
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    47
            i = 0
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    48
            result = []
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    49
            while i < len(delta):
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    50
                start = delta[i][2]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    51
                end = delta[i][3]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    52
                l = delta[i][4]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    53
                if l == None:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    54
                    l = ""
741
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
    55
                while i < len(delta) - 1 and start <= delta[i+1][2] \
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
    56
                          and end >= delta[i+1][2]:
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    57
                    if delta[i+1][3] > end:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    58
                        end = delta[i+1][3]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    59
                    if delta[i+1][4]:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    60
                        l += delta[i+1][4]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    61
                    i += 1
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    62
                result.append(struct.pack(">lll", start, end, len(l)) +  l)
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    63
                i += 1
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    64
            return result
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    65
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    66
        # apply the changes collected during the bisect loop to our addlist
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    67
        def addlistdelta(addlist, delta):
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    68
            # apply the deltas to the addlist.  start from the bottom up
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    69
            # so changes to the offsets don't mess things up.
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    70
            i = len(delta)
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    71
            while i > 0:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    72
                i -= 1
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    73
                start = delta[i][0]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    74
                end = delta[i][1]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    75
                if delta[i][4]:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    76
                    addlist[start:end] = [delta[i][4]]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    77
                else:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    78
                    del addlist[start:end]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    79
            return addlist
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    80
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    81
        # calculate the byte offset of the start of each line in the
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    82
        # manifest
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    83
        def calcoffsets(addlist):
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    84
            offsets = [0] * (len(addlist) + 1)
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    85
            offset = 0
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    86
            i = 0
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    87
            while i < len(addlist):
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    88
                offsets[i] = offset
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    89
                offset += len(addlist[i])
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    90
                i += 1
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    91
            offsets[i] = offset
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    92
            return offsets
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    93
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    94
        # 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
    95
        # parented by the same node we're diffing against
741
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
    96
        if not changed or not self.listcache or not p1 or \
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
    97
               self.mapcache[0] != p1:
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    98
            files = map.keys()
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
    99
            files.sort()
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   100
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   101
            self.addlist = ["%s\000%s%s\n" %
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   102
                            (f, hex(map[f]), flags[f] and "x" or '')
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   103
                            for f in files]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   104
            cachedelta = None
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   105
        else:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   106
            addlist = self.listcache[1]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   107
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   108
            # find the starting offset for each line in the add list
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   109
            offsets = calcoffsets(addlist)
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   110
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   111
            # combine the changed lists into one list for sorting
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   112
            work = [[x, 0] for x in changed[0]]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   113
            work[len(work):] = [[x, 1] for x in changed[1]]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   114
            work.sort()
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   115
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   116
            delta = []
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   117
            bs = 0
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
            for w in work:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   120
                f = w[0]
741
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
   121
                # bs will either be the index of the item or the insert point
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   122
                bs = bisect.bisect(addlist, f, bs)
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   123
                if bs < len(addlist):
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   124
                    fn = addlist[bs][:addlist[bs].index('\0')]
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   125
                else:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   126
                    fn = None
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   127
                if w[1] == 0:
741
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
   128
                    l = "%s\000%s%s\n" % (f, hex(map[f]),
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
   129
                                          flags[f] and "x" or '')
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   130
                else:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   131
                    l = None
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   132
                start = bs
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   133
                if fn != f:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   134
                    # item not found, insert a new one
659
3662e3d6b690 Whitespace cleanup
Matt Mackall <mpm@selenic.com>
parents: 658
diff changeset
   135
                    end = bs
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   136
                    if w[1] == 1:
1098
50a0a36dd48a manifest: convert sys.stderr bits to AssertionError
mpm@selenic.com
parents: 1089
diff changeset
   137
                        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
   138
                            _("failed to remove %s from manifest\n") % f)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   139
                else:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   140
                    # item is found, replace/delete the existing line
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   141
                    end = bs + 1
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   142
                delta.append([start, end, offsets[start], offsets[end], l])
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   143
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   144
            self.addlist = addlistdelta(addlist, delta)
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   145
            if self.mapcache[0] == self.tip():
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   146
                cachedelta = "".join(gendelta(delta))
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   147
            else:
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   148
                cachedelta = None
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   149
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   150
        text = "".join(self.addlist)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   151
        if cachedelta and mdiff.patch(self.listcache[0], cachedelta) != text:
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
   152
            raise AssertionError(_("manifest delta failure\n"))
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   153
        n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
302
498fb0fa2795 various fixups for git import
mpm@selenic.com
parents: 299
diff changeset
   154
        self.mapcache = (n, map, flags)
25
daa724b27300 Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents: 20
diff changeset
   155
        self.listcache = (text, self.addlist)
140
30ef77113872 Minor safety checks to manifest diff
mpm@selenic.com
parents: 118
diff changeset
   156
        self.addlist = None
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   157
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   158
        return n