##// END OF EJS Templates
polish the simplemerge command; add a test
Alexis S. L. Carvalho -
r4364:d5c3a70f default
parent child Browse files
Show More
@@ -0,0 +1,61 b''
1 #!/bin/sh
2
3 cp "$TESTDIR"/../contrib/simplemerge .
4
5 echo base > base
6
7 echo local > local
8 cat base >> local
9 cp local orig
10
11 cat base > other
12 echo other >> other
13
14 echo '% changing local directly'
15 python simplemerge local base other && echo "merge succeeded"
16 cat local
17 cp orig local
18
19 echo '% printing to stdout'
20 python simplemerge -p local base other
21 echo ' local:'
22 cat local
23
24 echo '% conflicts'
25 cp base conflict-local
26 cp other conflict-other
27 echo not other >> conflict-local
28 echo end >> conflict-local
29 echo end >> conflict-other
30 python simplemerge -p conflict-local base conflict-other || echo "merge failed"
31
32 echo '% --no-minimal'
33 python simplemerge -p --no-minimal conflict-local base conflict-other
34
35 echo '% 1 label'
36 python simplemerge -p -L foo conflict-local base conflict-other
37
38 echo '% 2 labels'
39 python simplemerge -p -L foo -L bar conflict-local base conflict-other
40
41 echo '% too many labels'
42 python simplemerge -p -L foo -L bar -L baz conflict-local base conflict-other
43
44 echo '% binary file'
45 printf '\x00' > binary-local
46 cat orig >> binary-local
47 python simplemerge -p binary-local base other
48
49 echo '% binary file --text'
50 python simplemerge -a -p binary-local base other
51
52 echo '% help'
53 python simplemerge --help
54
55 echo '% wrong number of arguments'
56 python simplemerge
57
58 echo '% bad option'
59 python simplemerge --foo -p local base other
60
61 exit 0
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -19,8 +19,10 b''
19 # mbp: "you know that thing where cvs gives you conflict markers?"
19 # mbp: "you know that thing where cvs gives you conflict markers?"
20 # s: "i hate that."
20 # s: "i hate that."
21
21
22 from mercurial import demandimport
23 demandimport.enable()
22
24
23 from mercurial import util, mdiff
25 from mercurial import util, mdiff, fancyopts
24 from mercurial.i18n import _
26 from mercurial.i18n import _
25
27
26
28
@@ -97,6 +99,7 b' class Merge3Text(object):'
97 reprocess=False):
99 reprocess=False):
98 """Return merge in cvs-like form.
100 """Return merge in cvs-like form.
99 """
101 """
102 self.conflicts = False
100 newline = '\n'
103 newline = '\n'
101 if len(self.a) > 0:
104 if len(self.a) > 0:
102 if self.a[0].endswith('\r\n'):
105 if self.a[0].endswith('\r\n'):
@@ -126,6 +129,7 b' class Merge3Text(object):'
126 for i in range(t[1], t[2]):
129 for i in range(t[1], t[2]):
127 yield self.b[i]
130 yield self.b[i]
128 elif what == 'conflict':
131 elif what == 'conflict':
132 self.conflicts = True
129 yield start_marker + newline
133 yield start_marker + newline
130 for i in range(t[3], t[4]):
134 for i in range(t[3], t[4]):
131 yield self.a[i]
135 yield self.a[i]
@@ -439,21 +443,115 b' class Merge3(Merge3Text):'
439 Merge3Text.__init__(self, basetext, atext, btext, base, a, b)
443 Merge3Text.__init__(self, basetext, atext, btext, base, a, b)
440
444
441
445
442 def main(argv):
446 def simplemerge(local, base, other, **opts):
443 # as for diff3 and meld the syntax is "MINE BASE OTHER"
447 def readfile(filename):
444 a = file(argv[1], 'rt').readlines()
448 f = open(filename, "rb")
445 base = file(argv[2], 'rt').readlines()
449 text = f.read()
446 b = file(argv[3], 'rt').readlines()
450 f.close()
451 if util.binary(text):
452 msg = _("%s looks like a binary file.") % filename
453 if not opts.get('text'):
454 raise util.Abort(msg)
455 elif not opts.get('quiet'):
456 sys.stderr.write(_('warning: %s\n') % msg)
457 return text
458
459 name_a = local
460 name_b = other
461 labels = opts.get('label', [])
462 if labels:
463 name_a = labels.pop(0)
464 if labels:
465 name_b = labels.pop(0)
466 if labels:
467 raise util.Abort(_("can only specify two labels."))
468
469 localtext = readfile(local)
470 basetext = readfile(base)
471 othertext = readfile(other)
472
473 orig = local
474 local = os.path.realpath(local)
475 if not opts.get('print'):
476 opener = util.opener(os.path.dirname(local))
477 out = opener(os.path.basename(local), "w", atomictemp=True)
478 else:
479 out = sys.stdout
480
481 reprocess = not opts.get('no_minimal')
482
483 m3 = Merge3Text(basetext, localtext, othertext)
484 for line in m3.merge_lines(name_a=name_a, name_b=name_b,
485 reprocess=reprocess):
486 out.write(line)
487
488 if not opts.get('print'):
489 out.rename()
490
491 if m3.conflicts:
492 if not opts.get('quiet'):
493 sys.stdout.flush()
494 sys.stderr.write(_("warning: conflicts during merge.\n"))
495 return 1
447
496
448 m3 = Merge3(base, a, b)
497 options = [('L', 'label', [], _('labels to use on conflict markers')),
498 ('a', 'text', None, _('treat all files as text')),
499 ('p', 'print', None,
500 _('print results instead of overwriting LOCAL')),
501 ('', 'no-minimal', None,
502 _('do not try to minimize conflict regions')),
503 ('h', 'help', None, _('display help and exit')),
504 ('q', 'quiet', None, _('suppress output'))]
505
506 usage = _('''simplemerge [OPTS] LOCAL BASE OTHER
507
508 Simple three-way file merge utility with a minimal feature set.
509
510 Apply to LOCAL the changes necessary to go from BASE to OTHER.
511
512 By default, LOCAL is overwritten with the results of this operation.
513 ''')
514
515 def showhelp():
516 sys.stdout.write(usage)
517 sys.stdout.write('\noptions:\n')
449
518
450 #for sr in m3.find_sync_regions():
519 out_opts = []
451 # print sr
520 for shortopt, longopt, default, desc in options:
521 out_opts.append(('%2s%s' % (shortopt and '-%s' % shortopt,
522 longopt and ' --%s' % longopt),
523 '%s' % desc))
524 opts_len = max([len(opt[0]) for opt in out_opts])
525 for first, second in out_opts:
526 sys.stdout.write(' %-*s %s\n' % (opts_len, first, second))
527
528 class ParseError(Exception):
529 """Exception raised on errors in parsing the command line."""
452
530
453 # sys.stdout.writelines(m3.merge_lines(name_a=argv[1], name_b=argv[3]))
531 def main(argv):
454 sys.stdout.writelines(m3.merge_annotated())
532 try:
455
533 opts = {}
534 try:
535 args = fancyopts.fancyopts(argv[1:], options, opts)
536 except fancyopts.getopt.GetoptError, e:
537 raise ParseError(e)
538 if opts['help']:
539 showhelp()
540 return 0
541 if len(args) != 3:
542 raise ParseError(_('wrong number of arguments'))
543 return simplemerge(*args, **opts)
544 except ParseError, e:
545 sys.stdout.write("%s: %s\n" % (sys.argv[0], e))
546 showhelp()
547 return 1
548 except util.Abort, e:
549 sys.stderr.write("abort: %s\n" % e)
550 return 255
551 except KeyboardInterrupt:
552 return 255
456
553
457 if __name__ == '__main__':
554 if __name__ == '__main__':
458 import sys
555 import sys
556 import os
459 sys.exit(main(sys.argv))
557 sys.exit(main(sys.argv))
General Comments 0
You need to be logged in to leave comments. Login now