397 return filectx.changectx()[filectx.path()] |
397 return filectx.changectx()[filectx.path()] |
398 else: |
398 else: |
399 return filectx |
399 return filectx |
400 |
400 |
401 |
401 |
402 def _premerge(repo, fcd, fco, fca, toolconf, files, labels=None): |
402 def _premerge(repo, fcd, fco, fca, toolconf, backup, labels=None): |
403 tool, toolpath, binary, symlink, scriptfn = toolconf |
403 tool, toolpath, binary, symlink, scriptfn = toolconf |
404 if symlink or fcd.isabsent() or fco.isabsent(): |
404 if symlink or fcd.isabsent() or fco.isabsent(): |
405 return 1 |
405 return 1 |
406 unused, unused, unused, backup = files |
|
407 |
406 |
408 ui = repo.ui |
407 ui = repo.ui |
409 |
408 |
410 validkeep = [b'keep', b'keep-merge3', b'keep-mergediff'] |
409 validkeep = [b'keep', b'keep-merge3', b'keep-mergediff'] |
411 |
410 |
461 ) |
460 ) |
462 return False |
461 return False |
463 return True |
462 return True |
464 |
463 |
465 |
464 |
466 def _merge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels, mode): |
465 def _merge(repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels, mode): |
467 """ |
466 """ |
468 Uses the internal non-interactive simple merge algorithm for merging |
467 Uses the internal non-interactive simple merge algorithm for merging |
469 files. It will fail if there are any conflicts and leave markers in |
468 files. It will fail if there are any conflicts and leave markers in |
470 the partially merged file. Markers will have two sections, one for each side |
469 the partially merged file. Markers will have two sections, one for each side |
471 of merge, unless mode equals 'union' which suppresses the markers.""" |
470 of merge, unless mode equals 'union' which suppresses the markers.""" |
482 b"warning: conflicts while merging %s! " |
481 b"warning: conflicts while merging %s! " |
483 b"(edit, then use 'hg resolve --mark')\n" |
482 b"(edit, then use 'hg resolve --mark')\n" |
484 ), |
483 ), |
485 precheck=_mergecheck, |
484 precheck=_mergecheck, |
486 ) |
485 ) |
487 def _iunion(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): |
486 def _iunion(repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels=None): |
488 """ |
487 """ |
489 Uses the internal non-interactive simple merge algorithm for merging |
488 Uses the internal non-interactive simple merge algorithm for merging |
490 files. It will use both left and right sides for conflict regions. |
489 files. It will use both left and right sides for conflict regions. |
491 No markers are inserted.""" |
490 No markers are inserted.""" |
492 return _merge( |
491 return _merge( |
493 repo, mynode, orig, fcd, fco, fca, toolconf, files, labels, b'union' |
492 repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels, b'union' |
494 ) |
493 ) |
495 |
494 |
496 |
495 |
497 @internaltool( |
496 @internaltool( |
498 b'merge', |
497 b'merge', |
501 b"warning: conflicts while merging %s! " |
500 b"warning: conflicts while merging %s! " |
502 b"(edit, then use 'hg resolve --mark')\n" |
501 b"(edit, then use 'hg resolve --mark')\n" |
503 ), |
502 ), |
504 precheck=_mergecheck, |
503 precheck=_mergecheck, |
505 ) |
504 ) |
506 def _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): |
505 def _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels=None): |
507 """ |
506 """ |
508 Uses the internal non-interactive simple merge algorithm for merging |
507 Uses the internal non-interactive simple merge algorithm for merging |
509 files. It will fail if there are any conflicts and leave markers in |
508 files. It will fail if there are any conflicts and leave markers in |
510 the partially merged file. Markers will have two sections, one for each side |
509 the partially merged file. Markers will have two sections, one for each side |
511 of merge.""" |
510 of merge.""" |
512 return _merge( |
511 return _merge( |
513 repo, mynode, orig, fcd, fco, fca, toolconf, files, labels, b'merge' |
512 repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels, b'merge' |
514 ) |
513 ) |
515 |
514 |
516 |
515 |
517 @internaltool( |
516 @internaltool( |
518 b'merge3', |
517 b'merge3', |
521 b"warning: conflicts while merging %s! " |
520 b"warning: conflicts while merging %s! " |
522 b"(edit, then use 'hg resolve --mark')\n" |
521 b"(edit, then use 'hg resolve --mark')\n" |
523 ), |
522 ), |
524 precheck=_mergecheck, |
523 precheck=_mergecheck, |
525 ) |
524 ) |
526 def _imerge3(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): |
525 def _imerge3(repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels=None): |
527 """ |
526 """ |
528 Uses the internal non-interactive simple merge algorithm for merging |
527 Uses the internal non-interactive simple merge algorithm for merging |
529 files. It will fail if there are any conflicts and leave markers in |
528 files. It will fail if there are any conflicts and leave markers in |
530 the partially merged file. Marker will have three sections, one from each |
529 the partially merged file. Marker will have three sections, one from each |
531 side of the merge and one for the base content.""" |
530 side of the merge and one for the base content.""" |
532 if not labels: |
531 if not labels: |
533 labels = _defaultconflictlabels |
532 labels = _defaultconflictlabels |
534 if len(labels) < 3: |
533 if len(labels) < 3: |
535 labels.append(b'base') |
534 labels.append(b'base') |
536 return _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels) |
535 return _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels) |
537 |
536 |
538 |
537 |
539 @internaltool( |
538 @internaltool( |
540 b'merge3-lie-about-conflicts', |
539 b'merge3-lie-about-conflicts', |
541 fullmerge, |
540 fullmerge, |
563 b"(edit, then use 'hg resolve --mark')\n" |
562 b"(edit, then use 'hg resolve --mark')\n" |
564 ), |
563 ), |
565 precheck=_mergecheck, |
564 precheck=_mergecheck, |
566 ) |
565 ) |
567 def _imerge_diff( |
566 def _imerge_diff( |
568 repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None |
567 repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels=None |
569 ): |
568 ): |
570 """ |
569 """ |
571 Uses the internal non-interactive simple merge algorithm for merging |
570 Uses the internal non-interactive simple merge algorithm for merging |
572 files. It will fail if there are any conflicts and leave markers in |
571 files. It will fail if there are any conflicts and leave markers in |
573 the partially merged file. The marker will have two sections, one with the |
572 the partially merged file. The marker will have two sections, one with the |
629 b"automatic tag merging of %s failed! " |
637 b"automatic tag merging of %s failed! " |
630 b"(use 'hg resolve --tool :merge' or another merge " |
638 b"(use 'hg resolve --tool :merge' or another merge " |
631 b"tool of your choice)\n" |
639 b"tool of your choice)\n" |
632 ), |
640 ), |
633 ) |
641 ) |
634 def _itagmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): |
642 def _itagmerge( |
|
643 repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels=None |
|
644 ): |
635 """ |
645 """ |
636 Uses the internal tag merge algorithm (experimental). |
646 Uses the internal tag merge algorithm (experimental). |
637 """ |
647 """ |
638 success, status = tagmerge.merge(repo, fcd, fco, fca) |
648 success, status = tagmerge.merge(repo, fcd, fco, fca) |
639 return success, status, False |
649 return success, status, False |
640 |
650 |
641 |
651 |
642 @internaltool(b'dump', fullmerge, binary=True, symlink=True) |
652 @internaltool(b'dump', fullmerge, binary=True, symlink=True) |
643 def _idump(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): |
653 def _idump(repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels=None): |
644 """ |
654 """ |
645 Creates three versions of the files to merge, containing the |
655 Creates three versions of the files to merge, containing the |
646 contents of local, other and base. These files can then be used to |
656 contents of local, other and base. These files can then be used to |
647 perform a merge manually. If the file to be merged is named |
657 perform a merge manually. If the file to be merged is named |
648 ``a.txt``, these files will accordingly be named ``a.txt.local``, |
658 ``a.txt``, these files will accordingly be named ``a.txt.local``, |
667 repo.wwrite(fd + b".base", fca.data(), fca.flags()) |
677 repo.wwrite(fd + b".base", fca.data(), fca.flags()) |
668 return False, 1, False |
678 return False, 1, False |
669 |
679 |
670 |
680 |
671 @internaltool(b'forcedump', mergeonly, binary=True, symlink=True) |
681 @internaltool(b'forcedump', mergeonly, binary=True, symlink=True) |
672 def _forcedump(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): |
682 def _forcedump( |
|
683 repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels=None |
|
684 ): |
673 """ |
685 """ |
674 Creates three versions of the files as same as :dump, but omits premerge. |
686 Creates three versions of the files as same as :dump, but omits premerge. |
675 """ |
687 """ |
676 return _idump( |
688 return _idump( |
677 repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=labels |
689 repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels=labels |
678 ) |
690 ) |
679 |
691 |
680 |
692 |
681 def _xmergeimm(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): |
693 def _xmergeimm( |
|
694 repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels=None |
|
695 ): |
682 # In-memory merge simply raises an exception on all external merge tools, |
696 # In-memory merge simply raises an exception on all external merge tools, |
683 # for now. |
697 # for now. |
684 # |
698 # |
685 # It would be possible to run most tools with temporary files, but this |
699 # It would be possible to run most tools with temporary files, but this |
686 # raises the question of what to do if the user only partially resolves the |
700 # raises the question of what to do if the user only partially resolves the |
744 ui, tmpl, defaults=templatekw.keywords, resources=tres |
758 ui, tmpl, defaults=templatekw.keywords, resources=tres |
745 ) |
759 ) |
746 ui.status(t.renderdefault(props)) |
760 ui.status(t.renderdefault(props)) |
747 |
761 |
748 |
762 |
749 def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels): |
763 def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, backup, labels): |
750 tool, toolpath, binary, symlink, scriptfn = toolconf |
764 tool, toolpath, binary, symlink, scriptfn = toolconf |
751 uipathfn = scmutil.getuipathfn(repo) |
765 uipathfn = scmutil.getuipathfn(repo) |
752 if fcd.isabsent() or fco.isabsent(): |
766 if fcd.isabsent() or fco.isabsent(): |
753 repo.ui.warn( |
767 repo.ui.warn( |
754 _(b'warning: %s cannot merge change/delete conflict for %s\n') |
768 _(b'warning: %s cannot merge change/delete conflict for %s\n') |
755 % (tool, uipathfn(fcd.path())) |
769 % (tool, uipathfn(fcd.path())) |
756 ) |
770 ) |
757 return False, 1, None |
771 return False, 1, None |
758 unused, unused, unused, backup = files |
|
759 localpath = _workingpath(repo, fcd) |
772 localpath = _workingpath(repo, fcd) |
760 args = _toolstr(repo.ui, tool, b"args") |
773 args = _toolstr(repo.ui, tool, b"args") |
761 |
774 |
762 with _maketempfiles( |
775 with _maketempfiles( |
763 repo, fco, fca, repo.wvfs.join(backup.path()), b"$output" in args |
776 repo, fco, fca, repo.wvfs.join(backup.path()), b"$output" in args |
1117 ) |
1130 ) |
1118 ui.warn(onfailure % fduipath) |
1131 ui.warn(onfailure % fduipath) |
1119 return True, 1, False |
1132 return True, 1, False |
1120 |
1133 |
1121 backup = _makebackup(repo, ui, wctx, fcd) |
1134 backup = _makebackup(repo, ui, wctx, fcd) |
1122 files = (None, None, None, backup) |
|
1123 r = 1 |
1135 r = 1 |
1124 try: |
1136 try: |
1125 internalmarkerstyle = ui.config(b'ui', b'mergemarkers') |
1137 internalmarkerstyle = ui.config(b'ui', b'mergemarkers') |
1126 if isexternal: |
1138 if isexternal: |
1127 markerstyle = _toolstr(ui, tool, b'mergemarkers') |
1139 markerstyle = _toolstr(ui, tool, b'mergemarkers') |
1152 premergelabels = _formatlabels( |
1164 premergelabels = _formatlabels( |
1153 repo, fcd, fco, fca, premergelabels, tool=labeltool |
1165 repo, fcd, fco, fca, premergelabels, tool=labeltool |
1154 ) |
1166 ) |
1155 |
1167 |
1156 r = _premerge( |
1168 r = _premerge( |
1157 repo, fcd, fco, fca, toolconf, files, labels=premergelabels |
1169 repo, fcd, fco, fca, toolconf, backup, labels=premergelabels |
1158 ) |
1170 ) |
1159 # we're done if premerge was successful (r is 0) |
1171 # we're done if premerge was successful (r is 0) |
1160 if not r: |
1172 if not r: |
1161 return not r, r, False |
1173 return not r, r, False |
1162 |
1174 |
1166 orig, |
1178 orig, |
1167 fcd, |
1179 fcd, |
1168 fco, |
1180 fco, |
1169 fca, |
1181 fca, |
1170 toolconf, |
1182 toolconf, |
1171 files, |
1183 backup, |
1172 labels=formattedlabels, |
1184 labels=formattedlabels, |
1173 ) |
1185 ) |
1174 |
1186 |
1175 if needcheck: |
1187 if needcheck: |
1176 r = _check(repo, r, ui, tool, fcd, files) |
1188 r = _check(repo, r, ui, tool, fcd, backup) |
1177 |
1189 |
1178 if r: |
1190 if r: |
1179 if onfailure: |
1191 if onfailure: |
1180 if wctx.isinmemory(): |
1192 if wctx.isinmemory(): |
1181 raise error.InMemoryMergeConflictsError( |
1193 raise error.InMemoryMergeConflictsError( |
1220 re.MULTILINE, |
1232 re.MULTILINE, |
1221 ) |
1233 ) |
1222 ) |
1234 ) |
1223 |
1235 |
1224 |
1236 |
1225 def _check(repo, r, ui, tool, fcd, files): |
1237 def _check(repo, r, ui, tool, fcd, backup): |
1226 fd = fcd.path() |
1238 fd = fcd.path() |
1227 uipathfn = scmutil.getuipathfn(repo) |
1239 uipathfn = scmutil.getuipathfn(repo) |
1228 unused, unused, unused, backup = files |
|
1229 |
1240 |
1230 if not r and ( |
1241 if not r and ( |
1231 _toolbool(ui, tool, b"checkconflicts") |
1242 _toolbool(ui, tool, b"checkconflicts") |
1232 or b'conflicts' in _toollist(ui, tool, b"check") |
1243 or b'conflicts' in _toollist(ui, tool, b"check") |
1233 ): |
1244 ): |