Follow-up to r29036: Now that the "mergeinfo" transaction file is no
[svn.git] / tools / examples / blame.py
blob5d953f1d7d3a1e9a4b1dd50775fbe8bf4adc8f14
1 #!/usr/bin/env python
3 # USAGE: blame.py [-r REV] repos-path file
6 import sys
7 import os
8 import getopt
9 try:
10 my_getopt = getopt.gnu_getopt
11 except AttributeError:
12 my_getopt = getopt.getopt
13 import difflib
14 from svn import fs, core, repos
16 CHUNK_SIZE = 100000
18 def blame(path, filename, rev=None):
20 annotresult = {}
21 path = core.svn_path_canonicalize(path)
23 repos_ptr = repos.open(path)
24 fsob = repos.fs(repos_ptr)
26 if rev is None:
27 rev = fs.youngest_rev(fsob)
28 filedata = ''
29 for i in xrange(0, rev+1):
30 root = fs.revision_root(fsob, i)
31 if fs.check_path(root, filename) != core.svn_node_none:
32 first = i
33 break
34 print "First revision is %d" % first
35 print "Last revision is %d" % rev
36 for i in xrange(first, rev+1):
37 previousroot = root
38 root = fs.revision_root(fsob, i)
39 if i != first:
40 if not fs.contents_changed(root, filename, previousroot, filename):
41 continue
43 file = fs.file_contents(root, filename)
44 previousdata = filedata
45 filedata = ''
46 while 1:
47 data = core.svn_stream_read(file, CHUNK_SIZE)
48 if not data:
49 break
50 filedata = filedata + data
52 print "Current revision is %d" % i
53 diffresult = difflib.ndiff(previousdata.splitlines(1),
54 filedata.splitlines(1))
55 # print ''.join(diffresult)
56 k = 0
57 for j in diffresult:
58 if j[0] == ' ':
59 if annotresult.has_key (k):
60 k = k + 1
61 continue
62 else:
63 annotresult[k] = (i, j[2:])
64 k = k + 1
65 continue
66 elif j[0] == '?':
67 continue
68 annotresult[k] = (i, j[2:])
69 if j[0] != '-':
70 k = k + 1
71 # print ''.join(diffresult)
72 # print annotresult
73 for x in xrange(len(annotresult.keys())):
74 sys.stdout.write("Line %d (rev %d):%s" % (x,
75 annotresult[x][0],
76 annotresult[x][1]))
78 def usage():
79 print "USAGE: blame.py [-r REV] repos-path file"
80 sys.exit(1)
82 def main():
83 opts, args = getopt.getopt(sys.argv[1:], 'r:')
84 if len(args) != 2:
85 usage()
86 rev = None
87 for name, value in opts:
88 if name == '-r':
89 rev = int(value)
90 blame(args[0], args[1], rev)
92 if __name__ == '__main__':
93 main()