summaryrefslogtreecommitdiff
path: root/git_contributors.py
diff options
context:
space:
mode:
authorCarlos Maiolino <[email protected]>2026-05-02 14:09:27 +0200
committerCarlos Maiolino <[email protected]>2026-05-02 14:09:27 +0200
commit296c6b9ee85209c0ce375717e30686545baea107 (patch)
treef0da71650e8f58ca528589ad4e39476732fa5b88 /git_contributors.py
parentb2e1a1cb259e482720430ff9898d2e564ee73d0f (diff)
Save new changesHEADmaster
Diffstat (limited to 'git_contributors.py')
-rw-r--r--git_contributors.py68
1 files changed, 68 insertions, 0 deletions
diff --git a/git_contributors.py b/git_contributors.py
new file mode 100644
index 0000000..91a7f6a
--- /dev/null
+++ b/git_contributors.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python3
+
+# List all contributors to a series of git commits.
+# Copyright(C) 2022 Darrick J. Wong, All Rights Reserved.
+# Licensed under GPL 2.0 or later
+
+import re
+import subprocess
+import io
+import sys
+import argparse
+
+DEBUG = False
+
+def backtick(args):
+ '''Generator function that yields lines of a program's stdout.'''
+ if DEBUG:
+ print(' '.join(args))
+ p = subprocess.Popen(args, stdout = subprocess.PIPE)
+ for line in io.TextIOWrapper(p.stdout, encoding="utf-8"):
+ yield line.strip()
+
+def get_developers(revspec):
+ """Return the address list generated from signed-off-by and
+ acked-by lines in the message.
+ """
+ tags = '%s|%s|%s|%s|%s|%s|%s|%s' % (
+ 'signed-off-by',
+ 'acked-by',
+ 'cc',
+ 'reviewed-by',
+ 'reported-by',
+ 'tested-by',
+ 'suggested-by',
+ 'reported-and-tested-by')
+ regex1 = r'^(%s):\s+(.+)$' % tags
+ regex2 = r'^(%s):\s+.+<(.+)>$' % tags
+
+ r1 = re.compile(regex1, re.I)
+ r2 = re.compile(regex2, re.I)
+
+ for output in backtick(['git', 'log', '--pretty=medium', revspec]):
+ m = r2.match(output)
+ if m:
+ addr_list.append(m.expand(r'\g<2>'))
+ continue
+ m = r1.match(output)
+ if m:
+ addr_list.append(m.expand(r'\g<2>'))
+
+ return set(addr_list)
+
+def main():
+ parser = argparse.ArgumentParser(description = "List email addresses of contributors to a series of git commits.")
+ parser.add_argument("revisions", nargs = 1, \
+ help = "git revisions to process.")
+ parser.add_argument("--delimiter", type = str, default = '\n', \
+ help = "Separate each email address with this string.")
+ args = parser.parse_args()
+
+ contributors = get_developers(args.revisions[0])
+
+ print(args.delimiter.join(sorted(contributors)))
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())