/
git-rewrite-author
executable file
·140 lines (91 loc) · 3.84 KB
/
git-rewrite-author
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env python
"""Rewrite author/committer history of a git repository
Have you ever accidentally committed to a git repository with a broken
user config? No? But your co-workers have?
So, you're stuck with commits like this::
Author: root <root@localhost>
Hotfix on the production server. This was urgent!
Nasty. Or::
Author: John Doe <john@localhost>
Fixed bug #1. Committed on my laptop.
Would it be nice to rewrite history? And take care of committers, as
well as of authors? Without all the hassle? Now, you can!
Usage::
$ git rewrite-author -w "John Doe <john@localhost>" "John Doe <dearjohn@example.com>"
Then, to push your changes to the default remote::
$ git push --force
Not using --force may duplicate the commits on origin, not replace them, so be careful with that.
You're not sure which authors/committers are hidden in your repository?
What about::
$ git rewrite-author -l
Tags are rewritten automagically, too!
Enjoy!
Installation
------------
Clone or download this repository and run::
$ python setup.py install
"""
import argparse
import re
import subprocess
import textwrap
description = "Rewrite author/committer in git history"
epilog = """
Example:
$ git-rewrite-author -w "Name <me@localhost>" "Full Name <me@example.com>"
"""
git_rewrite_command = """git filter-branch --env-filter '
if [ "$GIT_AUTHOR_NAME" = "%(old_name)s" -a "$GIT_AUTHOR_EMAIL" = "%(old_email)s" ]; then
export GIT_AUTHOR_NAME="%(new_name)s";
export GIT_AUTHOR_EMAIL="%(new_email)s";
fi;
' --tag-name-filter cat -f -- --all"""
git_log_command = "git log --pretty=full"
def parse_args():
"""Parse command-line arguments"""
parser = argparse.ArgumentParser(description=description,
epilog=epilog,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('-l', '--list', action='store_true',
help="List all authors and committers")
parser.add_argument('-w', '--rewrite', nargs=2,
metavar=('old', 'new'), type=str,
help="Rewrite authors and committers")
return parser.parse_args()
def main(args):
"""Rewrite history using args"""
if args.list:
list_git_authors()
elif args.rewrite:
old_name, old_email = parse_author_arg(args.rewrite[0])
new_name, new_email = parse_author_arg(args.rewrite[1])
rewrite_git_author(old_name, old_email, new_name, new_email)
rewrite_git_committer(old_name, old_email, new_name, new_email)
else:
print("Doing nothing. Invoke with -h for help.")
def parse_author_arg(arg):
"""Parse name/email argument"""
name, email = re.match("(.+)\s<(.*)>", arg).groups()
return name, email
def rewrite_git_author(old_name, old_email, new_name, new_email):
"""Rewrite author history in git"""
command = git_rewrite_command % \
{ 'old_name': old_name, 'old_email': old_email, 'new_name': new_name, 'new_email': new_email}
subprocess.call(command, shell=True)
def rewrite_git_committer(old_name, old_email, new_name, new_email):
"""Rewrite committer history in git"""
command = git_rewrite_command.replace('AUTHOR', 'COMMITTER') % \
{ 'old_name': old_name, 'old_email': old_email, 'new_name': new_name, 'new_email': new_email}
subprocess.call(command, shell=True)
def list_git_authors():
"""List authors and committers"""
output = subprocess.check_output(git_log_command.split(' '))
matches = re.findall(b'(Author|Commit): (.*)\n', output)
names = [u[1].decode('utf-8') for u in matches]
unique_names = sorted(set(names))
print("The following authors and committers have contributed:\n")
for name in unique_names:
print(name)
if __name__ == '__main__':
args = parse_args()
main(args)