comparison mercurial/merge.py @ 38494:d4be8ea8f22d

merge: add a 'keepconflictparent' argument to graft Before this change, `merge.graft` was always dropping the "grafted" changeset from the parent. This is impractical in case of conflict as the second parent can be useful to help with conflict resolution. We add a new boolean parameter to control this behavior. This will make using `merge.graft` directly in shelve practicable. Differential Revision: https://phab.mercurial-scm.org/D3692
author Boris Feld <boris.feld@octobus.net>
date Tue, 29 May 2018 00:26:20 +0200
parents 00368bc0a614
children be4984261611
comparison
equal deleted inserted replaced
38493:da2a7d8354b2 38494:d4be8ea8f22d
2192 if not partial: 2192 if not partial:
2193 repo.hook('update', parent1=xp1, parent2=xp2, 2193 repo.hook('update', parent1=xp1, parent2=xp2,
2194 error=stats.unresolvedcount) 2194 error=stats.unresolvedcount)
2195 return stats 2195 return stats
2196 2196
2197 def graft(repo, ctx, pctx, labels, keepparent=False): 2197 def graft(repo, ctx, pctx, labels, keepparent=False,
2198 keepconflictparent=False):
2198 """Do a graft-like merge. 2199 """Do a graft-like merge.
2199 2200
2200 This is a merge where the merge ancestor is chosen such that one 2201 This is a merge where the merge ancestor is chosen such that one
2201 or more changesets are grafted onto the current changeset. In 2202 or more changesets are grafted onto the current changeset. In
2202 addition to the merge, this fixes up the dirstate to include only 2203 addition to the merge, this fixes up the dirstate to include only
2205 2206
2206 ctx - changeset to rebase 2207 ctx - changeset to rebase
2207 pctx - merge base, usually ctx.p1() 2208 pctx - merge base, usually ctx.p1()
2208 labels - merge labels eg ['local', 'graft'] 2209 labels - merge labels eg ['local', 'graft']
2209 keepparent - keep second parent if any 2210 keepparent - keep second parent if any
2211 keepparent - if unresolved, keep parent used for the merge
2210 2212
2211 """ 2213 """
2212 # If we're grafting a descendant onto an ancestor, be sure to pass 2214 # If we're grafting a descendant onto an ancestor, be sure to pass
2213 # mergeancestor=True to update. This does two things: 1) allows the merge if 2215 # mergeancestor=True to update. This does two things: 1) allows the merge if
2214 # the destination is the same as the parent of the ctx (so we can use graft 2216 # the destination is the same as the parent of the ctx (so we can use graft
2218 mergeancestor = repo.changelog.isancestor(repo['.'].node(), ctx.node()) 2220 mergeancestor = repo.changelog.isancestor(repo['.'].node(), ctx.node())
2219 2221
2220 stats = update(repo, ctx.node(), True, True, pctx.node(), 2222 stats = update(repo, ctx.node(), True, True, pctx.node(),
2221 mergeancestor=mergeancestor, labels=labels) 2223 mergeancestor=mergeancestor, labels=labels)
2222 2224
2223 pother = nullid 2225
2224 parents = ctx.parents() 2226 if keepconflictparent and stats.unresolvedcount:
2225 if keepparent and len(parents) == 2 and pctx in parents: 2227 pother = ctx.node()
2226 parents.remove(pctx) 2228 else:
2227 pother = parents[0].node() 2229 pother = nullid
2230 parents = ctx.parents()
2231 if keepparent and len(parents) == 2 and pctx in parents:
2232 parents.remove(pctx)
2233 pother = parents[0].node()
2228 2234
2229 with repo.dirstate.parentchange(): 2235 with repo.dirstate.parentchange():
2230 repo.setparents(repo['.'].node(), pother) 2236 repo.setparents(repo['.'].node(), pother)
2231 repo.dirstate.write(repo.currenttransaction()) 2237 repo.dirstate.write(repo.currenttransaction())
2232 # fix up dirstate for copies and renames 2238 # fix up dirstate for copies and renames