comparison hgext/evolve.py @ 1067:5d063fed9e3d

evolve: yield to relevant markers handling in core The handling of obsolescence marker is now performed in core. If we detect a mercurial with such power we skip the wrapping from evolve. This changeset also suffer from massive diff from the change in display of obsolescence marker with parent information introduced at the same time in core.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Wed, 20 Aug 2014 20:49:48 -0700
parents 742c1ce79a96
children 9f87b103f7b5 bac4e0bc9f6a
comparison
equal deleted inserted replaced
1066:045f7de9e4d3 1067:5d063fed9e3d
68 from mercurial import wireproto 68 from mercurial import wireproto
69 from mercurial import localrepo 69 from mercurial import localrepo
70 from mercurial.hgweb import hgweb_mod 70 from mercurial.hgweb import hgweb_mod
71 from mercurial import bundle2 71 from mercurial import bundle2
72 72
73 cmdtable = {}
74 command = cmdutil.command(cmdtable)
75
73 _pack = struct.pack 76 _pack = struct.pack
74 77
75 if gboptsmap is not None: 78 if gboptsmap is not None:
76 memfilectx = context.memfilectx 79 memfilectx = context.memfilectx
77 elif gboptslist is not None: 80 elif gboptslist is not None:
355 if not opts.get('date') and opts.get('current_date'): 358 if not opts.get('date') and opts.get('current_date'):
356 opts['date'] = '%d %d' % util.makedate() 359 opts['date'] = '%d %d' % util.makedate()
357 if not opts.get('user') and opts.get('current_user'): 360 if not opts.get('user') and opts.get('current_user'):
358 opts['user'] = ui.username() 361 opts['user'] = ui.username()
359 362
360 @eh.wrapfunction(mercurial.obsolete, 'createmarkers') 363
361 def _createmarkers(orig, repo, relations, *args, **kwargs): 364 createmarkers = obsolete.createmarkers
362 """register parent information at prune time""" 365 if not util.safehasattr(obsolete.obsstore, 'relevantmarkers'):
363 # every time this test is run, a kitten is slain. 366
364 # Change it as soon as possible 367 @eh.wrapfunction(mercurial.obsolete, 'createmarkers')
365 if '[,{metadata}]' in orig.__doc__: 368 def _createmarkers(orig, repo, relations, *args, **kwargs):
366 relations = list(relations) 369 """register parent information at prune time"""
367 for idx, rel in enumerate(relations): 370 # every time this test is run, a kitten is slain.
368 prec = rel[0] 371 # Change it as soon as possible
369 sucs = rel[1] 372 if '[,{metadata}]' in orig.__doc__:
370 if not sucs: 373 relations = list(relations)
371 meta = {} 374 for idx, rel in enumerate(relations):
372 if 2 < len(rel): 375 prec = rel[0]
373 meta.update(rel[2]) 376 sucs = rel[1]
374 for i, p in enumerate(prec.parents(), 1): 377 if not sucs:
375 meta['p%i' % i] = p.hex() 378 meta = {}
376 relations[idx] = (prec, sucs, meta) 379 if 2 < len(rel):
377 return orig(repo, relations, *args, **kwargs) 380 meta.update(rel[2])
378 381 for i, p in enumerate(prec.parents(), 1):
379 def createmarkers(*args, **kwargs): 382 meta['p%i' % i] = p.hex()
380 return obsolete.createmarkers(*args, **kwargs) 383 relations[idx] = (prec, sucs, meta)
381 384 return orig(repo, relations, *args, **kwargs)
382 class pruneobsstore(obsolete.obsstore): 385
383 386 def createmarkers(*args, **kwargs):
384 def __init__(self, *args, **kwargs): 387 return obsolete.createmarkers(*args, **kwargs)
385 self.prunedchildren = {} 388
386 return super(pruneobsstore, self).__init__(*args, **kwargs) 389 class pruneobsstore(obsolete.obsstore):
387 390
388 def _load(self, markers): 391 def __init__(self, *args, **kwargs):
389 markers = self._prunedetectingmarkers(markers) 392 self.prunedchildren = {}
390 return super(pruneobsstore, self)._load(markers) 393 return super(pruneobsstore, self).__init__(*args, **kwargs)
391 394
392 395 def _load(self, markers):
393 def _prunedetectingmarkers(self, markers): 396 markers = self._prunedetectingmarkers(markers)
394 for m in markers: 397 return super(pruneobsstore, self)._load(markers)
395 if not m[1]: # no successors 398
396 meta = obsolete.decodemeta(m[3]) 399
397 if 'p1' in meta: 400 def _prunedetectingmarkers(self, markers):
398 p1 = node.bin(meta['p1']) 401 for m in markers:
399 self.prunedchildren.setdefault(p1, set()).add(m) 402 if not m[1]: # no successors
400 if 'p2' in meta: 403 meta = obsolete.decodemeta(m[3])
401 p2 = node.bin(meta['p2']) 404 if 'p1' in meta:
402 self.prunedchildren.setdefault(p2, set()).add(m) 405 p1 = node.bin(meta['p1'])
403 yield m 406 self.prunedchildren.setdefault(p1, set()).add(m)
404 407 if 'p2' in meta:
405 obsolete.obsstore = pruneobsstore 408 p2 = node.bin(meta['p2'])
409 self.prunedchildren.setdefault(p2, set()).add(m)
410 yield m
411
412 obsolete.obsstore = pruneobsstore
413
414 @eh.addattr(obsolete.obsstore, 'relevantmarkers')
415 def relevantmarkers(self, nodes):
416 """return a set of all obsolescence marker relevant to a set of node.
417
418 "relevant" to a set of node mean:
419
420 - marker that use this changeset as successors
421 - prune marker of direct children on this changeset.
422 - recursive application of the two rules on precursors of these markers
423
424 It a set so you cannot rely on order"""
425 seennodes = set(nodes)
426 seenmarkers = set()
427 pendingnodes = set(nodes)
428 precursorsmarkers = self.precursors
429 prunedchildren = self.prunedchildren
430 while pendingnodes:
431 direct = set()
432 for current in pendingnodes:
433 direct.update(precursorsmarkers.get(current, ()))
434 direct.update(prunedchildren.get(current, ()))
435 direct -= seenmarkers
436 pendingnodes = set([m[0] for m in direct])
437 seenmarkers |= direct
438 pendingnodes -= seennodes
439 seennodes |= pendingnodes
440 return seenmarkers
441
442 @command('debugobsoleterelevant',
443 [],
444 'REVSET')
445 def debugobsoleterelevant(ui, repo, *revsets):
446 """print allobsolescence marker relevant to a set of revision"""
447 nodes = [ctx.node() for ctx in repo.set('%lr', revsets)]
448 markers = repo.obsstore.relevantmarkers(nodes)
449 for rawmarker in sorted(markers):
450 marker = obsolete.marker(repo, rawmarker)
451 cmdutil.showmarker(ui, marker)
452
406 453
407 ##################################################################### 454 #####################################################################
408 ### Critical fix ### 455 ### Critical fix ###
409 ##################################################################### 456 #####################################################################
410 457
911 repo._bookmarks.write() 958 repo._bookmarks.write()
912 return updatebookmarks 959 return updatebookmarks
913 960
914 ### new command 961 ### new command
915 ############################# 962 #############################
916 cmdtable = {}
917 command = cmdutil.command(cmdtable)
918 metadataopts = [ 963 metadataopts = [
919 ('d', 'date', '', 964 ('d', 'date', '',
920 _('record the specified date in metadata'), _('DATE')), 965 _('record the specified date in metadata'), _('DATE')),
921 ('u', 'user', '', 966 ('u', 'user', '',
922 _('record the specified user in metadata'), _('USER')), 967 _('record the specified user in metadata'), _('USER')),
2283 if ui.configbool('experimental', 'verbose-obsolescence-exchange', False): 2328 if ui.configbool('experimental', 'verbose-obsolescence-exchange', False):
2284 topic = 'OBSEXC' 2329 topic = 'OBSEXC'
2285 ui.progress(topic, *args, **kwargs) 2330 ui.progress(topic, *args, **kwargs)
2286 2331
2287 2332
2288 @command('debugobsoleterelevant',
2289 [],
2290 'REVSET')
2291 def debugobsoleterelevant(ui, repo, *revsets):
2292 """print allobsolescence marker relevant to a set of revision"""
2293 nodes = [ctx.node() for ctx in repo.set('%lr', revsets)]
2294 markers = repo.obsstore.relevantmarkers(nodes)
2295 for rawmarker in sorted(markers):
2296 marker = obsolete.marker(repo, rawmarker)
2297 cmdutil.showmarker(ui, marker)
2298
2299 @eh.addattr(obsolete.obsstore, 'relevantmarkers')
2300 def relevantmarkers(self, nodes):
2301 """return a set of all obsolescence marker relevant to a set of node.
2302
2303 "relevant" to a set of node mean:
2304
2305 - marker that use this changeset as successors
2306 - prune marker of direct children on this changeset.
2307 - recursive application of the two rules on precursors of these markers
2308
2309 It a set so you cannot rely on order"""
2310 seennodes = set(nodes)
2311 seenmarkers = set()
2312 pendingnodes = set(nodes)
2313 precursorsmarkers = self.precursors
2314 prunedchildren = self.prunedchildren
2315 while pendingnodes:
2316 direct = set()
2317 for current in pendingnodes:
2318 direct.update(precursorsmarkers.get(current, ()))
2319 direct.update(prunedchildren.get(current, ()))
2320 direct -= seenmarkers
2321 pendingnodes = set([m[0] for m in direct])
2322 seenmarkers |= direct
2323 pendingnodes -= seennodes
2324 seennodes |= pendingnodes
2325 return seenmarkers
2326 2333
2327 2334
2328 _pushkeyescape = getattr(obsolete, '_pushkeyescape', None) 2335 _pushkeyescape = getattr(obsolete, '_pushkeyescape', None)
2329 if _pushkeyescape is None: 2336 if _pushkeyescape is None:
2330 _maxpayload = 5300 2337 _maxpayload = 5300