mercurial/changegroup.py
changeset 38925 66cf046ef60f
parent 38924 5839a170357d
child 38926 75d6139e69f9
equal deleted inserted replaced
38924:5839a170357d 38925:66cf046ef60f
   800         if not revlog.candelta(prev, rev):
   800         if not revlog.candelta(prev, rev):
   801             raise error.ProgrammingError('cg1 should not be used in this case')
   801             raise error.ProgrammingError('cg1 should not be used in this case')
   802         return prev
   802         return prev
   803 
   803 
   804     def revchunk(self, revlog, rev, prev, linknode):
   804     def revchunk(self, revlog, rev, prev, linknode):
       
   805         if util.safehasattr(self, 'full_nodes'):
       
   806             fn = self._revchunknarrow
       
   807         else:
       
   808             fn = self._revchunknormal
       
   809 
       
   810         return fn(revlog, rev, prev, linknode)
       
   811 
       
   812     def _revchunknormal(self, revlog, rev, prev, linknode):
   805         node = revlog.node(rev)
   813         node = revlog.node(rev)
   806         p1, p2 = revlog.parentrevs(rev)
   814         p1, p2 = revlog.parentrevs(rev)
   807         base = self.deltaparent(revlog, rev, p1, p2, prev)
   815         base = self.deltaparent(revlog, rev, p1, p2, prev)
   808 
   816 
   809         prefix = ''
   817         prefix = ''
   829         meta += prefix
   837         meta += prefix
   830         l = len(meta) + len(delta)
   838         l = len(meta) + len(delta)
   831         yield chunkheader(l)
   839         yield chunkheader(l)
   832         yield meta
   840         yield meta
   833         yield delta
   841         yield delta
       
   842 
       
   843     def _revchunknarrow(self, revlog, rev, prev, linknode):
       
   844         # build up some mapping information that's useful later. See
       
   845         # the local() nested function below.
       
   846         if not self.changelog_done:
       
   847             self.clnode_to_rev[linknode] = rev
       
   848             linkrev = rev
       
   849             self.clrev_to_localrev[linkrev] = rev
       
   850         else:
       
   851             linkrev = self.clnode_to_rev[linknode]
       
   852             self.clrev_to_localrev[linkrev] = rev
       
   853 
       
   854         # This is a node to send in full, because the changeset it
       
   855         # corresponds to was a full changeset.
       
   856         if linknode in self.full_nodes:
       
   857             for x in self._revchunknormal(revlog, rev, prev, linknode):
       
   858                 yield x
       
   859             return
       
   860 
       
   861         # At this point, a node can either be one we should skip or an
       
   862         # ellipsis. If it's not an ellipsis, bail immediately.
       
   863         if linkrev not in self.precomputed_ellipsis:
       
   864             return
       
   865 
       
   866         linkparents = self.precomputed_ellipsis[linkrev]
       
   867         def local(clrev):
       
   868             """Turn a changelog revnum into a local revnum.
       
   869 
       
   870             The ellipsis dag is stored as revnums on the changelog,
       
   871             but when we're producing ellipsis entries for
       
   872             non-changelog revlogs, we need to turn those numbers into
       
   873             something local. This does that for us, and during the
       
   874             changelog sending phase will also expand the stored
       
   875             mappings as needed.
       
   876             """
       
   877             if clrev == nullrev:
       
   878                 return nullrev
       
   879 
       
   880             if not self.changelog_done:
       
   881                 # If we're doing the changelog, it's possible that we
       
   882                 # have a parent that is already on the client, and we
       
   883                 # need to store some extra mapping information so that
       
   884                 # our contained ellipsis nodes will be able to resolve
       
   885                 # their parents.
       
   886                 if clrev not in self.clrev_to_localrev:
       
   887                     clnode = revlog.node(clrev)
       
   888                     self.clnode_to_rev[clnode] = clrev
       
   889                 return clrev
       
   890 
       
   891             # Walk the ellipsis-ized changelog breadth-first looking for a
       
   892             # change that has been linked from the current revlog.
       
   893             #
       
   894             # For a flat manifest revlog only a single step should be necessary
       
   895             # as all relevant changelog entries are relevant to the flat
       
   896             # manifest.
       
   897             #
       
   898             # For a filelog or tree manifest dirlog however not every changelog
       
   899             # entry will have been relevant, so we need to skip some changelog
       
   900             # nodes even after ellipsis-izing.
       
   901             walk = [clrev]
       
   902             while walk:
       
   903                 p = walk[0]
       
   904                 walk = walk[1:]
       
   905                 if p in self.clrev_to_localrev:
       
   906                     return self.clrev_to_localrev[p]
       
   907                 elif p in self.full_nodes:
       
   908                     walk.extend([pp for pp in self._repo.changelog.parentrevs(p)
       
   909                                     if pp != nullrev])
       
   910                 elif p in self.precomputed_ellipsis:
       
   911                     walk.extend([pp for pp in self.precomputed_ellipsis[p]
       
   912                                     if pp != nullrev])
       
   913                 else:
       
   914                     # In this case, we've got an ellipsis with parents
       
   915                     # outside the current bundle (likely an
       
   916                     # incremental pull). We "know" that we can use the
       
   917                     # value of this same revlog at whatever revision
       
   918                     # is pointed to by linknode. "Know" is in scare
       
   919                     # quotes because I haven't done enough examination
       
   920                     # of edge cases to convince myself this is really
       
   921                     # a fact - it works for all the (admittedly
       
   922                     # thorough) cases in our testsuite, but I would be
       
   923                     # somewhat unsurprised to find a case in the wild
       
   924                     # where this breaks down a bit. That said, I don't
       
   925                     # know if it would hurt anything.
       
   926                     for i in pycompat.xrange(rev, 0, -1):
       
   927                         if revlog.linkrev(i) == clrev:
       
   928                             return i
       
   929                     # We failed to resolve a parent for this node, so
       
   930                     # we crash the changegroup construction.
       
   931                     raise error.Abort(
       
   932                         'unable to resolve parent while packing %r %r'
       
   933                         ' for changeset %r' % (revlog.indexfile, rev, clrev))
       
   934 
       
   935             return nullrev
       
   936 
       
   937         if not linkparents or (
       
   938             revlog.parentrevs(rev) == (nullrev, nullrev)):
       
   939             p1, p2 = nullrev, nullrev
       
   940         elif len(linkparents) == 1:
       
   941             p1, = sorted(local(p) for p in linkparents)
       
   942             p2 = nullrev
       
   943         else:
       
   944             p1, p2 = sorted(local(p) for p in linkparents)
       
   945         n = revlog.node(rev)
       
   946 
       
   947         yield ellipsisdata(
       
   948             self, rev, revlog, p1, p2, revlog.revision(n), linknode)
       
   949 
   834     def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
   950     def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
   835         # do nothing with basenode, it is implicitly the previous one in HG10
   951         # do nothing with basenode, it is implicitly the previous one in HG10
   836         # do nothing with flags, it is implicitly 0 for cg1 and cg2
   952         # do nothing with flags, it is implicitly 0 for cg1 and cg2
   837         return struct.pack(self.deltaheader, node, p1n, p2n, linknode)
   953         return struct.pack(self.deltaheader, node, p1n, p2n, linknode)
   838 
   954