Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/merge.py @ 27267:d6859d86a5d5
merge.graft: add option to keep second parent
Currently merge.graft re-writes the dirstate so only a single
parent is kept. For some cases, like evolving a merge commit,
this behaviour is not desired. More specifically, this is
needed to fix issue4389.
author | Andrew Halberstadt <ahalberstadt@mozilla.com> |
---|---|
date | Thu, 03 Dec 2015 23:01:59 -0500 |
parents | 25e4b2f000c5 |
children | 777f668eca70 |
comparison
equal
deleted
inserted
replaced
27266:4dccc37b87bd | 27267:d6859d86a5d5 |
---|---|
1487 | 1487 |
1488 if not partial: | 1488 if not partial: |
1489 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3]) | 1489 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3]) |
1490 return stats | 1490 return stats |
1491 | 1491 |
1492 def graft(repo, ctx, pctx, labels): | 1492 def graft(repo, ctx, pctx, labels, keepparent=False): |
1493 """Do a graft-like merge. | 1493 """Do a graft-like merge. |
1494 | 1494 |
1495 This is a merge where the merge ancestor is chosen such that one | 1495 This is a merge where the merge ancestor is chosen such that one |
1496 or more changesets are grafted onto the current changeset. In | 1496 or more changesets are grafted onto the current changeset. In |
1497 addition to the merge, this fixes up the dirstate to include only | 1497 addition to the merge, this fixes up the dirstate to include only |
1498 a single parent and tries to duplicate any renames/copies | 1498 a single parent (if keepparent is False) and tries to duplicate any |
1499 appropriately. | 1499 renames/copies appropriately. |
1500 | 1500 |
1501 ctx - changeset to rebase | 1501 ctx - changeset to rebase |
1502 pctx - merge base, usually ctx.p1() | 1502 pctx - merge base, usually ctx.p1() |
1503 labels - merge labels eg ['local', 'graft'] | 1503 labels - merge labels eg ['local', 'graft'] |
1504 keepparent - keep second parent if any | |
1504 | 1505 |
1505 """ | 1506 """ |
1506 # If we're grafting a descendant onto an ancestor, be sure to pass | 1507 # If we're grafting a descendant onto an ancestor, be sure to pass |
1507 # mergeancestor=True to update. This does two things: 1) allows the merge if | 1508 # mergeancestor=True to update. This does two things: 1) allows the merge if |
1508 # the destination is the same as the parent of the ctx (so we can use graft | 1509 # the destination is the same as the parent of the ctx (so we can use graft |
1512 mergeancestor = repo.changelog.isancestor(repo['.'].node(), ctx.node()) | 1513 mergeancestor = repo.changelog.isancestor(repo['.'].node(), ctx.node()) |
1513 | 1514 |
1514 stats = update(repo, ctx.node(), True, True, False, pctx.node(), | 1515 stats = update(repo, ctx.node(), True, True, False, pctx.node(), |
1515 mergeancestor=mergeancestor, labels=labels) | 1516 mergeancestor=mergeancestor, labels=labels) |
1516 | 1517 |
1517 # drop the second merge parent | 1518 pother = nullid |
1519 parents = ctx.parents() | |
1520 if keepparent and len(parents) == 2 and pctx in parents: | |
1521 parents.remove(pctx) | |
1522 pother = parents[0].node() | |
1523 | |
1518 repo.dirstate.beginparentchange() | 1524 repo.dirstate.beginparentchange() |
1519 repo.setparents(repo['.'].node(), nullid) | 1525 repo.setparents(repo['.'].node(), pother) |
1520 repo.dirstate.write(repo.currenttransaction()) | 1526 repo.dirstate.write(repo.currenttransaction()) |
1521 # fix up dirstate for copies and renames | 1527 # fix up dirstate for copies and renames |
1522 copies.duplicatecopies(repo, ctx.rev(), pctx.rev()) | 1528 copies.duplicatecopies(repo, ctx.rev(), pctx.rev()) |
1523 repo.dirstate.endparentchange() | 1529 repo.dirstate.endparentchange() |
1524 return stats | 1530 return stats |