740 % (tool, uipathfn(fcd.path())) |
740 % (tool, uipathfn(fcd.path())) |
741 ) |
741 ) |
742 return False, 1, None |
742 return False, 1, None |
743 localpath = _workingpath(repo, fcd) |
743 localpath = _workingpath(repo, fcd) |
744 args = _toolstr(repo.ui, tool, b"args") |
744 args = _toolstr(repo.ui, tool, b"args") |
745 localoutputpath = None |
745 |
|
746 files = [ |
|
747 (b"base", fca.path(), fca.decodeddata()), |
|
748 (b"other", fco.path(), fco.decodeddata()), |
|
749 ] |
|
750 outpath = b"" |
746 if b"$output" in args: |
751 if b"$output" in args: |
|
752 # read input from backup, write to original |
|
753 outpath = localpath |
747 localoutputpath = backup.path() |
754 localoutputpath = backup.path() |
748 # Remove the .orig to make syntax-highlighting more likely. |
755 # Remove the .orig to make syntax-highlighting more likely. |
749 if localoutputpath.endswith(b'.orig'): |
756 if localoutputpath.endswith(b'.orig'): |
750 localoutputpath, ext = os.path.splitext(localoutputpath) |
757 localoutputpath, ext = os.path.splitext(localoutputpath) |
751 |
758 localdata = util.readfile(localpath) |
752 with _maketempfiles( |
759 files.append((b"local", localoutputpath, localdata)) |
753 fco, |
760 |
754 fca, |
761 with _maketempfiles(files) as temppaths: |
755 localoutputpath, |
762 basepath, otherpath = temppaths[:2] |
756 ) as temppaths: |
763 if len(temppaths) == 3: |
757 basepath, otherpath, localoutputpath = temppaths |
764 localpath = temppaths[2] |
758 outpath = b"" |
|
759 |
765 |
760 def format_label(input): |
766 def format_label(input): |
761 if input.label_detail: |
767 if input.label_detail: |
762 return b'%s: %s' % (input.label, input.label_detail) |
768 return b'%s: %s' % (input.label, input.label_detail) |
763 else: |
769 else: |
913 |
915 |
914 return context.arbitraryfilectx(backup, repo=repo) |
916 return context.arbitraryfilectx(backup, repo=repo) |
915 |
917 |
916 |
918 |
917 @contextlib.contextmanager |
919 @contextlib.contextmanager |
918 def _maketempfiles(fco, fca, localpath): |
920 def _maketempfiles(files): |
919 """Writes out `fco` and `fca` as temporary files, and (if localpath is not |
921 """Creates a temporary file for each (prefix, path, data) tuple in `files`, |
920 None) copies `localpath` to another temporary file, so an external merge |
922 so an external merge tool may use them. |
921 tool may use them. |
|
922 """ |
923 """ |
923 tmproot = pycompat.mkdtemp(prefix=b'hgmerge-') |
924 tmproot = pycompat.mkdtemp(prefix=b'hgmerge-') |
924 |
925 |
925 def maketempfrompath(prefix, path, data): |
926 def maketempfrompath(prefix, path, data): |
926 fullbase, ext = os.path.splitext(path) |
927 fullbase, ext = os.path.splitext(path) |
929 if ext: |
930 if ext: |
930 name += ext |
931 name += ext |
931 util.writefile(name, data) |
932 util.writefile(name, data) |
932 return name |
933 return name |
933 |
934 |
934 def tempfromcontext(prefix, ctx): |
935 temp_files = [] |
935 return maketempfrompath(prefix, ctx.path(), ctx.decodeddata()) |
936 for prefix, path, data in files: |
936 |
937 temp_files.append(maketempfrompath(prefix, path, data)) |
937 b = tempfromcontext(b"base", fca) |
|
938 c = tempfromcontext(b"other", fco) |
|
939 d = localpath |
|
940 if localpath is not None: |
|
941 data = util.readfile(localpath) |
|
942 d = maketempfrompath(b"local", localpath, data) |
|
943 |
|
944 try: |
938 try: |
945 yield b, c, d |
939 yield temp_files |
946 finally: |
940 finally: |
947 shutil.rmtree(tmproot) |
941 shutil.rmtree(tmproot) |
948 |
942 |
949 |
943 |
950 def filemerge(repo, wctx, mynode, orig, fcd, fco, fca, labels=None): |
944 def filemerge(repo, wctx, mynode, orig, fcd, fco, fca, labels=None): |