mercurial/changegroup.py
changeset 26587 56b2bcea2529
parent 26540 7469067de2ba
child 26595 be0489770925
equal deleted inserted replaced
26586:d51c658d3f04 26587:56b2bcea2529
    35 
    35 
    36 def readexactly(stream, n):
    36 def readexactly(stream, n):
    37     '''read n bytes from stream.read and abort if less was available'''
    37     '''read n bytes from stream.read and abort if less was available'''
    38     s = stream.read(n)
    38     s = stream.read(n)
    39     if len(s) < n:
    39     if len(s) < n:
    40         raise util.Abort(_("stream ended unexpectedly"
    40         raise error.Abort(_("stream ended unexpectedly"
    41                            " (got %d bytes, expected %d)")
    41                            " (got %d bytes, expected %d)")
    42                           % (len(s), n))
    42                           % (len(s), n))
    43     return s
    43     return s
    44 
    44 
    45 def getchunk(stream):
    45 def getchunk(stream):
    46     """return the next chunk from stream as a string"""
    46     """return the next chunk from stream as a string"""
    47     d = readexactly(stream, 4)
    47     d = readexactly(stream, 4)
    48     l = struct.unpack(">l", d)[0]
    48     l = struct.unpack(">l", d)[0]
    49     if l <= 4:
    49     if l <= 4:
    50         if l:
    50         if l:
    51             raise util.Abort(_("invalid chunk length %d") % l)
    51             raise error.Abort(_("invalid chunk length %d") % l)
    52         return ""
    52         return ""
    53     return readexactly(stream, l - 4)
    53     return readexactly(stream, l - 4)
    54 
    54 
    55 def chunkheader(length):
    55 def chunkheader(length):
    56     """return a changegroup chunk header (string)"""
    56     """return a changegroup chunk header (string)"""
   142         chunkiter = bundle.getchunks()
   142         chunkiter = bundle.getchunks()
   143     else:
   143     else:
   144         # compression argument is only for the bundle2 case
   144         # compression argument is only for the bundle2 case
   145         assert compression is None
   145         assert compression is None
   146         if cg.version != '01':
   146         if cg.version != '01':
   147             raise util.Abort(_('old bundle types only supports v1 '
   147             raise error.Abort(_('old bundle types only supports v1 '
   148                                'changegroups'))
   148                                 'changegroups'))
   149         header, comp = bundletypes[bundletype]
   149         header, comp = bundletypes[bundletype]
   150         if comp not in util.compressors:
   150         if comp not in util.compressors:
   151             raise util.Abort(_('unknown stream compression type: %s')
   151             raise error.Abort(_('unknown stream compression type: %s')
   152                              % comp)
   152                               % comp)
   153         z = util.compressors[comp]()
   153         z = util.compressors[comp]()
   154         subchunkiter = cg.getchunks()
   154         subchunkiter = cg.getchunks()
   155         def chunkiter():
   155         def chunkiter():
   156             yield header
   156             yield header
   157             for chunk in subchunkiter:
   157             for chunk in subchunkiter:
   173     version = '01'
   173     version = '01'
   174     def __init__(self, fh, alg):
   174     def __init__(self, fh, alg):
   175         if alg == 'UN':
   175         if alg == 'UN':
   176             alg = None # get more modern without breaking too much
   176             alg = None # get more modern without breaking too much
   177         if not alg in util.decompressors:
   177         if not alg in util.decompressors:
   178             raise util.Abort(_('unknown stream compression type: %s')
   178             raise error.Abort(_('unknown stream compression type: %s')
   179                              % alg)
   179                              % alg)
   180         if alg == 'BZ':
   180         if alg == 'BZ':
   181             alg = '_truncatedBZ'
   181             alg = '_truncatedBZ'
   182         self._stream = util.decompressors[alg](fh)
   182         self._stream = util.decompressors[alg](fh)
   183         self._type = alg
   183         self._type = alg
   196     def chunklength(self):
   196     def chunklength(self):
   197         d = readexactly(self._stream, 4)
   197         d = readexactly(self._stream, 4)
   198         l = struct.unpack(">l", d)[0]
   198         l = struct.unpack(">l", d)[0]
   199         if l <= 4:
   199         if l <= 4:
   200             if l:
   200             if l:
   201                 raise util.Abort(_("invalid chunk length %d") % l)
   201                 raise error.Abort(_("invalid chunk length %d") % l)
   202             return 0
   202             return 0
   203         if self.callback:
   203         if self.callback:
   204             self.callback()
   204             self.callback()
   205         return l - 4
   205         return l - 4
   206 
   206 
   475         # for progress output
   475         # for progress output
   476         msgfiles = _('files')
   476         msgfiles = _('files')
   477         for i, fname in enumerate(sorted(changedfiles)):
   477         for i, fname in enumerate(sorted(changedfiles)):
   478             filerevlog = repo.file(fname)
   478             filerevlog = repo.file(fname)
   479             if not filerevlog:
   479             if not filerevlog:
   480                 raise util.Abort(_("empty or missing revlog for %s") % fname)
   480                 raise error.Abort(_("empty or missing revlog for %s") % fname)
   481 
   481 
   482             linkrevnodes = linknodes(filerevlog, fname)
   482             linkrevnodes = linknodes(filerevlog, fname)
   483             # Lookup for filenodes, we collected the linkrev nodes above in the
   483             # Lookup for filenodes, we collected the linkrev nodes above in the
   484             # fastpath case and with lookupmf in the slowpath case.
   484             # fastpath case and with lookupmf in the slowpath case.
   485             def lookupfilelog(x):
   485             def lookupfilelog(x):
   686         pr()
   686         pr()
   687         fl = repo.file(f)
   687         fl = repo.file(f)
   688         o = len(fl)
   688         o = len(fl)
   689         try:
   689         try:
   690             if not fl.addgroup(source, revmap, trp):
   690             if not fl.addgroup(source, revmap, trp):
   691                 raise util.Abort(_("received file revlog group is empty"))
   691                 raise error.Abort(_("received file revlog group is empty"))
   692         except error.CensoredBaseError as e:
   692         except error.CensoredBaseError as e:
   693             raise util.Abort(_("received delta base is censored: %s") % e)
   693             raise error.Abort(_("received delta base is censored: %s") % e)
   694         revisions += len(fl) - o
   694         revisions += len(fl) - o
   695         files += 1
   695         files += 1
   696         if f in needfiles:
   696         if f in needfiles:
   697             needs = needfiles[f]
   697             needs = needfiles[f]
   698             for new in xrange(o, len(fl)):
   698             for new in xrange(o, len(fl)):
   699                 n = fl.node(new)
   699                 n = fl.node(new)
   700                 if n in needs:
   700                 if n in needs:
   701                     needs.remove(n)
   701                     needs.remove(n)
   702                 else:
   702                 else:
   703                     raise util.Abort(
   703                     raise error.Abort(
   704                         _("received spurious file revlog entry"))
   704                         _("received spurious file revlog entry"))
   705             if not needs:
   705             if not needs:
   706                 del needfiles[f]
   706                 del needfiles[f]
   707     repo.ui.progress(_('files'), None)
   707     repo.ui.progress(_('files'), None)
   708 
   708 
   710         fl = repo.file(f)
   710         fl = repo.file(f)
   711         for n in needs:
   711         for n in needs:
   712             try:
   712             try:
   713                 fl.rev(n)
   713                 fl.rev(n)
   714             except error.LookupError:
   714             except error.LookupError:
   715                 raise util.Abort(
   715                 raise error.Abort(
   716                     _('missing file data for %s:%s - run hg verify') %
   716                     _('missing file data for %s:%s - run hg verify') %
   717                     (f, hex(n)))
   717                     (f, hex(n)))
   718 
   718 
   719     return revisions, files
   719     return revisions, files
   720 
   720 
   782         srccontent = cl.addgroup(source, csmap, trp,
   782         srccontent = cl.addgroup(source, csmap, trp,
   783                                  addrevisioncb=onchangelog)
   783                                  addrevisioncb=onchangelog)
   784         efiles = len(efiles)
   784         efiles = len(efiles)
   785 
   785 
   786         if not (srccontent or emptyok):
   786         if not (srccontent or emptyok):
   787             raise util.Abort(_("received changelog group is empty"))
   787             raise error.Abort(_("received changelog group is empty"))
   788         clend = len(cl)
   788         clend = len(cl)
   789         changesets = clend - clstart
   789         changesets = clend - clstart
   790         repo.ui.progress(_('changesets'), None)
   790         repo.ui.progress(_('changesets'), None)
   791 
   791 
   792         # pull off the manifest group
   792         # pull off the manifest group