comparison hgext/histedit.py @ 24756:d71c2da01d0d

histedit: replace pickle with custom serialization Pickle is undesirable, so let's serialize it ourselves. We keep the ability to parse existing pickle blobs for now.
author Durham Goode <durham@fb.com>
date Mon, 13 Apr 2015 08:23:57 -0700
parents e767f5aba810
children 7b59f16174c5
comparison
equal deleted inserted replaced
24755:cd89f4e6faf2 24756:d71c2da01d0d
218 except IOError, err: 218 except IOError, err:
219 if err.errno != errno.ENOENT: 219 if err.errno != errno.ENOENT:
220 raise 220 raise
221 raise util.Abort(_('no histedit in progress')) 221 raise util.Abort(_('no histedit in progress'))
222 222
223 parentctxnode, rules, keep, topmost, replacements = pickle.load(fp) 223 try:
224 data = pickle.load(fp)
225 parentctxnode, rules, keep, topmost, replacements = data
226 except pickle.UnpicklingError:
227 data = self._load()
228 parentctxnode, rules, keep, topmost, replacements = data
224 229
225 self.parentctxnode = parentctxnode 230 self.parentctxnode = parentctxnode
226 self.rules = rules 231 self.rules = rules
227 self.keep = keep 232 self.keep = keep
228 self.topmost = topmost 233 self.topmost = topmost
229 self.replacements = replacements 234 self.replacements = replacements
230 235
231 def write(self): 236 def write(self):
232 fp = self.repo.vfs('histedit-state', 'w') 237 fp = self.repo.vfs('histedit-state', 'w')
233 pickle.dump((self.parentctxnode, self.rules, self.keep, 238 fp.write('v1\n')
234 self.topmost, self.replacements), fp) 239 fp.write('%s\n' % node.hex(self.parentctxnode))
240 fp.write('%s\n' % node.hex(self.topmost))
241 fp.write('%s\n' % self.keep)
242 fp.write('%d\n' % len(self.rules))
243 for rule in self.rules:
244 fp.write('%s%s\n' % (rule[1], rule[0]))
245 fp.write('%d\n' % len(self.replacements))
246 for replacement in self.replacements:
247 fp.write('%s%s\n' % (node.hex(replacement[0]), ''.join(node.hex(r)
248 for r in replacement[1])))
235 fp.close() 249 fp.close()
250
251 def _load(self):
252 fp = self.repo.vfs('histedit-state', 'r')
253 lines = [l[:-1] for l in fp.readlines()]
254
255 index = 0
256 lines[index] # version number
257 index += 1
258
259 parentctxnode = node.bin(lines[index])
260 index += 1
261
262 topmost = node.bin(lines[index])
263 index += 1
264
265 keep = lines[index] == 'True'
266 index += 1
267
268 # Rules
269 rules = []
270 rulelen = int(lines[index])
271 index += 1
272 for i in xrange(rulelen):
273 rule = lines[index]
274 rulehash = rule[:40]
275 ruleaction = rule[40:]
276 rules.append((ruleaction, rulehash))
277 index += 1
278
279 # Replacements
280 replacements = []
281 replacementlen = int(lines[index])
282 index += 1
283 for i in xrange(replacementlen):
284 replacement = lines[index]
285 original = node.bin(replacement[:40])
286 succ = [node.bin(replacement[i:i + 40]) for i in
287 range(40, len(replacement), 40)]
288 replacements.append((original, succ))
289 index += 1
290
291 fp.close()
292
293 return parentctxnode, rules, keep, topmost, replacements
236 294
237 def clear(self): 295 def clear(self):
238 self.repo.vfs.unlink('histedit-state') 296 self.repo.vfs.unlink('histedit-state')
239 297
240 def commitfuncfor(repo, src): 298 def commitfuncfor(repo, src):