[PATCH] Add support for 'union' merge strategy
Erik Huelsmann
ehuels at gmail.com
Fri Jun 26 19:24:53 UTC 2015
As discussed on IRC, I'm submitting my first mercurial patch: to support
the 'union' merge strategy, where both sides of a conflict are included in
the result and not marking the file as conflicted.
Please tell me how to proceed. Thanks for your comments and help!
Regards,
Erik.
# HG changeset patch
# User erik <erik at hucs.nl>
# Date 1435346089 -7200
# Fri Jun 26 21:14:49 2015 +0200
# Node ID d35c0f4e71ed16627a2c95539121bfda2b253157
# Parent ff5172c830022b64cc5bd1bae36b2276e9dc6e5d
internal merge tool: add support for 'union' merge strategy.
One use-case for this merge strategy is the Changelog file being changed
on multiple branches and conflicting when being merged back to the main
branch.
diff -r ff5172c83002 -r d35c0f4e71ed mercurial/filemerge.py
--- a/mercurial/filemerge.py Wed Jun 24 13:41:27 2015 -0500
+++ b/mercurial/filemerge.py Fri Jun 26 21:14:49 2015 +0200
@@ -212,10 +212,7 @@
util.copyfile(back, a) # restore from backup and try again
return 1 # continue merging
- at internaltool('merge', True,
- _("merging %s incomplete! "
- "(edit conflicts, then use 'hg resolve --mark')\n"))
-def _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files,
labels=None):
+def __imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels,
mode):
"""
Uses the internal non-interactive simple merge algorithm for merging
files. It will fail if there are any conflicts and leave markers in
@@ -232,10 +229,38 @@
ui = repo.ui
- r = simplemerge.simplemerge(ui, a, b, c, label=labels)
+ r = simplemerge.simplemerge(ui, a, b, c, label=labels, mode=mode)
return True, r
return False, 0
+
+ at internaltool('merge', True,
+ _("merging %s incomplete! "
+ "(edit conflicts, then use 'hg resolve --mark')\n"))
+def _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files,
labels=None):
+ """
+ Uses the internal non-interactive simple merge algorithm for merging
+ files. It will fail if there are any conflicts and leave markers in
+ the partially merged file. Markers will have two sections, one for
each side
+ of merge."""
+
+ return __imerge(repo, mynode, orig, fcd, fco, fca, toolconf,
+ files, labels, 'merge')
+
+
+ at internaltool('union', True,
+ _("merging %s incomplete! "
+ "(edit conflicts, then use 'hg resolve --mark')\n"))
+def _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files,
labels=None):
+ """
+ Uses the internal non-interactive union merge algorithm for merging
+ files. It will use both sides if there are any conflicts."""
+
+ return __imerge(repo, mynode, orig, fcd, fco, fca, toolconf,
+ files, labels, 'union')
+
+
+
@internaltool('merge3', True,
_("merging %s incomplete! "
"(edit conflicts, then use 'hg resolve --mark')\n"))
diff -r ff5172c83002 -r d35c0f4e71ed mercurial/simplemerge.py
--- a/mercurial/simplemerge.py Wed Jun 24 13:41:27 2015 -0500
+++ b/mercurial/simplemerge.py Fri Jun 26 21:14:49 2015 +0200
@@ -92,9 +92,9 @@
newline = '\r\n'
elif self.a[0].endswith('\r'):
newline = '\r'
- if name_a:
+ if name_a and start_marker:
start_marker = start_marker + ' ' + name_a
- if name_b:
+ if name_b and end_marker:
end_marker = end_marker + ' ' + name_b
if name_base and base_marker:
base_marker = base_marker + ' ' + name_base
@@ -112,17 +112,20 @@
yield self.b[i]
elif what == 'conflict':
self.conflicts = True
- yield start_marker + newline
+ if start_marker is not None:
+ yield start_marker + newline
for i in range(t[3], t[4]):
yield self.a[i]
if base_marker is not None:
yield base_marker + newline
for i in range(t[1], t[2]):
yield self.base[i]
- yield mid_marker + newline
+ if mid_marker is not None:
+ yield mid_marker + newline
for i in range(t[5], t[6]):
yield self.b[i]
- yield end_marker + newline
+ if end_marker is not None:
+ yield end_marker + newline
else:
raise ValueError(what)
@@ -345,18 +348,24 @@
raise util.Abort(msg)
return text
- name_a = local
- name_b = other
- name_base = None
- labels = opts.get('label', [])
- if len(labels) > 0:
- name_a = labels[0]
- if len(labels) > 1:
- name_b = labels[1]
- if len(labels) > 2:
- name_base = labels[2]
- if len(labels) > 3:
- raise util.Abort(_("can only specify three labels."))
+ mode = opts.get('mode', '')
+ if mode == 'union':
+ name_a = None
+ name_b = None
+ name_base = None
+ else:
+ name_a = local
+ name_b = other
+ name_base = None
+ labels = opts.get('label', [])
+ if len(labels) > 0:
+ name_a = labels[0]
+ if len(labels) > 1:
+ name_b = labels[1]
+ if len(labels) > 2:
+ name_base = labels[2]
+ if len(labels) > 3:
+ raise util.Abort(_("can only specify three labels."))
try:
localtext = readfile(local)
@@ -374,7 +383,11 @@
m3 = Merge3Text(basetext, localtext, othertext)
extrakwargs = {}
- if name_base is not None:
+ if mode == 'union':
+ extrakwargs['start_marker'] = None
+ extrakwargs['end_marker'] = None
+ extrakwargs['mid_marker'] = None
+ elif name_base is not None:
extrakwargs['base_marker'] = '|||||||'
extrakwargs['name_base'] = name_base
for line in m3.merge_lines(name_a=name_a, name_b=name_b,
**extrakwargs):
@@ -383,7 +396,7 @@
if not opts.get('print'):
out.close()
- if m3.conflicts:
+ if m3.conflicts and not mode == 'union':
if not opts.get('quiet'):
ui.warn(_("warning: conflicts during merge.\n"))
return 1
--
Bye,
Erik.
http://efficito.com -- Hosted accounting and ERP.
Robust and Flexible. No vendor lock-in.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://selenic.com/pipermail/mercurial-devel/attachments/20150626/d6a81e9d/attachment.html>
More information about the Mercurial-devel
mailing list