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: