comparison mercurial/bundle2.py @ 26542:b87e4638dabf

bundle2: add a way to just forward the bundle2 stream to another user There is use case for directly forward and bundle2 stream from the peer to a file (eg: 'hg incoming --bundle'), However ssh peers have no way to know the 'getbundle' is over except for actually interpreting the bundle. So we need to have the unbundle do the interpreting and forward job. The function is marked as private to highlight that this is terrible and that we are sorry.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Thu, 08 Oct 2015 01:40:21 -0700
parents d40029b4296e
children ee1bcb9aa6e4
comparison
equal deleted inserted replaced
26541:d40029b4296e 26542:b87e4638dabf
639 """interpret a bundle2 stream 639 """interpret a bundle2 stream
640 640
641 This class is fed with a binary stream and yields parts through its 641 This class is fed with a binary stream and yields parts through its
642 `iterparts` methods.""" 642 `iterparts` methods."""
643 643
644 _magicstring = 'HG20'
645
644 def __init__(self, ui, fp): 646 def __init__(self, ui, fp):
645 """If header is specified, we do not read it out of the stream.""" 647 """If header is specified, we do not read it out of the stream."""
646 self.ui = ui 648 self.ui = ui
647 self._decompressor = util.decompressors[None] 649 self._decompressor = util.decompressors[None]
648 super(unbundle20, self).__init__(fp) 650 super(unbundle20, self).__init__(fp)
695 indebug(self.ui, "ignoring unknown parameter %r" % name) 697 indebug(self.ui, "ignoring unknown parameter %r" % name)
696 else: 698 else:
697 raise error.BundleUnknownFeatureError(params=(name,)) 699 raise error.BundleUnknownFeatureError(params=(name,))
698 else: 700 else:
699 handler(self, name, value) 701 handler(self, name, value)
702
703 def _forwardchunks(self):
704 """utility to transfer a bundle2 as binary
705
706 This is made necessary by the fact the 'getbundle' command over 'ssh'
707 have no way to know then the reply end, relying on the bundle to be
708 interpreted to know its end. This is terrible and we are sorry, but we
709 needed to move forward to get general delta enabled.
710 """
711 yield self._magicstring
712 assert 'params' not in vars(self)
713 paramssize = self._unpack(_fstreamparamsize)[0]
714 if paramssize < 0:
715 raise error.BundleValueError('negative bundle param size: %i'
716 % paramssize)
717 yield _pack(_fstreamparamsize, paramssize)
718 if paramssize:
719 params = self._readexact(paramssize)
720 self._processallparams(params)
721 yield params
722 assert self._decompressor is util.decompressors[None]
723 # From there, payload might need to be decompressed
724 self._fp = self._decompressor(self._fp)
725 emptycount = 0
726 while emptycount < 2:
727 # so we can brainlessly loop
728 assert _fpartheadersize == _fpayloadsize
729 size = self._unpack(_fpartheadersize)[0]
730 yield _pack(_fpartheadersize, size)
731 if size:
732 emptycount = 0
733 else:
734 emptycount += 1
735 continue
736 if size == flaginterrupt:
737 continue
738 elif size < 0:
739 raise error.BundleValueError('negative chunk size: %i')
740 yield self._readexact(size)
741
700 742
701 def iterparts(self): 743 def iterparts(self):
702 """yield all parts contained in the stream""" 744 """yield all parts contained in the stream"""
703 # make sure param have been loaded 745 # make sure param have been loaded
704 self.params 746 self.params