##// END OF EJS Templates
filemerge: support passing labels to external merge tools...
Kyle Lippincott -
r35981:9037c29e default
parent child Browse files
Show More
@@ -743,6 +743,16 b" coreconfigitem('merge-tools', br'.*\\.gui"
743 743 generic=True,
744 744 priority=-1,
745 745 )
746 coreconfigitem('merge-tools', br'.*\.mergemarkers$',
747 default='basic',
748 generic=True,
749 priority=-1,
750 )
751 coreconfigitem('merge-tools', br'.*\.mergemarkertemplate$',
752 default=dynamicdefault, # take from ui.mergemarkertemplate
753 generic=True,
754 priority=-1,
755 )
746 756 coreconfigitem('merge-tools', br'.*\.priority$',
747 757 default=0,
748 758 generic=True,
@@ -513,6 +513,11 b' def _xmerge(repo, mynode, orig, fcd, fco'
513 513 b, c = _maketempfiles(repo, fco, fca)
514 514 try:
515 515 out = ""
516 mylabel, otherlabel = labels[:2]
517 if len(labels) >= 3:
518 baselabel = labels[2]
519 else:
520 baselabel = 'base'
516 521 env = {'HG_FILE': fcd.path(),
517 522 'HG_MY_NODE': short(mynode),
518 523 'HG_OTHER_NODE': str(fco.changectx()),
@@ -520,6 +525,9 b' def _xmerge(repo, mynode, orig, fcd, fco'
520 525 'HG_MY_ISLINK': 'l' in fcd.flags(),
521 526 'HG_OTHER_ISLINK': 'l' in fco.flags(),
522 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 532 ui = repo.ui
525 533
@@ -528,7 +536,9 b' def _xmerge(repo, mynode, orig, fcd, fco'
528 536 # read input from backup, write to original
529 537 out = a
530 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 542 args = util.interpolate(br'\$', replace, args,
533 543 lambda s: util.shellquote(util.localpath(s)))
534 544 cmd = toolpath + ' ' + args
@@ -566,7 +576,7 b' def _formatconflictmarker(ctx, template,'
566 576
567 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 580 """Formats the given labels using the conflict marker template.
571 581
572 582 Returns a list of formatted labels.
@@ -577,6 +587,8 b' def _formatlabels(repo, fcd, fco, fca, l'
577 587
578 588 ui = repo.ui
579 589 template = ui.config('ui', 'mergemarkertemplate')
590 if tool is not None:
591 template = _toolstr(ui, tool, 'mergemarkertemplate', template)
580 592 template = templater.unquotestring(template)
581 593 tres = formatter.templateresources(ui, repo)
582 594 tmpl = formatter.maketemplater(ui, template, defaults=templatekw.keywords,
@@ -706,6 +718,7 b' def _filemerge(premerge, repo, wctx, myn'
706 718 mergetype = func.mergetype
707 719 onfailure = func.onfailure
708 720 precheck = func.precheck
721 isexternal = False
709 722 else:
710 723 if wctx.isinmemory():
711 724 func = _xmergeimm
@@ -714,6 +727,7 b' def _filemerge(premerge, repo, wctx, myn'
714 727 mergetype = fullmerge
715 728 onfailure = _("merging %s failed!\n")
716 729 precheck = None
730 isexternal = True
717 731
718 732 toolconf = tool, toolpath, binary, symlink
719 733
@@ -743,19 +757,42 b' def _filemerge(premerge, repo, wctx, myn'
743 757 files = (None, None, None, back)
744 758 r = 1
745 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 766 if not labels:
748 767 labels = _defaultconflictlabels
768 formattedlabels = labels
749 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 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 791 # complete if premerge successful (r is 0)
755 792 return not r, r, False
756 793
757 794 needcheck, r, deleted = func(repo, mynode, orig, fcd, fco, fca,
758 toolconf, files, labels=labels)
795 toolconf, files, labels=formattedlabels)
759 796
760 797 if needcheck:
761 798 r = _check(repo, r, ui, tool, fcd, files)
@@ -1363,13 +1363,18 b' Supported arguments:'
1363 1363 ``args``
1364 1364 The arguments to pass to the tool executable. You can refer to the
1365 1365 files being merged as well as the output file through these
1366 variables: ``$base``, ``$local``, ``$other``, ``$output``. The meaning
1367 of ``$local`` and ``$other`` can vary depending on which action is being
1368 performed. During and update or merge, ``$local`` represents the original
1369 state of the file, while ``$other`` represents the commit you are updating
1370 to or the commit you are merging with. During a rebase ``$local``
1371 represents the destination of the rebase, and ``$other`` represents the
1372 commit being rebased.
1366 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1367
1368 The meaning of ``$local`` and ``$other`` can vary depending on which action is
1369 being performed. During an update or merge, ``$local`` represents the original
1370 state of the file, while ``$other`` represents the commit you are updating to or
1371 the commit you are merging with. During a rebase, ``$local`` represents the
1372 destination of the rebase, and ``$other`` represents the commit being rebased.
1373
1374 Some operations define custom labels to assist with identifying the revisions,
1375 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1376 labels are not available, these will be ``local``, ``other``, and ``base``,
1377 respectively.
1373 1378 (default: ``$local $base $other``)
1374 1379
1375 1380 ``premerge``
@@ -1405,6 +1410,21 b' Supported arguments:'
1405 1410 ``gui``
1406 1411 This tool requires a graphical interface to run. (default: False)
1407 1412
1413 ``mergemarkers``
1414 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1415 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1416 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1417 markers generated during premerge will be ``detailed`` if either this option or
1418 the corresponding option in the ``[ui]`` section is ``detailed``.
1419 (default: ``basic``)
1420
1421 ``mergemarkertemplate``
1422 This setting can be used to override ``mergemarkertemplate`` from the ``[ui]``
1423 section on a per-tool basis; this applies to the ``$label``-prefixed variables
1424 and to the conflict markers that are generated if ``premerge`` is ``keep` or
1425 ``keep-merge3``. See the corresponding variable in ``[ui]`` for more
1426 information.
1427
1408 1428 .. container:: windows
1409 1429
1410 1430 ``regkey``
@@ -2120,6 +2140,8 b' User interface controls.'
2120 2140 markers is different from the encoding of the merged files,
2121 2141 serious problems may occur.
2122 2142
2143 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2144
2123 2145 ``origbackuppath``
2124 2146 The path to a directory used to store generated .orig files. If the path is
2125 2147 not a directory, one will be created. If set, files stored in this
@@ -1059,6 +1059,150 b' premerge=keep-merge3 keeps conflict mark'
1059 1059 # hg resolve --list
1060 1060 R f
1061 1061
1062 premerge=keep respects ui.mergemarkers=basic:
1063
1064 $ beforemerge
1065 [merge-tools]
1066 false.whatever=
1067 true.priority=1
1068 true.executable=cat
1069 # hg update -C 1
1070 $ hg merge -r 4 --config merge-tools.true.premerge=keep --config ui.mergemarkers=basic
1071 merging f
1072 <<<<<<< working copy
1073 revision 1
1074 space
1075 =======
1076 revision 4
1077 >>>>>>> merge rev
1078 revision 0
1079 space
1080 revision 4
1081 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1082 (branch merge, don't forget to commit)
1083 $ aftermerge
1084 # cat f
1085 <<<<<<< working copy
1086 revision 1
1087 space
1088 =======
1089 revision 4
1090 >>>>>>> merge rev
1091 # hg stat
1092 M f
1093 # hg resolve --list
1094 R f
1095
1096 premerge=keep ignores ui.mergemarkers=basic if true.mergemarkers=detailed:
1097
1098 $ beforemerge
1099 [merge-tools]
1100 false.whatever=
1101 true.priority=1
1102 true.executable=cat
1103 # hg update -C 1
1104 $ hg merge -r 4 --config merge-tools.true.premerge=keep \
1105 > --config ui.mergemarkers=basic \
1106 > --config merge-tools.true.mergemarkers=detailed
1107 merging f
1108 <<<<<<< working copy: ef83787e2614 - test: revision 1
1109 revision 1
1110 space
1111 =======
1112 revision 4
1113 >>>>>>> merge rev: 81448d39c9a0 - test: revision 4
1114 revision 0
1115 space
1116 revision 4
1117 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1118 (branch merge, don't forget to commit)
1119 $ aftermerge
1120 # cat f
1121 <<<<<<< working copy: ef83787e2614 - test: revision 1
1122 revision 1
1123 space
1124 =======
1125 revision 4
1126 >>>>>>> merge rev: 81448d39c9a0 - test: revision 4
1127 # hg stat
1128 M f
1129 # hg resolve --list
1130 R f
1131
1132 premerge=keep respects ui.mergemarkertemplate instead of
1133 true.mergemarkertemplate if true.mergemarkers=basic:
1134
1135 $ beforemerge
1136 [merge-tools]
1137 false.whatever=
1138 true.priority=1
1139 true.executable=cat
1140 # hg update -C 1
1141 $ hg merge -r 4 --config merge-tools.true.premerge=keep \
1142 > --config ui.mergemarkertemplate='uitmpl {rev}' \
1143 > --config merge-tools.true.mergemarkertemplate='tooltmpl {short(node)}'
1144 merging f
1145 <<<<<<< working copy: uitmpl 1
1146 revision 1
1147 space
1148 =======
1149 revision 4
1150 >>>>>>> merge rev: uitmpl 4
1151 revision 0
1152 space
1153 revision 4
1154 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1155 (branch merge, don't forget to commit)
1156 $ aftermerge
1157 # cat f
1158 <<<<<<< working copy: uitmpl 1
1159 revision 1
1160 space
1161 =======
1162 revision 4
1163 >>>>>>> merge rev: uitmpl 4
1164 # hg stat
1165 M f
1166 # hg resolve --list
1167 R f
1168
1169 premerge=keep respects true.mergemarkertemplate instead of
1170 true.mergemarkertemplate if true.mergemarkers=detailed:
1171
1172 $ beforemerge
1173 [merge-tools]
1174 false.whatever=
1175 true.priority=1
1176 true.executable=cat
1177 # hg update -C 1
1178 $ hg merge -r 4 --config merge-tools.true.premerge=keep \
1179 > --config ui.mergemarkertemplate='uitmpl {rev}' \
1180 > --config merge-tools.true.mergemarkertemplate='tooltmpl {short(node)}' \
1181 > --config merge-tools.true.mergemarkers=detailed
1182 merging f
1183 <<<<<<< working copy: tooltmpl ef83787e2614
1184 revision 1
1185 space
1186 =======
1187 revision 4
1188 >>>>>>> merge rev: tooltmpl 81448d39c9a0
1189 revision 0
1190 space
1191 revision 4
1192 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1193 (branch merge, don't forget to commit)
1194 $ aftermerge
1195 # cat f
1196 <<<<<<< working copy: tooltmpl ef83787e2614
1197 revision 1
1198 space
1199 =======
1200 revision 4
1201 >>>>>>> merge rev: tooltmpl 81448d39c9a0
1202 # hg stat
1203 M f
1204 # hg resolve --list
1205 R f
1062 1206
1063 1207 Tool execution
1064 1208
@@ -1190,6 +1334,142 b' Merge using tool with a path that must b'
1190 1334 # hg resolve --list
1191 1335 R f
1192 1336
1337 Merge using a tool that supports labellocal, labelother, and labelbase, checking
1338 that they're quoted properly as well. This is using the default 'basic'
1339 mergemarkers even though ui.mergemarkers is 'detailed', so it's ignoring both
1340 mergemarkertemplate settings:
1341
1342 $ beforemerge
1343 [merge-tools]
1344 false.whatever=
1345 true.priority=1
1346 true.executable=cat
1347 # hg update -C 1
1348 $ cat <<EOF > printargs_merge_tool
1349 > while test \$# -gt 0; do echo arg: \"\$1\"; shift; done
1350 > EOF
1351 $ hg --config merge-tools.true.executable='sh' \
1352 > --config merge-tools.true.args='./printargs_merge_tool ll:$labellocal lo: $labelother lb:$labelbase": "$base' \
1353 > --config merge-tools.true.mergemarkertemplate='tooltmpl {short(node)}' \
1354 > --config ui.mergemarkertemplate='uitmpl {rev}' \
1355 > --config ui.mergemarkers=detailed \
1356 > merge -r 2
1357 merging f
1358 arg: "ll:working copy"
1359 arg: "lo:"
1360 arg: "merge rev"
1361 arg: "lb:base: /tmp/f~base.*" (glob)
1362 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1363 (branch merge, don't forget to commit)
1364 $ rm -f 'printargs_merge_tool'
1365
1366 Merge using a tool that supports labellocal, labelother, and labelbase, checking
1367 that they're quoted properly as well. This is using 'detailed' mergemarkers,
1368 even though ui.mergemarkers is 'basic', and using the tool's
1369 mergemarkertemplate:
1370
1371 $ beforemerge
1372 [merge-tools]
1373 false.whatever=
1374 true.priority=1
1375 true.executable=cat
1376 # hg update -C 1
1377 $ cat <<EOF > printargs_merge_tool
1378 > while test \$# -gt 0; do echo arg: \"\$1\"; shift; done
1379 > EOF
1380 $ hg --config merge-tools.true.executable='sh' \
1381 > --config merge-tools.true.args='./printargs_merge_tool ll:$labellocal lo: $labelother lb:$labelbase": "$base' \
1382 > --config merge-tools.true.mergemarkers=detailed \
1383 > --config merge-tools.true.mergemarkertemplate='tooltmpl {short(node)}' \
1384 > --config ui.mergemarkertemplate='uitmpl {rev}' \
1385 > --config ui.mergemarkers=basic \
1386 > merge -r 2
1387 merging f
1388 arg: "ll:working copy: tooltmpl ef83787e2614"
1389 arg: "lo:"
1390 arg: "merge rev: tooltmpl 0185f4e0cf02"
1391 arg: "lb:base: /tmp/f~base.*" (glob)
1392 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1393 (branch merge, don't forget to commit)
1394 $ rm -f 'printargs_merge_tool'
1395
1396 The merge tool still gets labellocal and labelother as 'basic' even when
1397 premerge=keep is used and has 'detailed' markers:
1398
1399 $ beforemerge
1400 [merge-tools]
1401 false.whatever=
1402 true.priority=1
1403 true.executable=cat
1404 # hg update -C 1
1405 $ cat <<EOF > mytool
1406 > echo labellocal: \"\$1\"
1407 > echo labelother: \"\$2\"
1408 > echo "output (arg)": \"\$3\"
1409 > echo "output (contents)":
1410 > cat "\$3"
1411 > EOF
1412 $ hg --config merge-tools.true.executable='sh' \
1413 > --config merge-tools.true.args='mytool $labellocal $labelother $output' \
1414 > --config merge-tools.true.premerge=keep \
1415 > --config merge-tools.true.mergemarkertemplate='tooltmpl {short(node)}' \
1416 > --config ui.mergemarkertemplate='uitmpl {rev}' \
1417 > --config ui.mergemarkers=detailed \
1418 > merge -r 2
1419 merging f
1420 labellocal: "working copy"
1421 labelother: "merge rev"
1422 output (arg): "$TESTTMP/f"
1423 output (contents):
1424 <<<<<<< working copy: uitmpl 1
1425 revision 1
1426 =======
1427 revision 2
1428 >>>>>>> merge rev: uitmpl 2
1429 space
1430 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1431 (branch merge, don't forget to commit)
1432 $ rm -f 'mytool'
1433
1434 premerge=keep uses the *tool's* mergemarkertemplate if tool's
1435 mergemarkers=detailed; labellocal and labelother also use the tool's template
1436
1437 $ beforemerge
1438 [merge-tools]
1439 false.whatever=
1440 true.priority=1
1441 true.executable=cat
1442 # hg update -C 1
1443 $ cat <<EOF > mytool
1444 > echo labellocal: \"\$1\"
1445 > echo labelother: \"\$2\"
1446 > echo "output (arg)": \"\$3\"
1447 > echo "output (contents)":
1448 > cat "\$3"
1449 > EOF
1450 $ hg --config merge-tools.true.executable='sh' \
1451 > --config merge-tools.true.args='mytool $labellocal $labelother $output' \
1452 > --config merge-tools.true.premerge=keep \
1453 > --config merge-tools.true.mergemarkers=detailed \
1454 > --config merge-tools.true.mergemarkertemplate='tooltmpl {short(node)}' \
1455 > --config ui.mergemarkertemplate='uitmpl {rev}' \
1456 > --config ui.mergemarkers=detailed \
1457 > merge -r 2
1458 merging f
1459 labellocal: "working copy: tooltmpl ef83787e2614"
1460 labelother: "merge rev: tooltmpl 0185f4e0cf02"
1461 output (arg): "$TESTTMP/f"
1462 output (contents):
1463 <<<<<<< working copy: tooltmpl ef83787e2614
1464 revision 1
1465 =======
1466 revision 2
1467 >>>>>>> merge rev: tooltmpl 0185f4e0cf02
1468 space
1469 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1470 (branch merge, don't forget to commit)
1471 $ rm -f 'mytool'
1472
1193 1473 Issue3581: Merging a filename that needs to be quoted
1194 1474 (This test doesn't work on Windows filesystems even on Linux, so check
1195 1475 for Unix-like permission)
General Comments 0
You need to be logged in to leave comments. Login now