This repository has been archived by the owner on Oct 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
git.py
69 lines (53 loc) · 2.22 KB
/
git.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from functools import reduce
import os
import re
def open_git_log(repository, authors, start_date=None, end_date=None):
'''Open git log for a given repository as a file.
Example:
>>> open_git_log(repository=os.getcwd(), authors=['walterkaunda@live.co.uk'], start_date='2019-05-15', end_date='2019-05-16')\
.readlines()[0]
'commit 8c13c3d2d86aaff65211ee2c9c29ee4b7582784a\\n'
'''
def build_command():
authors_opt = reduce(lambda s, i: f'{s} --author {i}', authors, '')
start_date_opt = start_date and f'--since {start_date}' or ''
end_date_opt = end_date and f'--until {end_date}' or ''
repository_opt = repository and f'-C {repository}' or ''
return f'git {repository_opt} log {authors_opt} {start_date_opt} {end_date_opt} --date iso --date-order --branches'
return os.popen(build_command())
def parse_git_log(log_file, commit_transformer=lambda commit: commit):
'''Parses git commits from a file object.
Example:
>>> log = open_git_log(repository=os.getcwd(), authors=['walterkaunda@live.co.uk'], end_date='2019-05-16')
>>> commit = parse_git_log(log)[0]
>>> commit['id']
'8c13c3d2d86aaff65211ee2c9c29ee4b7582784a'
>>> commit['date']
'2019-05-15 21:20:54 +0200'
>>> commit['author']
'Walter Kaunda <walterkaunda@live.co.uk>'
'''
commits = []
current_commit = {}
for line in log_file:
if line.isspace():
continue
elif line.startswith('commit'):
if current_commit:
commits.append(current_commit)
current_commit = {'body': ''}
_, commit_id = line.split(' ', 1)
current_commit['id'] = commit_id.strip()
elif line.startswith('Author') or line.startswith('Date'):
field, value = re.split(r'\s+', line, 1)
current_commit[field.lower()[:-1]] = value.strip()
else:
body = current_commit.get('body', '')
line = line.lstrip()
current_commit['body'] = f'{body}{line}'
if current_commit:
commits.append(current_commit)
return commits
if __name__ == '__main__':
import doctest
doctest.testmod()