--- a/hgext/convert/hg.py Sat Aug 15 13:46:30 2015 -0700
+++ b/hgext/convert/hg.py Fri Aug 14 15:22:47 2015 -0700
@@ -23,6 +23,7 @@
from mercurial.node import bin, hex, nullid
from mercurial import hg, util, context, bookmarks, error, scmutil, exchange
from mercurial import phases
+from mercurial import merge as mergemod
from common import NoRepo, commit, converter_source, converter_sink, mapfile
@@ -176,12 +177,51 @@
return fp.getvalue()
+ def _calculatemergedfiles(self, source, p1ctx, p2ctx):
+ """Calculates the files from p2 that we need to pull in when merging p1
+ and p2, given that the merge is coming from the given source.
+
+ This prevents us from losing files that only exist in the target p2 and
+ that don't come from the source repo (like if you're merging multiple
+ repositories together).
+ """
+ anc = [p1ctx.ancestor(p2ctx)]
+ # Calculate what files are coming from p2
+ actions, diverge, rename = mergemod.calculateupdates(
+ self.repo, p1ctx, p2ctx, anc,
+ True, # branchmerge
+ True, # force
+ False, # partial
+ False, # acceptremote
+ False, # followcopies
+ )
+
+ for file, (action, info, msg) in actions.iteritems():
+ if source.targetfilebelongstosource(file):
+ # If the file belongs to the source repo, ignore the p2
+ # since it will be covered by the existing fileset.
+ continue
+
+ # If the file requires actual merging, abort. We don't have enough
+ # context to resolve merges correctly.
+ if action in ['m', 'dm', 'cd', 'dc']:
+ raise util.Abort(_("unable to convert merge commit "
+ "since target parents do not merge cleanly (file "
+ "%s, parents %s and %s)") % (file, p1ctx,
+ p2ctx))
+ elif action == 'k':
+ # 'keep' means nothing changed from p1
+ continue
+ else:
+ # Any other change means we want to take the p2 version
+ yield file
+
def putcommit(self, files, copies, parents, commit, source, revmap, full,
cleanp2):
files = dict(files)
def getfilectx(repo, memctx, f):
- if p2ctx and f in cleanp2 and f not in copies:
+ if p2ctx and f in p2files and f not in copies:
self.ui.debug('reusing %s from p2\n' % f)
return p2ctx[f]
try:
@@ -255,6 +295,7 @@
while parents:
p1 = p2
p2 = parents.pop(0)
+ p1ctx = self.repo[p1]
p2ctx = None
if p2 != nullid:
p2ctx = self.repo[p2]
@@ -262,6 +303,13 @@
if full:
fileset.update(self.repo[p1])
fileset.update(self.repo[p2])
+
+ if p2ctx:
+ p2files = set(cleanp2)
+ for file in self._calculatemergedfiles(source, p1ctx, p2ctx):
+ p2files.add(file)
+ fileset.add(file)
+
ctx = context.memctx(self.repo, (p1, p2), text, fileset,
getfilectx, commit.author, commit.date, extra)