annotate contrib/hgdiff @ 4398:3b7e284b8f28

merge: expand and simplify the invalid handling for directory moves
author Matt Mackall <mpm@selenic.com>
date Thu, 03 May 2007 17:24:43 -0500
parents 0f308690bda8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1636
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1 #!/usr/bin/env python
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
3 import os, sys, struct, stat
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 import difflib
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
5 import re
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
6 from optparse import OptionParser
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7 from mercurial.bdiff import bdiff, blocks
3398
0f308690bda8 Fixed contrib/hgdiff script to pass diffopts in the new format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1644
diff changeset
8 from mercurial.mdiff import bunidiff, diffopts
1636
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
9
3398
0f308690bda8 Fixed contrib/hgdiff script to pass diffopts in the new format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1644
diff changeset
10 VERSION="0.3"
1636
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
11 usage = "usage: %prog [options] file1 file2"
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
12 parser = OptionParser(usage=usage)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
13
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
14 parser.add_option("-d", "--difflib", action="store_true", default=False)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
15 parser.add_option('-x', '--count', default=1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
16 parser.add_option('-c', '--context', type="int", default=3)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
17 parser.add_option('-p', '--show-c-function', action="store_true", default=False)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
18 parser.add_option('-w', '--ignore-all-space', action="store_true",
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
19 default=False)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
20
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
21 (options, args) = parser.parse_args()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
22
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
23 if not args:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
24 parser.print_help()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
25 sys.exit(1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
26
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
27 # simple utility function to put all the
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
28 # files from a directory tree into a dict
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
29 def buildlist(names, top):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
30 tlen = len(top)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
31 for root, dirs, files in os.walk(top):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
32 l = root[tlen + 1:]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
33 for x in files:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
34 p = os.path.join(root, x)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
35 st = os.lstat(p)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
36 if stat.S_ISREG(st.st_mode):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
37 names[os.path.join(l, x)] = (st.st_dev, st.st_ino)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
38
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
39 def diff_files(file1, file2):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
40 if file1 == None:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
41 b = file(file2).read().splitlines(1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
42 l1 = "--- %s\n" % (file2)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
43 l2 = "+++ %s\n" % (file2)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
44 l3 = "@@ -0,0 +1,%d @@\n" % len(b)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
45 l = [l1, l2, l3] + ["+" + e for e in b]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
46 elif file2 == None:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
47 a = file(file1).read().splitlines(1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
48 l1 = "--- %s\n" % (file1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
49 l2 = "+++ %s\n" % (file1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
50 l3 = "@@ -1,%d +0,0 @@\n" % len(a)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
51 l = [l1, l2, l3] + ["-" + e for e in a]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
52 else:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
53 t1 = file(file1).read()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
54 t2 = file(file2).read()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
55 l1 = t1.splitlines(1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
56 l2 = t2.splitlines(1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
57 if options.difflib:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
58 l = difflib.unified_diff(l1, l2, file1, file2)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
59 else:
3398
0f308690bda8 Fixed contrib/hgdiff script to pass diffopts in the new format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1644
diff changeset
60 l = bunidiff(t1, t2, l1, l2, file1, file2,
0f308690bda8 Fixed contrib/hgdiff script to pass diffopts in the new format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1644
diff changeset
61 diffopts(context=options.context,
0f308690bda8 Fixed contrib/hgdiff script to pass diffopts in the new format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1644
diff changeset
62 showfunc=options.show_c_function,
0f308690bda8 Fixed contrib/hgdiff script to pass diffopts in the new format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1644
diff changeset
63 ignorews=options.ignore_all_space))
1636
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
64 for x in l:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
65 if x[-1] != '\n':
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
66 x += "\n\ No newline at end of file\n"
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
67 print x,
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
68
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
69 file1 = args[0]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
70 file2 = args[1]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
71
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
72 if os.path.isfile(file1) and os.path.isfile(file2):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
73 diff_files(file1, file2)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
74 elif os.path.isdir(file1):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
75 if not os.path.isdir(file2):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
76 sys.stderr.write("file types don't match\n")
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
77 sys.exit(1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
78
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
79 d1 = {}
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
80 d2 = {}
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
81
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
82 buildlist(d1, file1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
83 buildlist(d2, file2)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
84 keys = d1.keys()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
85 keys.sort()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
86 for x in keys:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
87 if x not in d2:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
88 f2 = None
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
89 else:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
90 f2 = os.path.join(file2, x)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
91 st1 = d1[x]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
92 st2 = d2[x]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
93 del d2[x]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
94 if st1[0] == st2[0] and st1[1] == st2[1]:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
95 sys.stderr.write("%s is a hard link\n" % x)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
96 continue
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
97 x = os.path.join(file1, x)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
98 diff_files(x, f2)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
99 keys = d2.keys()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
100 keys.sort()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
101 for x in keys:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
102 f1 = None
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
103 x = os.path.join(file2, x)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
104 diff_files(f1, x)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
105