-
Notifications
You must be signed in to change notification settings - Fork 1
/
git-coauthor
executable file
·162 lines (131 loc) · 3.25 KB
/
git-coauthor
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/bin/bash
#
# A git porcelain to add co-authored-by trailers to git commits
# and manage a database of authors.
#
# I live at https://github.com/simoleone/git-coauthor
readonly COMMIT_TEMPLATE="${HOME}/.git_coauthor_commit_template"
function err() {
echo "$@" >&2
}
function author_create() {
local -r author="$1"
if author_exact_match "${author}"; then
err "author already exists"
return 1
fi
git config --global --add coauthor.author "${author}"
}
function author_delete() {
local -r query="$1"
local full_author
full_author="$(author_match "${query}")"
[[ $? -eq 0 ]] || { err "no authors deleted" && return 1; }
git config --global --unset-all coauthor.author "${full_author}"
}
function author_list() {
git config --global --get-all coauthor.author
}
function author_exact_match() {
local -r query="$1"
author_list | grep -i -m 1 -E "^${query}$"
return $?
}
function author_match() {
local -r query="$1"
local match
local pattern
if [[ -z "${query}" ]]; then
# empty query no good
return 1
elif [[ "${#query}" -eq 2 ]]; then
# match on author's initials
local -r first_initial="${query:0:1}"
local -r second_initial="${query:1:1}"
pattern="^${first_initial}.* ${second_initial}"
else
# just try to match something
# preference to lines that start with the query
pattern="^${query}|${query}"
fi
match="$(author_list | grep -i -m 1 -E "${pattern}")"
[[ $? -eq 0 ]] || { err "no author matched: ${query}" && return 1; }
echo "${match}"
return 0
}
function setup_pair() {
local commit_template
commit_template=""
for i in "$@"; do
local full_author
full_author="$(author_match "$i")"
[[ $? -eq 0 ]] || { err "could not set up pair" && return 1; }
commit_template="${commit_template}\nCo-authored-by: ${full_author}"
done
commit_template="$(echo -e "${commit_template}" | sort)"
echo -e "\n${commit_template}" > "${COMMIT_TEMPLATE}"
git config --global commit.template "${COMMIT_TEMPLATE}"
display_current
}
function solo() {
echo "" > "${COMMIT_TEMPLATE}"
git config --global --unset commit.template
echo "now committing solo"
}
function display_current() {
local -r authors="$(grep 'Co-authored-by:' "${COMMIT_TEMPLATE}" 2>/dev/null | cut -d':' -f2)"
echo "CURRENT CO-AUTHORS"
if [[ -z "${authors}" ]]; then
echo "You're committing solo!"
else
echo "${authors}"
fi
}
function usage(){
cat <<EOF
Usage
git coauthor
display current coauthors and this usage message
git coauthor <initials or name> ...
set current co-authors to developers with matching initials or names
git coauthor --solo
remove current co-authors and go solo
git coauthor --add "Jane Smith <jane@example.com>"
add a new author to the database
git coauthor --ls
list all authors in the database
git coauthor --rm <initials or name>
remove author with matching initials or name from the database
EOF
}
function main() {
local -r cmd="$1"
case "${cmd}" in
--add)
shift
author_create "$*"
;;
--ls)
author_list
;;
--rm)
shift
author_delete "$*"
;;
--help|-h)
usage
exit 1
;;
--solo)
solo
;;
'')
usage
display_current
;;
*)
setup_pair "$@"
;;
esac
}
main "$@"