511 unused, unused, unused, back = files |
511 unused, unused, unused, back = files |
512 a = _workingpath(repo, fcd) |
512 a = _workingpath(repo, fcd) |
513 b, c = _maketempfiles(repo, fco, fca) |
513 b, c = _maketempfiles(repo, fco, fca) |
514 try: |
514 try: |
515 out = "" |
515 out = "" |
|
516 mylabel, otherlabel = labels[:2] |
|
517 if len(labels) >= 3: |
|
518 baselabel = labels[2] |
|
519 else: |
|
520 baselabel = 'base' |
516 env = {'HG_FILE': fcd.path(), |
521 env = {'HG_FILE': fcd.path(), |
517 'HG_MY_NODE': short(mynode), |
522 'HG_MY_NODE': short(mynode), |
518 'HG_OTHER_NODE': str(fco.changectx()), |
523 'HG_OTHER_NODE': str(fco.changectx()), |
519 'HG_BASE_NODE': str(fca.changectx()), |
524 'HG_BASE_NODE': str(fca.changectx()), |
520 'HG_MY_ISLINK': 'l' in fcd.flags(), |
525 'HG_MY_ISLINK': 'l' in fcd.flags(), |
521 'HG_OTHER_ISLINK': 'l' in fco.flags(), |
526 'HG_OTHER_ISLINK': 'l' in fco.flags(), |
522 'HG_BASE_ISLINK': 'l' in fca.flags(), |
527 'HG_BASE_ISLINK': 'l' in fca.flags(), |
|
528 'HG_MY_LABEL': mylabel, |
|
529 'HG_OTHER_LABEL': otherlabel, |
|
530 'HG_BASE_LABEL': baselabel, |
523 } |
531 } |
524 ui = repo.ui |
532 ui = repo.ui |
525 |
533 |
526 args = _toolstr(ui, tool, "args") |
534 args = _toolstr(ui, tool, "args") |
527 if "$output" in args: |
535 if "$output" in args: |
528 # read input from backup, write to original |
536 # read input from backup, write to original |
529 out = a |
537 out = a |
530 a = repo.wvfs.join(back.path()) |
538 a = repo.wvfs.join(back.path()) |
531 replace = {'local': a, 'base': b, 'other': c, 'output': out} |
539 replace = {'local': a, 'base': b, 'other': c, 'output': out, |
|
540 'labellocal': mylabel, 'labelother': otherlabel, |
|
541 'labelbase': baselabel} |
532 args = util.interpolate(br'\$', replace, args, |
542 args = util.interpolate(br'\$', replace, args, |
533 lambda s: util.shellquote(util.localpath(s))) |
543 lambda s: util.shellquote(util.localpath(s))) |
534 cmd = toolpath + ' ' + args |
544 cmd = toolpath + ' ' + args |
535 if _toolbool(ui, tool, "gui"): |
545 if _toolbool(ui, tool, "gui"): |
536 repo.ui.status(_('running merge tool %s for file %s\n') % |
546 repo.ui.status(_('running merge tool %s for file %s\n') % |
564 # 8 for the prefix of conflict marker lines (e.g. '<<<<<<< ') |
574 # 8 for the prefix of conflict marker lines (e.g. '<<<<<<< ') |
565 return util.ellipsis(mark, 80 - 8) |
575 return util.ellipsis(mark, 80 - 8) |
566 |
576 |
567 _defaultconflictlabels = ['local', 'other'] |
577 _defaultconflictlabels = ['local', 'other'] |
568 |
578 |
569 def _formatlabels(repo, fcd, fco, fca, labels): |
579 def _formatlabels(repo, fcd, fco, fca, labels, tool=None): |
570 """Formats the given labels using the conflict marker template. |
580 """Formats the given labels using the conflict marker template. |
571 |
581 |
572 Returns a list of formatted labels. |
582 Returns a list of formatted labels. |
573 """ |
583 """ |
574 cd = fcd.changectx() |
584 cd = fcd.changectx() |
575 co = fco.changectx() |
585 co = fco.changectx() |
576 ca = fca.changectx() |
586 ca = fca.changectx() |
577 |
587 |
578 ui = repo.ui |
588 ui = repo.ui |
579 template = ui.config('ui', 'mergemarkertemplate') |
589 template = ui.config('ui', 'mergemarkertemplate') |
|
590 if tool is not None: |
|
591 template = _toolstr(ui, tool, 'mergemarkertemplate', template) |
580 template = templater.unquotestring(template) |
592 template = templater.unquotestring(template) |
581 tres = formatter.templateresources(ui, repo) |
593 tres = formatter.templateresources(ui, repo) |
582 tmpl = formatter.maketemplater(ui, template, defaults=templatekw.keywords, |
594 tmpl = formatter.maketemplater(ui, template, defaults=templatekw.keywords, |
583 resources=tres) |
595 resources=tres) |
584 |
596 |
704 if tool in internals: |
716 if tool in internals: |
705 func = internals[tool] |
717 func = internals[tool] |
706 mergetype = func.mergetype |
718 mergetype = func.mergetype |
707 onfailure = func.onfailure |
719 onfailure = func.onfailure |
708 precheck = func.precheck |
720 precheck = func.precheck |
|
721 isexternal = False |
709 else: |
722 else: |
710 if wctx.isinmemory(): |
723 if wctx.isinmemory(): |
711 func = _xmergeimm |
724 func = _xmergeimm |
712 else: |
725 else: |
713 func = _xmerge |
726 func = _xmerge |
714 mergetype = fullmerge |
727 mergetype = fullmerge |
715 onfailure = _("merging %s failed!\n") |
728 onfailure = _("merging %s failed!\n") |
716 precheck = None |
729 precheck = None |
|
730 isexternal = True |
717 |
731 |
718 toolconf = tool, toolpath, binary, symlink |
732 toolconf = tool, toolpath, binary, symlink |
719 |
733 |
720 if mergetype == nomerge: |
734 if mergetype == nomerge: |
721 r, deleted = func(repo, mynode, orig, fcd, fco, fca, toolconf, labels) |
735 r, deleted = func(repo, mynode, orig, fcd, fco, fca, toolconf, labels) |
741 |
755 |
742 back = _makebackup(repo, ui, wctx, fcd, premerge) |
756 back = _makebackup(repo, ui, wctx, fcd, premerge) |
743 files = (None, None, None, back) |
757 files = (None, None, None, back) |
744 r = 1 |
758 r = 1 |
745 try: |
759 try: |
746 markerstyle = ui.config('ui', 'mergemarkers') |
760 internalmarkerstyle = ui.config('ui', 'mergemarkers') |
|
761 if isexternal: |
|
762 markerstyle = _toolstr(ui, tool, 'mergemarkers') |
|
763 else: |
|
764 markerstyle = internalmarkerstyle |
|
765 |
747 if not labels: |
766 if not labels: |
748 labels = _defaultconflictlabels |
767 labels = _defaultconflictlabels |
|
768 formattedlabels = labels |
749 if markerstyle != 'basic': |
769 if markerstyle != 'basic': |
750 labels = _formatlabels(repo, fcd, fco, fca, labels) |
770 formattedlabels = _formatlabels(repo, fcd, fco, fca, labels, |
|
771 tool=tool) |
751 |
772 |
752 if premerge and mergetype == fullmerge: |
773 if premerge and mergetype == fullmerge: |
753 r = _premerge(repo, fcd, fco, fca, toolconf, files, labels=labels) |
774 # conflict markers generated by premerge will use 'detailed' |
|
775 # settings if either ui.mergemarkers or the tool's mergemarkers |
|
776 # setting is 'detailed'. This way tools can have basic labels in |
|
777 # space-constrained areas of the UI, but still get full information |
|
778 # in conflict markers if premerge is 'keep' or 'keep-merge3'. |
|
779 premergelabels = labels |
|
780 labeltool = None |
|
781 if markerstyle != 'basic': |
|
782 # respect 'tool's mergemarkertemplate (which defaults to |
|
783 # ui.mergemarkertemplate) |
|
784 labeltool = tool |
|
785 if internalmarkerstyle != 'basic' or markerstyle != 'basic': |
|
786 premergelabels = _formatlabels(repo, fcd, fco, fca, |
|
787 premergelabels, tool=labeltool) |
|
788 |
|
789 r = _premerge(repo, fcd, fco, fca, toolconf, files, |
|
790 labels=premergelabels) |
754 # complete if premerge successful (r is 0) |
791 # complete if premerge successful (r is 0) |
755 return not r, r, False |
792 return not r, r, False |
756 |
793 |
757 needcheck, r, deleted = func(repo, mynode, orig, fcd, fco, fca, |
794 needcheck, r, deleted = func(repo, mynode, orig, fcd, fco, fca, |
758 toolconf, files, labels=labels) |
795 toolconf, files, labels=formattedlabels) |
759 |
796 |
760 if needcheck: |
797 if needcheck: |
761 r = _check(repo, r, ui, tool, fcd, files) |
798 r = _check(repo, r, ui, tool, fcd, files) |
762 |
799 |
763 if r: |
800 if r: |