##// END OF EJS Templates
simplemerge: let extension check for binary inputs (unless `--text`)...
Martin von Zweigbergk -
r49596:109fec7b default
parent child Browse files
Show More
@@ -1,121 +1,140 b''
1 #!/usr/bin/env python3
1 #!/usr/bin/env python3
2 from __future__ import absolute_import
2 from __future__ import absolute_import
3
3
4 import getopt
4 import getopt
5 import sys
5 import sys
6
6
7 import hgdemandimport
7 import hgdemandimport
8
8
9 hgdemandimport.enable()
9 hgdemandimport.enable()
10
10
11 from mercurial.i18n import _
11 from mercurial.i18n import _
12 from mercurial import (
12 from mercurial import (
13 context,
13 context,
14 error,
14 error,
15 fancyopts,
15 fancyopts,
16 simplemerge,
16 simplemerge,
17 ui as uimod,
17 ui as uimod,
18 )
18 )
19 from mercurial.utils import procutil, stringutil
19 from mercurial.utils import procutil, stringutil
20
20
21 options = [
21 options = [
22 (b'L', b'label', [], _(b'labels to use on conflict markers')),
22 (b'L', b'label', [], _(b'labels to use on conflict markers')),
23 (b'a', b'text', None, _(b'treat all files as text')),
23 (b'a', b'text', None, _(b'treat all files as text')),
24 (b'p', b'print', None, _(b'print results instead of overwriting LOCAL')),
24 (b'p', b'print', None, _(b'print results instead of overwriting LOCAL')),
25 (b'', b'no-minimal', None, _(b'no effect (DEPRECATED)')),
25 (b'', b'no-minimal', None, _(b'no effect (DEPRECATED)')),
26 (b'h', b'help', None, _(b'display help and exit')),
26 (b'h', b'help', None, _(b'display help and exit')),
27 (b'q', b'quiet', None, _(b'suppress output')),
27 (b'q', b'quiet', None, _(b'suppress output')),
28 ]
28 ]
29
29
30 usage = _(
30 usage = _(
31 b'''simplemerge [OPTS] LOCAL BASE OTHER
31 b'''simplemerge [OPTS] LOCAL BASE OTHER
32
32
33 Simple three-way file merge utility with a minimal feature set.
33 Simple three-way file merge utility with a minimal feature set.
34
34
35 Apply to LOCAL the changes necessary to go from BASE to OTHER.
35 Apply to LOCAL the changes necessary to go from BASE to OTHER.
36
36
37 By default, LOCAL is overwritten with the results of this operation.
37 By default, LOCAL is overwritten with the results of this operation.
38 '''
38 '''
39 )
39 )
40
40
41
41
42 class ParseError(Exception):
42 class ParseError(Exception):
43 """Exception raised on errors in parsing the command line."""
43 """Exception raised on errors in parsing the command line."""
44
44
45
45
46 def showhelp():
46 def showhelp():
47 procutil.stdout.write(usage)
47 procutil.stdout.write(usage)
48 procutil.stdout.write(b'\noptions:\n')
48 procutil.stdout.write(b'\noptions:\n')
49
49
50 out_opts = []
50 out_opts = []
51 for shortopt, longopt, default, desc in options:
51 for shortopt, longopt, default, desc in options:
52 out_opts.append(
52 out_opts.append(
53 (
53 (
54 b'%2s%s'
54 b'%2s%s'
55 % (
55 % (
56 shortopt and b'-%s' % shortopt,
56 shortopt and b'-%s' % shortopt,
57 longopt and b' --%s' % longopt,
57 longopt and b' --%s' % longopt,
58 ),
58 ),
59 b'%s' % desc,
59 b'%s' % desc,
60 )
60 )
61 )
61 )
62 opts_len = max([len(opt[0]) for opt in out_opts])
62 opts_len = max([len(opt[0]) for opt in out_opts])
63 for first, second in out_opts:
63 for first, second in out_opts:
64 procutil.stdout.write(b' %-*s %s\n' % (opts_len, first, second))
64 procutil.stdout.write(b' %-*s %s\n' % (opts_len, first, second))
65
65
66
66
67 def _verifytext(input, ui, quiet=False, allow_binary=False):
68 """verifies that text is non-binary (unless opts[text] is passed,
69 then we just warn)"""
70 if stringutil.binary(input.text()):
71 msg = _(b"%s looks like a binary file.") % input.fctx.path()
72 if not quiet:
73 ui.warn(_(b'warning: %s\n') % msg)
74 if not allow_binary:
75 sys.exit(1)
76
77
67 try:
78 try:
68 for fp in (sys.stdin, procutil.stdout, sys.stderr):
79 for fp in (sys.stdin, procutil.stdout, sys.stderr):
69 procutil.setbinary(fp)
80 procutil.setbinary(fp)
70
81
71 opts = {}
82 opts = {}
72 try:
83 try:
73 bargv = [a.encode('utf8') for a in sys.argv[1:]]
84 bargv = [a.encode('utf8') for a in sys.argv[1:]]
74 args = fancyopts.fancyopts(bargv, options, opts)
85 args = fancyopts.fancyopts(bargv, options, opts)
75 except getopt.GetoptError as e:
86 except getopt.GetoptError as e:
76 raise ParseError(e)
87 raise ParseError(e)
77 if opts[b'help']:
88 if opts[b'help']:
78 showhelp()
89 showhelp()
79 sys.exit(0)
90 sys.exit(0)
80 if len(args) != 3:
91 if len(args) != 3:
81 raise ParseError(_(b'wrong number of arguments').decode('utf8'))
92 raise ParseError(_(b'wrong number of arguments').decode('utf8'))
82 mode = b'merge'
93 mode = b'merge'
83 if len(opts[b'label']) > 2:
94 if len(opts[b'label']) > 2:
84 mode = b'merge3'
95 mode = b'merge3'
85 local, base, other = args
96 local, base, other = args
86 overrides = opts[b'label']
97 overrides = opts[b'label']
87 if len(overrides) > 3:
98 if len(overrides) > 3:
88 raise error.InputError(b'can only specify three labels.')
99 raise error.InputError(b'can only specify three labels.')
89 labels = [local, other, base]
100 labels = [local, other, base]
90 labels[: len(overrides)] = overrides
101 labels[: len(overrides)] = overrides
91 local_input = simplemerge.MergeInput(
102 local_input = simplemerge.MergeInput(
92 context.arbitraryfilectx(local), labels[0]
103 context.arbitraryfilectx(local), labels[0]
93 )
104 )
94 other_input = simplemerge.MergeInput(
105 other_input = simplemerge.MergeInput(
95 context.arbitraryfilectx(other), labels[1]
106 context.arbitraryfilectx(other), labels[1]
96 )
107 )
97 base_input = simplemerge.MergeInput(
108 base_input = simplemerge.MergeInput(
98 context.arbitraryfilectx(base), labels[2]
109 context.arbitraryfilectx(base), labels[2]
99 )
110 )
111
112 quiet = opts.get(b'quiet')
113 allow_binary = opts.get(b'text')
114 ui = uimod.ui.load()
115 _verifytext(local_input, ui, quiet=quiet, allow_binary=allow_binary)
116 _verifytext(base_input, ui, quiet=quiet, allow_binary=allow_binary)
117 _verifytext(other_input, ui, quiet=quiet, allow_binary=allow_binary)
118
100 sys.exit(
119 sys.exit(
101 simplemerge.simplemerge(
120 simplemerge.simplemerge(
102 uimod.ui.load(),
121 ui,
103 local_input,
122 local_input,
104 base_input,
123 base_input,
105 other_input,
124 other_input,
106 mode,
125 mode,
107 quiet=opts.get(b'quiet'),
126 quiet=True,
108 allow_binary=opts.get(b'text'),
127 allow_binary=allow_binary,
109 print_result=opts.get(b'print'),
128 print_result=opts.get(b'print'),
110 )
129 )
111 )
130 )
112 except ParseError as e:
131 except ParseError as e:
113 e = stringutil.forcebytestr(e)
132 e = stringutil.forcebytestr(e)
114 procutil.stdout.write(b"%s: %s\n" % (sys.argv[0].encode('utf8'), e))
133 procutil.stdout.write(b"%s: %s\n" % (sys.argv[0].encode('utf8'), e))
115 showhelp()
134 showhelp()
116 sys.exit(1)
135 sys.exit(1)
117 except error.Abort as e:
136 except error.Abort as e:
118 procutil.stderr.write(b"abort: %s\n" % e)
137 procutil.stderr.write(b"abort: %s\n" % e)
119 sys.exit(255)
138 sys.exit(255)
120 except KeyboardInterrupt:
139 except KeyboardInterrupt:
121 sys.exit(255)
140 sys.exit(255)
General Comments 0
You need to be logged in to leave comments. Login now