Mercurial > public > mercurial-scm > hg-stable
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 |