simplemerge
141 lines
| 4.0 KiB
| text/plain
|
TextLexer
/ contrib / simplemerge
Gregory Szorc
|
r46434 | #!/usr/bin/env python3 | ||
Augie Fackler
|
r33896 | from __future__ import absolute_import | ||
Alexis S. L. Carvalho
|
r4362 | |||
Pulkit Goyal
|
r30576 | import getopt | ||
Simon Heimberg
|
r19378 | import sys | ||
Augie Fackler
|
r33896 | |||
import hgdemandimport | ||||
Gregory Szorc
|
r44058 | |||
Augie Fackler
|
r33896 | hgdemandimport.enable() | ||
Alexis S. L. Carvalho
|
r4363 | from mercurial.i18n import _ | ||
Augie Fackler
|
r33896 | from mercurial import ( | ||
Phil Cohen
|
r34053 | context, | ||
Augie Fackler
|
r33896 | error, | ||
fancyopts, | ||||
simplemerge, | ||||
ui as uimod, | ||||
Martin von Zweigbergk
|
r49599 | util, | ||
Yuya Nishihara
|
r37138 | ) | ||
Gregory Szorc
|
r44058 | from mercurial.utils import procutil, stringutil | ||
Alexis S. L. Carvalho
|
r4362 | |||
Gregory Szorc
|
r44058 | options = [ | ||
(b'L', b'label', [], _(b'labels to use on conflict markers')), | ||||
(b'a', b'text', None, _(b'treat all files as text')), | ||||
(b'p', b'print', None, _(b'print results instead of overwriting LOCAL')), | ||||
(b'', b'no-minimal', None, _(b'no effect (DEPRECATED)')), | ||||
(b'h', b'help', None, _(b'display help and exit')), | ||||
(b'q', b'quiet', None, _(b'suppress output')), | ||||
] | ||||
Alexis S. L. Carvalho
|
r4364 | |||
Gregory Szorc
|
r44058 | usage = _( | ||
b'''simplemerge [OPTS] LOCAL BASE OTHER | ||||
Alexis S. L. Carvalho
|
r4364 | |||
Simple three-way file merge utility with a minimal feature set. | ||||
Thomas Arendsen Hein
|
r5081 | |||
Alexis S. L. Carvalho
|
r4364 | Apply to LOCAL the changes necessary to go from BASE to OTHER. | ||
Thomas Arendsen Hein
|
r5081 | |||
Alexis S. L. Carvalho
|
r4364 | By default, LOCAL is overwritten with the results of this operation. | ||
Gregory Szorc
|
r44058 | ''' | ||
) | ||||
Alexis S. L. Carvalho
|
r4364 | |||
Matt Mackall
|
r6002 | class ParseError(Exception): | ||
"""Exception raised on errors in parsing the command line.""" | ||||
Gregory Szorc
|
r44058 | |||
Alexis S. L. Carvalho
|
r4364 | def showhelp(): | ||
Manuel Jacob
|
r45598 | procutil.stdout.write(usage) | ||
procutil.stdout.write(b'\noptions:\n') | ||||
Alexis S. L. Carvalho
|
r4362 | |||
Alexis S. L. Carvalho
|
r4364 | out_opts = [] | ||
for shortopt, longopt, default, desc in options: | ||||
Gregory Szorc
|
r44058 | out_opts.append( | ||
( | ||||
b'%2s%s' | ||||
% ( | ||||
shortopt and b'-%s' % shortopt, | ||||
longopt and b' --%s' % longopt, | ||||
), | ||||
b'%s' % desc, | ||||
) | ||||
) | ||||
Alexis S. L. Carvalho
|
r4364 | opts_len = max([len(opt[0]) for opt in out_opts]) | ||
for first, second in out_opts: | ||||
Manuel Jacob
|
r45598 | procutil.stdout.write(b' %-*s %s\n' % (opts_len, first, second)) | ||
Alexis S. L. Carvalho
|
r4364 | |||
Gregory Szorc
|
r44058 | |||
Martin von Zweigbergk
|
r49596 | def _verifytext(input, ui, quiet=False, allow_binary=False): | ||
"""verifies that text is non-binary (unless opts[text] is passed, | ||||
then we just warn)""" | ||||
if stringutil.binary(input.text()): | ||||
msg = _(b"%s looks like a binary file.") % input.fctx.path() | ||||
if not quiet: | ||||
ui.warn(_(b'warning: %s\n') % msg) | ||||
if not allow_binary: | ||||
sys.exit(1) | ||||
Matt Mackall
|
r6002 | try: | ||
Manuel Jacob
|
r45598 | for fp in (sys.stdin, procutil.stdout, sys.stderr): | ||
Yuya Nishihara
|
r37138 | procutil.setbinary(fp) | ||
Mads Kiilerich
|
r19022 | |||
Matt Mackall
|
r6002 | opts = {} | ||
Alexis S. L. Carvalho
|
r4364 | try: | ||
Augie Fackler
|
r40296 | bargv = [a.encode('utf8') for a in sys.argv[1:]] | ||
args = fancyopts.fancyopts(bargv, options, opts) | ||||
Pulkit Goyal
|
r30576 | except getopt.GetoptError as e: | ||
Matt Mackall
|
r6002 | raise ParseError(e) | ||
Pulkit Goyal
|
r39826 | if opts[b'help']: | ||
Alexis S. L. Carvalho
|
r4364 | showhelp() | ||
Matt Mackall
|
r6002 | sys.exit(0) | ||
if len(args) != 3: | ||||
Gregory Szorc
|
r44058 | raise ParseError(_(b'wrong number of arguments').decode('utf8')) | ||
Martin von Zweigbergk
|
r49593 | mode = b'merge' | ||
Martin von Zweigbergk
|
r49404 | if len(opts[b'label']) > 2: | ||
Martin von Zweigbergk
|
r49593 | mode = b'merge3' | ||
Phil Cohen
|
r33904 | local, base, other = args | ||
Martin von Zweigbergk
|
r49409 | overrides = opts[b'label'] | ||
Martin von Zweigbergk
|
r49427 | if len(overrides) > 3: | ||
raise error.InputError(b'can only specify three labels.') | ||||
Martin von Zweigbergk
|
r49409 | labels = [local, other, base] | ||
labels[: len(overrides)] = overrides | ||||
Martin von Zweigbergk
|
r49427 | local_input = simplemerge.MergeInput( | ||
context.arbitraryfilectx(local), labels[0] | ||||
) | ||||
other_input = simplemerge.MergeInput( | ||||
context.arbitraryfilectx(other), labels[1] | ||||
) | ||||
base_input = simplemerge.MergeInput( | ||||
context.arbitraryfilectx(base), labels[2] | ||||
) | ||||
Martin von Zweigbergk
|
r49596 | |||
quiet = opts.get(b'quiet') | ||||
allow_binary = opts.get(b'text') | ||||
ui = uimod.ui.load() | ||||
_verifytext(local_input, ui, quiet=quiet, allow_binary=allow_binary) | ||||
_verifytext(base_input, ui, quiet=quiet, allow_binary=allow_binary) | ||||
_verifytext(other_input, ui, quiet=quiet, allow_binary=allow_binary) | ||||
Martin von Zweigbergk
|
r49599 | merged_text, conflicts = simplemerge.simplemerge( | ||
local_input, | ||||
base_input, | ||||
other_input, | ||||
mode, | ||||
allow_binary=allow_binary, | ||||
Gregory Szorc
|
r44058 | ) | ||
Martin von Zweigbergk
|
r49599 | if opts.get(b'print'): | ||
ui.fout.write(merged_text) | ||||
else: | ||||
util.writefile(local, merged_text) | ||||
sys.exit(1 if conflicts else 0) | ||||
FUJIWARA Katsunori
|
r28047 | except ParseError as e: | ||
Emmanuel Leblond
|
r43684 | e = stringutil.forcebytestr(e) | ||
Manuel Jacob
|
r45598 | procutil.stdout.write(b"%s: %s\n" % (sys.argv[0].encode('utf8'), e)) | ||
Matt Mackall
|
r6002 | showhelp() | ||
sys.exit(1) | ||||
FUJIWARA Katsunori
|
r28047 | except error.Abort as e: | ||
Manuel Jacob
|
r45598 | procutil.stderr.write(b"abort: %s\n" % e) | ||
Matt Mackall
|
r6002 | sys.exit(255) | ||
except KeyboardInterrupt: | ||||
sys.exit(255) | ||||