mercurial/merge.py
changeset 27267 d6859d86a5d5
parent 27137 25e4b2f000c5
child 27316 777f668eca70
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