Mercurial > hg-stable
comparison mercurial/filemerge.py @ 21519:25d5a9ecbb85
merge: add conflict marker formatter (BC)
Adds a conflict marker formatter that can produce custom conflict marker
descriptions. It can be set via ui.mergemarkertemplate. The old behavior
can be used still by setting ui.mergemarkers=basic.
The default format is similar to:
{node|short} {tag} {branch} {bookmarks} - {author}: "{desc|firstline}"
And renders as:
contextblahblah
<<<<<<< local: c7fdd7ce4652 - durham: "Fix broken stuff in my feature branch"
line from my changes
=======
line from the other changes
>>>>>>> other: a3e55d7f4d38 master - sid0: "This is a commit to master th...
morecontextblahblah
author | Durham Goode <durham@fb.com> |
---|---|
date | Thu, 08 May 2014 16:50:22 -0700 |
parents | 20b8090d8125 |
children | 47b97d9af27e |
comparison
equal
deleted
inserted
replaced
21518:8e8049b9bda4 | 21519:25d5a9ecbb85 |
---|---|
5 # This software may be used and distributed according to the terms of the | 5 # This software may be used and distributed according to the terms of the |
6 # GNU General Public License version 2 or any later version. | 6 # GNU General Public License version 2 or any later version. |
7 | 7 |
8 from node import short | 8 from node import short |
9 from i18n import _ | 9 from i18n import _ |
10 import util, simplemerge, match, error | 10 import util, simplemerge, match, error, templater, templatekw |
11 import os, tempfile, re, filecmp | 11 import os, tempfile, re, filecmp |
12 | 12 |
13 def _toolstr(ui, tool, part, default=""): | 13 def _toolstr(ui, tool, part, default=""): |
14 return ui.config("merge-tools", tool + "." + part, default) | 14 return ui.config("merge-tools", tool + "." + part, default) |
15 | 15 |
267 r = util.system(toolpath + ' ' + args, cwd=repo.root, environ=env, | 267 r = util.system(toolpath + ' ' + args, cwd=repo.root, environ=env, |
268 out=ui.fout) | 268 out=ui.fout) |
269 return True, r | 269 return True, r |
270 return False, 0 | 270 return False, 0 |
271 | 271 |
272 def _formatconflictmarker(repo, ctx, template, label, pad): | |
273 """Applies the given template to the ctx, prefixed by the label. | |
274 | |
275 Pad is the minimum width of the label prefix, so that multiple markers | |
276 can have aligned templated parts. | |
277 """ | |
278 if ctx.node() is None: | |
279 ctx = ctx.p1() | |
280 | |
281 props = templatekw.keywords.copy() | |
282 props['templ'] = template | |
283 props['ctx'] = ctx | |
284 props['repo'] = repo | |
285 templateresult = template('conflictmarker', **props) | |
286 | |
287 label = ('%s:' % label).ljust(pad + 1) | |
288 mark = '%s %s' % (label, templater.stringify(templateresult)) | |
289 | |
290 # The <<< marks add 8 to the length, and '...' adds three, so max | |
291 # length of the actual marker is 69. | |
292 maxlength = 80 - 8 - 3 | |
293 if len(mark) > maxlength: | |
294 mark = mark[:maxlength] + '...' | |
295 return mark | |
296 | |
297 _defaultconflictmarker = ('{node|short} ' + | |
298 '{ifeq(tags, "tip", "", "{tags} ")}' + | |
299 '{if(bookmarks, "{bookmarks} ")}' + | |
300 '{ifeq(branch, "default", "", "{branch} ")}' + | |
301 '- {author|user}: "{desc|firstline}"') | |
302 | |
303 def _formatlabels(repo, fcd, fco, labels): | |
304 """Formats the given labels using the conflict marker template. | |
305 | |
306 Returns a list of formatted labels. | |
307 """ | |
308 cd = fcd.changectx() | |
309 co = fco.changectx() | |
310 | |
311 ui = repo.ui | |
312 template = ui.config('ui', 'mergemarkertemplate', _defaultconflictmarker) | |
313 template = templater.parsestring(template, quoted=False) | |
314 tmpl = templater.templater(None, cache={ 'conflictmarker' : template }) | |
315 | |
316 pad = max(len(labels[0]), len(labels[1])) | |
317 | |
318 return [_formatconflictmarker(repo, cd, tmpl, labels[0], pad), | |
319 _formatconflictmarker(repo, co, tmpl, labels[1], pad)] | |
320 | |
272 def filemerge(repo, mynode, orig, fcd, fco, fca): | 321 def filemerge(repo, mynode, orig, fcd, fco, fca): |
273 """perform a 3-way merge in the working directory | 322 """perform a 3-way merge in the working directory |
274 | 323 |
275 mynode = parent node before merge | 324 mynode = parent node before merge |
276 orig = original local filename before merge | 325 orig = original local filename before merge |
324 else: | 373 else: |
325 ui.status(_("merging %s\n") % fd) | 374 ui.status(_("merging %s\n") % fd) |
326 | 375 |
327 ui.debug("my %s other %s ancestor %s\n" % (fcd, fco, fca)) | 376 ui.debug("my %s other %s ancestor %s\n" % (fcd, fco, fca)) |
328 | 377 |
378 markerstyle = ui.config('ui', 'mergemarkers', 'detailed') | |
329 labels = ['local', 'other'] | 379 labels = ['local', 'other'] |
380 if markerstyle == 'basic': | |
381 formattedlabels = labels | |
382 else: | |
383 formattedlabels = _formatlabels(repo, fcd, fco, labels) | |
384 | |
330 needcheck, r = func(repo, mynode, orig, fcd, fco, fca, toolconf, | 385 needcheck, r = func(repo, mynode, orig, fcd, fco, fca, toolconf, |
331 (a, b, c, back), labels=labels) | 386 (a, b, c, back), labels=formattedlabels) |
332 if not needcheck: | 387 if not needcheck: |
333 if r: | 388 if r: |
334 if onfailure: | 389 if onfailure: |
335 ui.warn(onfailure % fd) | 390 ui.warn(onfailure % fd) |
336 else: | 391 else: |