mercurial/bundlerepo.py
changeset 18416 87f370c5fef5
parent 18415 95b8629fd2de
child 18417 610706715778
equal deleted inserted replaced
18415:95b8629fd2de 18416:87f370c5fef5
    23         # To retrieve a revision, we need to know the offset of the revision in
    23         # To retrieve a revision, we need to know the offset of the revision in
    24         # the bundle (an unbundle object). We store this offset in the index
    24         # the bundle (an unbundle object). We store this offset in the index
    25         # (start).
    25         # (start).
    26         #
    26         #
    27         # basemap is indexed with revisions coming from the bundle, and it
    27         # basemap is indexed with revisions coming from the bundle, and it
    28         # maps to the node that is the base of the corresponding delta.
    28         # maps to the revision that is the base of the corresponding delta.
    29         #
    29         #
    30         # To differentiate a rev in the bundle from a rev in the revlog, we
    30         # To differentiate a rev in the bundle from a rev in the revlog, we
    31         # check revision against basemap.
    31         # check revision against basemap.
    32         opener = scmutil.readonlyvfs(opener)
    32         opener = scmutil.readonlyvfs(opener)
    33         revlog.revlog.__init__(self, opener, indexfile)
    33         revlog.revlog.__init__(self, opener, indexfile)
    34         self.bundle = bundle
    34         self.bundle = bundle
    35         self.basemap = {}
    35         self.basemap = {} # mapping rev to delta base rev
    36         n = len(self)
    36         n = len(self)
    37         chain = None
    37         chain = None
    38         self.bundlerevs = set() # used by 'bundle()' revset expression
    38         self.bundlerevs = set() # used by 'bundle()' revset expression
    39         while True:
    39         while True:
    40             chunkdata = bundle.deltachunk(chain)
    40             chunkdata = bundle.deltachunk(chain)
    59 
    59 
    60             for p in (p1, p2):
    60             for p in (p1, p2):
    61                 if p not in self.nodemap:
    61                 if p not in self.nodemap:
    62                     raise error.LookupError(p, self.indexfile,
    62                     raise error.LookupError(p, self.indexfile,
    63                                             _("unknown parent"))
    63                                             _("unknown parent"))
       
    64 
       
    65             if deltabase not in self.nodemap:
       
    66                 raise LookupError(deltabase, self.indexfile,
       
    67                                   _('unknown delta base'))
       
    68 
       
    69             baserev = self.rev(deltabase)
    64             # start, size, full unc. size, base (unused), link, p1, p2, node
    70             # start, size, full unc. size, base (unused), link, p1, p2, node
    65             e = (revlog.offset_type(start, 0), size, -1, -1, link,
    71             e = (revlog.offset_type(start, 0), size, -1, -1, link,
    66                  self.rev(p1), self.rev(p2), node)
    72                  self.rev(p1), self.rev(p2), node)
    67             self.basemap[n] = deltabase
    73             self.basemap[n] = baserev
    68             self.index.insert(-1, e)
    74             self.index.insert(-1, e)
    69             self.nodemap[node] = n
    75             self.nodemap[node] = n
    70             self.bundlerevs.add(n)
    76             self.bundlerevs.add(n)
    71             chain = node
    77             chain = node
    72             n += 1
    78             n += 1
    82 
    88 
    83     def revdiff(self, rev1, rev2):
    89     def revdiff(self, rev1, rev2):
    84         """return or calculate a delta between two revisions"""
    90         """return or calculate a delta between two revisions"""
    85         if rev1 in self.basemap and rev2 in self.basemap:
    91         if rev1 in self.basemap and rev2 in self.basemap:
    86             # hot path for bundle
    92             # hot path for bundle
    87             revb = self.rev(self.basemap[rev2])
    93             revb = self.basemap[rev2]
    88             if revb == rev1:
    94             if revb == rev1:
    89                 return self._chunk(rev2)
    95                 return self._chunk(rev2)
    90         elif rev1 not in self.basemap and rev2 not in self.basemap:
    96         elif rev1 not in self.basemap and rev2 not in self.basemap:
    91             return revlog.revlog.revdiff(self, rev1, rev2)
    97             return revlog.revlog.revdiff(self, rev1, rev2)
    92 
    98 
   114         while iterrev in self.basemap:
   120         while iterrev in self.basemap:
   115             if self._cache and self._cache[1] == iterrev:
   121             if self._cache and self._cache[1] == iterrev:
   116                 text = self._cache[2]
   122                 text = self._cache[2]
   117                 break
   123                 break
   118             chain.append(iterrev)
   124             chain.append(iterrev)
   119             iterrev = self.rev(self.basemap[iterrev])
   125             iterrev = self.basemap[iterrev]
   120         if text is None:
   126         if text is None:
   121             text = revlog.revlog.revision(self, iterrev)
   127             text = revlog.revlog.revision(self, iterrev)
   122 
   128 
   123         while chain:
   129         while chain:
   124             delta = self._chunk(chain.pop())
   130             delta = self._chunk(chain.pop())