3 # Find out how many lines were introduced in each major release.
7 # This code is part of the LWN git data miner.
9 # Copyright 2007-11 Eklektix, Inc.
10 # Copyright 2007-11 Jonathan Corbet <corbet@lwn.net>
12 # This file may be distributed under the terms of the GNU General
13 # Public License, version 2.
15 import sys
, re
, os
, pickle
, subprocess
19 commitpat
= re
.compile(r
'^([\da-f][\da-f]+) ')
21 def GetCommitLines(file):
23 # blame = os.popen('git blame -p ' + file, 'rb')
24 with subprocess
.Popen(['/usr/bin/git', 'blame', '-p', file],
25 stdout
= subprocess
.PIPE
) as blame
:
26 for line
in blame
.stdout
.readlines():
28 line
= line
.decode('utf8')
29 except UnicodeDecodeError:
30 print('Bad line in %s:\n\t %s' % (file, line
.decode('latin1')))
32 m
= commitpat
.search(line
)
34 # All-zero commits mean we got fed a file that git doesn't
35 # know about. We could throw an exception and abort processing
36 # now, or we can just silently ignore it...
38 if not m
or m
.group(1) == '0000000000000000000000000000000000000000':
41 CommitLines
[m
.group(1)] += 1
43 CommitLines
[m
.group(1)] = 1
46 # Try to figure out which tag is the first to contain each commit.
48 def CommitToTag(commit
):
52 print('Missing commit %s' % (commit
))
57 print('Mapping tags...')
58 for commit
in CommitLines
.keys():
59 tag
= CommitToTag(commit
)
61 TagLines
[tag
] += CommitLines
[commit
]
63 TagLines
[tag
] = CommitLines
[commit
]
66 # Here we just plow through all the files.
68 if len(sys
.argv
) != 2:
69 sys
.stderr
.write('Usage: linetags directory\n')
72 # Grab the tags/version database.
74 dbf
= open('committags.db', 'rb')
78 out
= open('linetags.out', 'w')
80 files
= os
.popen('/usr/bin/find . -type f', 'r')
81 for file in files
.readlines():
82 if file.find('.git/') < 0:
83 GetCommitLines(file[:-1])
85 tags
= sorted(TagLines
.keys())
87 out
.write('%s %d\n' % (tag
, TagLines
[tag
]))