mercurial/changegroup.py
changeset 39009 9e8eb2b444e5
parent 39008 8c84f1ef949e
child 39010 fcdab6629dde
equal deleted inserted replaced
39008:8c84f1ef949e 39009:9e8eb2b444e5
   679         linknode=linknode,
   679         linknode=linknode,
   680         flags=flags,
   680         flags=flags,
   681         deltachunks=(diffheader, data),
   681         deltachunks=(diffheader, data),
   682     )
   682     )
   683 
   683 
       
   684 def deltagroup(repo, revs, store, ischangelog, lookup, deltaparentfn,
       
   685                deltaheaderfn, units=None,
       
   686                ellipses=False, clrevtolocalrev=None, fullclnodes=None,
       
   687                precomputedellipsis=None):
       
   688     """Calculate a delta group, yielding a sequence of changegroup chunks
       
   689     (strings).
       
   690 
       
   691     Given a list of changeset revs, return a set of deltas and
       
   692     metadata corresponding to nodes. The first delta is
       
   693     first parent(nodelist[0]) -> nodelist[0], the receiver is
       
   694     guaranteed to have this parent as it has all history before
       
   695     these changesets. In the case firstparent is nullrev the
       
   696     changegroup starts with a full revision.
       
   697 
       
   698     If units is not None, progress detail will be generated, units specifies
       
   699     the type of revlog that is touched (changelog, manifest, etc.).
       
   700     """
       
   701     # if we don't have any revisions touched by these changesets, bail
       
   702     if len(revs) == 0:
       
   703         yield closechunk()
       
   704         return
       
   705 
       
   706     cl = repo.changelog
       
   707 
       
   708     # add the parent of the first rev
       
   709     p = store.parentrevs(revs[0])[0]
       
   710     revs.insert(0, p)
       
   711 
       
   712     # build deltas
       
   713     progress = None
       
   714     if units is not None:
       
   715         progress = repo.ui.makeprogress(_('bundling'), unit=units,
       
   716                                         total=(len(revs) - 1))
       
   717     for r in pycompat.xrange(len(revs) - 1):
       
   718         if progress:
       
   719             progress.update(r + 1)
       
   720         prev, curr = revs[r], revs[r + 1]
       
   721         linknode = lookup(store.node(curr))
       
   722 
       
   723         if ellipses:
       
   724             linkrev = cl.rev(linknode)
       
   725             clrevtolocalrev[linkrev] = curr
       
   726 
       
   727             # This is a node to send in full, because the changeset it
       
   728             # corresponds to was a full changeset.
       
   729             if linknode in fullclnodes:
       
   730                 delta = _revisiondeltanormal(store, curr, prev, linknode,
       
   731                                              deltaparentfn)
       
   732             elif linkrev not in precomputedellipsis:
       
   733                 delta = None
       
   734             else:
       
   735                 delta = _revisiondeltanarrow(
       
   736                     cl, store, ischangelog, curr, linkrev, linknode,
       
   737                     clrevtolocalrev, fullclnodes,
       
   738                     precomputedellipsis)
       
   739         else:
       
   740             delta = _revisiondeltanormal(store, curr, prev, linknode,
       
   741                                          deltaparentfn)
       
   742 
       
   743         if not delta:
       
   744             continue
       
   745 
       
   746         meta = deltaheaderfn(delta)
       
   747         l = len(meta) + sum(len(x) for x in delta.deltachunks)
       
   748         yield chunkheader(l)
       
   749         yield meta
       
   750         for x in delta.deltachunks:
       
   751             yield x
       
   752 
       
   753     if progress:
       
   754         progress.complete()
       
   755 
       
   756     yield closechunk()
       
   757 
   684 class cgpacker(object):
   758 class cgpacker(object):
   685     def __init__(self, repo, filematcher, version, allowreorder,
   759     def __init__(self, repo, filematcher, version, allowreorder,
   686                  deltaparentfn, builddeltaheader, manifestsend,
   760                  deltaparentfn, builddeltaheader, manifestsend,
   687                  bundlecaps=None, ellipses=False,
   761                  bundlecaps=None, ellipses=False,
   688                  shallow=False, ellipsisroots=None, fullnodes=None):
   762                  shallow=False, ellipsisroots=None, fullnodes=None):
   748 
   822 
   749         if self._repo.ui.verbose and not self._repo.ui.debugflag:
   823         if self._repo.ui.verbose and not self._repo.ui.debugflag:
   750             self._verbosenote = self._repo.ui.note
   824             self._verbosenote = self._repo.ui.note
   751         else:
   825         else:
   752             self._verbosenote = lambda s: None
   826             self._verbosenote = lambda s: None
   753 
       
   754     def group(self, repo, revs, store, ischangelog, lookup, deltaparentfn,
       
   755               deltaheaderfn, units=None,
       
   756               ellipses=False, clrevtolocalrev=None, fullclnodes=None,
       
   757               precomputedellipsis=None):
       
   758         """Calculate a delta group, yielding a sequence of changegroup chunks
       
   759         (strings).
       
   760 
       
   761         Given a list of changeset revs, return a set of deltas and
       
   762         metadata corresponding to nodes. The first delta is
       
   763         first parent(nodelist[0]) -> nodelist[0], the receiver is
       
   764         guaranteed to have this parent as it has all history before
       
   765         these changesets. In the case firstparent is nullrev the
       
   766         changegroup starts with a full revision.
       
   767 
       
   768         If units is not None, progress detail will be generated, units specifies
       
   769         the type of revlog that is touched (changelog, manifest, etc.).
       
   770         """
       
   771         # if we don't have any revisions touched by these changesets, bail
       
   772         if len(revs) == 0:
       
   773             yield closechunk()
       
   774             return
       
   775 
       
   776         cl = repo.changelog
       
   777 
       
   778         # add the parent of the first rev
       
   779         p = store.parentrevs(revs[0])[0]
       
   780         revs.insert(0, p)
       
   781 
       
   782         # build deltas
       
   783         progress = None
       
   784         if units is not None:
       
   785             progress = repo.ui.makeprogress(_('bundling'), unit=units,
       
   786                                             total=(len(revs) - 1))
       
   787         for r in pycompat.xrange(len(revs) - 1):
       
   788             if progress:
       
   789                 progress.update(r + 1)
       
   790             prev, curr = revs[r], revs[r + 1]
       
   791             linknode = lookup(store.node(curr))
       
   792 
       
   793             if ellipses:
       
   794                 linkrev = cl.rev(linknode)
       
   795                 clrevtolocalrev[linkrev] = curr
       
   796 
       
   797                 # This is a node to send in full, because the changeset it
       
   798                 # corresponds to was a full changeset.
       
   799                 if linknode in fullclnodes:
       
   800                     delta = _revisiondeltanormal(store, curr, prev, linknode,
       
   801                                                  deltaparentfn)
       
   802                 elif linkrev not in precomputedellipsis:
       
   803                     delta = None
       
   804                 else:
       
   805                     delta = _revisiondeltanarrow(
       
   806                         cl, store, ischangelog, curr, linkrev, linknode,
       
   807                         clrevtolocalrev, fullclnodes,
       
   808                         precomputedellipsis)
       
   809             else:
       
   810                 delta = _revisiondeltanormal(store, curr, prev, linknode,
       
   811                                              deltaparentfn)
       
   812 
       
   813             if not delta:
       
   814                 continue
       
   815 
       
   816             meta = deltaheaderfn(delta)
       
   817             l = len(meta) + sum(len(x) for x in delta.deltachunks)
       
   818             yield chunkheader(l)
       
   819             yield meta
       
   820             for x in delta.deltachunks:
       
   821                 yield x
       
   822 
       
   823         if progress:
       
   824             progress.complete()
       
   825 
       
   826         yield closechunk()
       
   827 
   827 
   828     def generate(self, commonrevs, clnodes, fastpathlinkrev, source):
   828     def generate(self, commonrevs, clnodes, fastpathlinkrev, source):
   829         """Yield a sequence of changegroup byte chunks."""
   829         """Yield a sequence of changegroup byte chunks."""
   830 
   830 
   831         repo = self._repo
   831         repo = self._repo
   956             'mfs': mfs,
   956             'mfs': mfs,
   957             'changedfiles': changedfiles,
   957             'changedfiles': changedfiles,
   958             'clrevtomanifestrev': clrevtomanifestrev,
   958             'clrevtomanifestrev': clrevtomanifestrev,
   959         }
   959         }
   960 
   960 
   961         gen = self.group(self._repo, revs, cl, True, lookupcl,
   961         gen = deltagroup(
   962                          self._deltaparentfn, self._builddeltaheader,
   962             self._repo, revs, cl, True, lookupcl,
   963                          ellipses=self._ellipses,
   963             self._deltaparentfn, self._builddeltaheader,
   964                          units=_('changesets'),
   964             ellipses=self._ellipses,
   965                          clrevtolocalrev={},
   965             units=_('changesets'),
   966                          fullclnodes=self._fullclnodes,
   966             clrevtolocalrev={},
   967                          precomputedellipsis=self._precomputedellipsis)
   967             fullclnodes=self._fullclnodes,
       
   968             precomputedellipsis=self._precomputedellipsis)
   968 
   969 
   969         return state, gen
   970         return state, gen
   970 
   971 
   971     def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev, mfs,
   972     def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev, mfs,
   972                           fnodes, source, clrevtolocalrev):
   973                           fnodes, source, clrevtolocalrev):
  1051                 assert self.version == b'03'
  1052                 assert self.version == b'03'
  1052                 chunk = _fileheader(dir)
  1053                 chunk = _fileheader(dir)
  1053                 size += len(chunk)
  1054                 size += len(chunk)
  1054                 yield chunk
  1055                 yield chunk
  1055 
  1056 
  1056             it = self.group(
  1057             it = deltagroup(
  1057                 self._repo, revs, store, False, lookupfn,
  1058                 self._repo, revs, store, False, lookupfn,
  1058                 self._deltaparentfn, self._builddeltaheader,
  1059                 self._deltaparentfn, self._builddeltaheader,
  1059                 ellipses=self._ellipses,
  1060                 ellipses=self._ellipses,
  1060                 units=_('manifests'),
  1061                 units=_('manifests'),
  1061                 clrevtolocalrev=clrevtolocalrev,
  1062                 clrevtolocalrev=clrevtolocalrev,
  1151                 progress.update(i + 1, item=fname)
  1152                 progress.update(i + 1, item=fname)
  1152                 h = _fileheader(fname)
  1153                 h = _fileheader(fname)
  1153                 size = len(h)
  1154                 size = len(h)
  1154                 yield h
  1155                 yield h
  1155 
  1156 
  1156                 it = self.group(
  1157                 it = deltagroup(
  1157                     self._repo, revs, filerevlog, False, lookupfilelog,
  1158                     self._repo, revs, filerevlog, False, lookupfilelog,
  1158                     self._deltaparentfn, self._builddeltaheader,
  1159                     self._deltaparentfn, self._builddeltaheader,
  1159                     ellipses=self._ellipses,
  1160                     ellipses=self._ellipses,
  1160                     clrevtolocalrev=clrevtolocalrev,
  1161                     clrevtolocalrev=clrevtolocalrev,
  1161                     fullclnodes=self._fullclnodes,
  1162                     fullclnodes=self._fullclnodes,