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 |
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 |