345 if not opts.get('date') and opts.get('current_date'): |
345 if not opts.get('date') and opts.get('current_date'): |
346 opts['date'] = '%d %d' % util.makedate() |
346 opts['date'] = '%d %d' % util.makedate() |
347 if not opts.get('user') and opts.get('current_user'): |
347 if not opts.get('user') and opts.get('current_user'): |
348 opts['user'] = ui.username() |
348 opts['user'] = ui.username() |
349 |
349 |
350 |
|
351 createmarkers = obsolete.createmarkers |
|
352 if not util.safehasattr(obsolete.obsstore, 'relevantmarkers'): |
|
353 |
|
354 @eh.wrapfunction(mercurial.obsolete, 'createmarkers') |
|
355 def _createmarkers(orig, repo, relations, *args, **kwargs): |
|
356 """register parent information at prune time""" |
|
357 # every time this test is run, a kitten is slain. |
|
358 # Change it as soon as possible |
|
359 if '[,{metadata}]' in orig.__doc__: |
|
360 relations = list(relations) |
|
361 for idx, rel in enumerate(relations): |
|
362 prec = rel[0] |
|
363 sucs = rel[1] |
|
364 if not sucs: |
|
365 meta = {} |
|
366 if 2 < len(rel): |
|
367 meta.update(rel[2]) |
|
368 for i, p in enumerate(prec.parents(), 1): |
|
369 meta['p%i' % i] = p.hex() |
|
370 relations[idx] = (prec, sucs, meta) |
|
371 return orig(repo, relations, *args, **kwargs) |
|
372 |
|
373 def createmarkers(*args, **kwargs): |
|
374 return obsolete.createmarkers(*args, **kwargs) |
|
375 |
|
376 class pruneobsstore(obsolete.obsstore): |
|
377 |
|
378 def __init__(self, *args, **kwargs): |
|
379 self.prunedchildren = {} |
|
380 return super(pruneobsstore, self).__init__(*args, **kwargs) |
|
381 |
|
382 def _load(self, markers): |
|
383 markers = self._prunedetectingmarkers(markers) |
|
384 return super(pruneobsstore, self)._load(markers) |
|
385 |
|
386 |
|
387 def _prunedetectingmarkers(self, markers): |
|
388 for m in markers: |
|
389 if not m[1]: # no successors |
|
390 meta = obsolete.decodemeta(m[3]) |
|
391 if 'p1' in meta: |
|
392 p1 = node.bin(meta['p1']) |
|
393 self.prunedchildren.setdefault(p1, set()).add(m) |
|
394 if 'p2' in meta: |
|
395 p2 = node.bin(meta['p2']) |
|
396 self.prunedchildren.setdefault(p2, set()).add(m) |
|
397 yield m |
|
398 |
|
399 obsolete.obsstore = pruneobsstore |
|
400 |
|
401 @eh.addattr(obsolete.obsstore, 'relevantmarkers') |
|
402 def relevantmarkers(self, nodes): |
|
403 """return a set of all obsolescence marker relevant to a set of node. |
|
404 |
|
405 "relevant" to a set of node mean: |
|
406 |
|
407 - marker that use this changeset as successors |
|
408 - prune marker of direct children on this changeset. |
|
409 - recursive application of the two rules on precursors of these markers |
|
410 |
|
411 It a set so you cannot rely on order""" |
|
412 seennodes = set(nodes) |
|
413 seenmarkers = set() |
|
414 pendingnodes = set(nodes) |
|
415 precursorsmarkers = self.precursors |
|
416 prunedchildren = self.prunedchildren |
|
417 while pendingnodes: |
|
418 direct = set() |
|
419 for current in pendingnodes: |
|
420 direct.update(precursorsmarkers.get(current, ())) |
|
421 direct.update(prunedchildren.get(current, ())) |
|
422 direct -= seenmarkers |
|
423 pendingnodes = set([m[0] for m in direct]) |
|
424 seenmarkers |= direct |
|
425 pendingnodes -= seennodes |
|
426 seennodes |= pendingnodes |
|
427 return seenmarkers |
|
428 |
350 |
429 ##################################################################### |
351 ##################################################################### |
430 ### Critical fix ### |
352 ### Critical fix ### |
431 ##################################################################### |
353 ##################################################################### |
432 |
354 |
895 exc.__class__ = LocalMergeFailure |
817 exc.__class__ = LocalMergeFailure |
896 raise |
818 raise |
897 oldbookmarks = repo.nodebookmarks(nodesrc) |
819 oldbookmarks = repo.nodebookmarks(nodesrc) |
898 if nodenew is not None: |
820 if nodenew is not None: |
899 phases.retractboundary(repo, tr, destphase, [nodenew]) |
821 phases.retractboundary(repo, tr, destphase, [nodenew]) |
900 createmarkers(repo, [(repo[nodesrc], (repo[nodenew],))]) |
822 obsolete.createmarkers(repo, [(repo[nodesrc], (repo[nodenew],))]) |
901 for book in oldbookmarks: |
823 for book in oldbookmarks: |
902 repo._bookmarks[book] = nodenew |
824 repo._bookmarks[book] = nodenew |
903 else: |
825 else: |
904 createmarkers(repo, [(repo[nodesrc], ())]) |
826 obsolete.createmarkers(repo, [(repo[nodesrc], ())]) |
905 # Behave like rebase, move bookmarks to dest |
827 # Behave like rebase, move bookmarks to dest |
906 for book in oldbookmarks: |
828 for book in oldbookmarks: |
907 repo._bookmarks[book] = dest.node() |
829 repo._bookmarks[book] = dest.node() |
908 for book in destbookmarks: # restore bookmark that rebase move |
830 for book in destbookmarks: # restore bookmark that rebase move |
909 repo._bookmarks[book] = dest.node() |
831 repo._bookmarks[book] = dest.node() |
1454 _('rebasing to destination parent: %s\n') % prec.p1()) |
1376 _('rebasing to destination parent: %s\n') % prec.p1()) |
1455 try: |
1377 try: |
1456 tmpid = relocate(repo, bumped, prec.p1()) |
1378 tmpid = relocate(repo, bumped, prec.p1()) |
1457 if tmpid is not None: |
1379 if tmpid is not None: |
1458 tmpctx = repo[tmpid] |
1380 tmpctx = repo[tmpid] |
1459 createmarkers(repo, [(bumped, (tmpctx,))]) |
1381 obsolete.createmarkers(repo, [(bumped, (tmpctx,))]) |
1460 except MergeFailure: |
1382 except MergeFailure: |
1461 repo.opener.write('graftstate', bumped.hex() + '\n') |
1383 repo.opener.write('graftstate', bumped.hex() + '\n') |
1462 repo.ui.write_err(_('evolution failed!\n')) |
1384 repo.ui.write_err(_('evolution failed!\n')) |
1463 repo.ui.write_err( |
1385 repo.ui.write_err( |
1464 _('fix conflict and run "hg evolve --continue"\n')) |
1386 _('fix conflict and run "hg evolve --continue"\n')) |
1496 date=bumped.date(), |
1418 date=bumped.date(), |
1497 extra=bumped.extra()) |
1419 extra=bumped.extra()) |
1498 |
1420 |
1499 newid = repo.commitctx(new) |
1421 newid = repo.commitctx(new) |
1500 if newid is None: |
1422 if newid is None: |
1501 createmarkers(repo, [(tmpctx, ())]) |
1423 obsolete.createmarkers(repo, [(tmpctx, ())]) |
1502 newid = prec.node() |
1424 newid = prec.node() |
1503 else: |
1425 else: |
1504 phases.retractboundary(repo, tr, bumped.phase(), [newid]) |
1426 phases.retractboundary(repo, tr, bumped.phase(), [newid]) |
1505 createmarkers(repo, [(tmpctx, (repo[newid],))], |
1427 obsolete.createmarkers(repo, [(tmpctx, (repo[newid],))], |
1506 flag=obsolete.bumpedfix) |
1428 flag=obsolete.bumpedfix) |
1507 bmupdate(newid) |
1429 bmupdate(newid) |
1508 tr.close() |
1430 tr.close() |
1509 repo.ui.status(_('committed as %s\n') % node.short(newid)) |
1431 repo.ui.status(_('committed as %s\n') % node.short(newid)) |
1510 finally: |
1432 finally: |
1809 relations = [(p, sucs) for p in precs] |
1731 relations = [(p, sucs) for p in precs] |
1810 if biject: |
1732 if biject: |
1811 relations = [(p, (s,)) for p, s in zip(precs, sucs)] |
1733 relations = [(p, (s,)) for p, s in zip(precs, sucs)] |
1812 |
1734 |
1813 # create markers |
1735 # create markers |
1814 createmarkers(repo, relations, metadata=metadata) |
1736 obsolete.createmarkers(repo, relations, metadata=metadata) |
1815 |
1737 |
1816 # informs that changeset have been pruned |
1738 # informs that changeset have been pruned |
1817 ui.status(_('%i changesets pruned\n') % len(precs)) |
1739 ui.status(_('%i changesets pruned\n') % len(precs)) |
1818 |
1740 |
1819 wdp = repo['.'] |
1741 wdp = repo['.'] |
2035 newid = _commitfiltered(repo, old, match, target=rev) |
1957 newid = _commitfiltered(repo, old, match, target=rev) |
2036 if newid is None: |
1958 if newid is None: |
2037 raise util.Abort(_('nothing to uncommit'), |
1959 raise util.Abort(_('nothing to uncommit'), |
2038 hint=_("use --all to uncommit all files")) |
1960 hint=_("use --all to uncommit all files")) |
2039 # Move local changes on filtered changeset |
1961 # Move local changes on filtered changeset |
2040 createmarkers(repo, [(old, (repo[newid],))]) |
1962 obsolete.createmarkers(repo, [(old, (repo[newid],))]) |
2041 phases.retractboundary(repo, tr, oldphase, [newid]) |
1963 phases.retractboundary(repo, tr, oldphase, [newid]) |
2042 repo.dirstate.setparents(newid, node.nullid) |
1964 repo.dirstate.setparents(newid, node.nullid) |
2043 _uncommitdirstate(repo, old, match) |
1965 _uncommitdirstate(repo, old, match) |
2044 updatebookmarks(newid) |
1966 updatebookmarks(newid) |
2045 if not repo[newid].files(): |
1967 if not repo[newid].files(): |
2121 [p1, p2], |
2043 [p1, p2], |
2122 commitopts={'extra': extra}) |
2044 commitopts={'extra': extra}) |
2123 # store touched version to help potential children |
2045 # store touched version to help potential children |
2124 newmapping[ctx.node()] = new |
2046 newmapping[ctx.node()] = new |
2125 if not duplicate: |
2047 if not duplicate: |
2126 createmarkers(repo, [(ctx, (repo[new],))]) |
2048 obsolete.createmarkers(repo, [(ctx, (repo[new],))]) |
2127 phases.retractboundary(repo, tr, ctx.phase(), [new]) |
2049 phases.retractboundary(repo, tr, ctx.phase(), [new]) |
2128 if ctx in repo[None].parents(): |
2050 if ctx in repo[None].parents(): |
2129 repo.dirstate.setparents(new, node.nullid) |
2051 repo.dirstate.setparents(new, node.nullid) |
2130 tr.close() |
2052 tr.close() |
2131 finally: |
2053 finally: |
2226 |
2148 |
2227 newid, unusedvariable = rewrite(repo, root, allctx, head, |
2149 newid, unusedvariable = rewrite(repo, root, allctx, head, |
2228 [root.p1().node(), root.p2().node()], |
2150 [root.p1().node(), root.p2().node()], |
2229 commitopts=commitopts) |
2151 commitopts=commitopts) |
2230 phases.retractboundary(repo, tr, targetphase, [newid]) |
2152 phases.retractboundary(repo, tr, targetphase, [newid]) |
2231 createmarkers(repo, [(ctx, (repo[newid],)) |
2153 obsolete.createmarkers(repo, [(ctx, (repo[newid],)) |
2232 for ctx in allctx]) |
2154 for ctx in allctx]) |
2233 tr.close() |
2155 tr.close() |
2234 finally: |
2156 finally: |
2235 tr.release() |
2157 tr.release() |
2236 ui.status('%i changesets folded\n' % len(revs)) |
2158 ui.status('%i changesets folded\n' % len(revs)) |