浏览代码

Added ability to merge/rename authors

There's a new config field, 'merge_authors', which is a dictionary of
source name to target name. Whenever an author name matches a source
name it will be treated as if it was the target name instead.

Use this if authors have committed under multiple names, to squash their
statistics down to a single author. You can also use it to rename an
author for the purposes of the output.

Additionally, the -c option has been extended so for a dictionary option
you specify -c field=key,value. The key,value pair is then ADDED to the
dictionary.

Putting it all together in an example:

  ./gitstats -c merge_authors=bob,Bob\ Jones    \
      -c merge_authors=bob2,Bob\ Jones          \
      -c merge_authors=erica,Erica\ Smith ....

Signed-off-by: Heikki Hokkanen <hoxu@users.sf.net>
Ciaran Gultnieks 13 年前
父节点
当前提交
380b164bc5
共有 1 个文件被更改,包括 12 次插入0 次删除
  1. 12
    0
      gitstats

+ 12
- 0
gitstats 查看文件

40
 	'commit_end': 'HEAD',
40
 	'commit_end': 'HEAD',
41
 	'linear_linestats': 1,
41
 	'linear_linestats': 1,
42
 	'project_name': '',
42
 	'project_name': '',
43
+	'merge_authors': {}
43
 }
44
 }
44
 
45
 
45
 def getpipeoutput(cmds, quiet = False):
46
 def getpipeoutput(cmds, quiet = False):
286
 				parts = re.split('\s+', line, 2)
287
 				parts = re.split('\s+', line, 2)
287
 				commits = int(parts[1])
288
 				commits = int(parts[1])
288
 				author = parts[2]
289
 				author = parts[2]
290
+				if author in conf['merge_authors']:
291
+					author = conf['merge_authors'][author]
289
 				self.tags[tag]['commits'] += commits
292
 				self.tags[tag]['commits'] += commits
290
 				self.tags[tag]['authors'][author] = commits
293
 				self.tags[tag]['authors'][author] = commits
291
 
294
 
302
 			timezone = parts[3]
305
 			timezone = parts[3]
303
 			author, mail = parts[4].split('<', 1)
306
 			author, mail = parts[4].split('<', 1)
304
 			author = author.rstrip()
307
 			author = author.rstrip()
308
+			if author in conf['merge_authors']:
309
+				author = conf['merge_authors'][author]
305
 			mail = mail.rstrip('>')
310
 			mail = mail.rstrip('>')
306
 			domain = '?'
311
 			domain = '?'
307
 			if mail.find('@') != -1:
312
 			if mail.find('@') != -1:
474
 				if pos != -1:
479
 				if pos != -1:
475
 					try:
480
 					try:
476
 						(stamp, author) = (int(line[:pos]), line[pos+1:])
481
 						(stamp, author) = (int(line[:pos]), line[pos+1:])
482
+						if author in conf['merge_authors']:
483
+							author = conf['merge_authors'][author]
477
 						self.changes_by_date[stamp] = { 'files': files, 'ins': inserted, 'del': deleted, 'lines': total_lines }
484
 						self.changes_by_date[stamp] = { 'files': files, 'ins': inserted, 'del': deleted, 'lines': total_lines }
478
 
485
 
479
 						date = datetime.datetime.fromtimestamp(stamp)
486
 						date = datetime.datetime.fromtimestamp(stamp)
530
 					try:
537
 					try:
531
 						oldstamp = stamp
538
 						oldstamp = stamp
532
 						(stamp, author) = (int(line[:pos]), line[pos+1:])
539
 						(stamp, author) = (int(line[:pos]), line[pos+1:])
540
+						if author in conf['merge_authors']:
541
+							author = conf['merge_authors'][author]
533
 						if oldstamp > stamp:
542
 						if oldstamp > stamp:
534
 							# clock skew, keep old timestamp to avoid having ugly graph
543
 							# clock skew, keep old timestamp to avoid having ugly graph
535
 							stamp = oldstamp
544
 							stamp = oldstamp
1344
 					raise KeyError('no such key "%s" in config' % key)
1353
 					raise KeyError('no such key "%s" in config' % key)
1345
 				if isinstance(conf[key], int):
1354
 				if isinstance(conf[key], int):
1346
 					conf[key] = int(value)
1355
 					conf[key] = int(value)
1356
+				elif isinstance(conf[key], dict):
1357
+					kk,vv = value.split(',', 1)
1358
+					conf[key][kk] = vv
1347
 				else:
1359
 				else:
1348
 					conf[key] = value
1360
 					conf[key] = value
1349
 
1361