comparison mercurial/bundle2.py @ 29591:6215b5537ba5

bundle2: use a sorted dict for holding parameters An upcoming change that introduces a 2nd part parameter to a part reveals that `hg debugbundle` isn't deterministic because parameters are stored on n plain, unsorted dict. While we could change that command to sort before output, I think the more important underlying issue is that bundle2 reading is taking an ordered data structure and converting it to an unordered one. Plugging in util.sortdict() fixes that problem while preserving API compatibility. This patch also appears to shine light on the fact that we don't have tests verifying parts with multiple parameters roundtrip correctly. That would be a good thing to test (and fuzz)... someday.
author Gregory Szorc <gregory.szorc@gmail.com>
date Sun, 17 Jul 2016 14:51:00 -0700
parents 077d0535f51f
children 953839de96ab
comparison
equal deleted inserted replaced
29590:84c1a5942f1d 29591:6215b5537ba5
688 params = self._processallparams(params) 688 params = self._processallparams(params)
689 return params 689 return params
690 690
691 def _processallparams(self, paramsblock): 691 def _processallparams(self, paramsblock):
692 """""" 692 """"""
693 params = {} 693 params = util.sortdict()
694 for p in paramsblock.split(' '): 694 for p in paramsblock.split(' '):
695 p = p.split('=', 1) 695 p = p.split('=', 1)
696 p = [urlreq.unquote(i) for i in p] 696 p = [urlreq.unquote(i) for i in p]
697 if len(p) < 2: 697 if len(p) < 2:
698 p.append(None) 698 p.append(None)
1113 """internal function to setup all logic related parameters""" 1113 """internal function to setup all logic related parameters"""
1114 # make it read only to prevent people touching it by mistake. 1114 # make it read only to prevent people touching it by mistake.
1115 self.mandatoryparams = tuple(mandatoryparams) 1115 self.mandatoryparams = tuple(mandatoryparams)
1116 self.advisoryparams = tuple(advisoryparams) 1116 self.advisoryparams = tuple(advisoryparams)
1117 # user friendly UI 1117 # user friendly UI
1118 self.params = dict(self.mandatoryparams) 1118 self.params = util.sortdict(self.mandatoryparams)
1119 self.params.update(dict(self.advisoryparams)) 1119 self.params.update(self.advisoryparams)
1120 self.mandatorykeys = frozenset(p[0] for p in mandatoryparams) 1120 self.mandatorykeys = frozenset(p[0] for p in mandatoryparams)
1121 1121
1122 def _payloadchunks(self, chunknum=0): 1122 def _payloadchunks(self, chunknum=0):
1123 '''seek to specified chunk and start yielding data''' 1123 '''seek to specified chunk and start yielding data'''
1124 if len(self._chunkindex) == 0: 1124 if len(self._chunkindex) == 0: