blob: 6daeebafb121c5629e91ea089f7a280a37de4403 (
plain)
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
|
#! /bin/sh
# Copyright (C) 2015 The Qt Company Ltd.
# Contact: http://www.qt.io/licensing/
#
# You may use this file under the terms of the 3-clause BSD license.
# See the file LICENSE from this package for details.
#
force=false
remove=false
while test $# != 0; do
case $1 in
-f) force=true;;
-r) remove=true;;
-*) echo "Unrecognized option $1." >&2; exit 1;;
*) break;;
esac
shift
done
if test -z "$2"; then
cat >&2 <<EOF
Usage: $0 [-f] [-r] <user> <sha-1>...
git-note-review adds Reviewed-by: lines to the log messages of the
named commits. Commits can be specified as either as a single sha1 or
as a sha1_excl..sha1_incl range (see git rev-list).
If any <whatever>-by: tag with the specified <user> is found to be
already present in a given commit, the commit is skipped.
If -f is specified, the check whether the commits were already pushed
is omitted. This only makes sense if you are planning to make a forced
push.
If -r is specified, the named user's reviews are removed from the commits.
EOF
exit 1
fi
GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
if [ -z "$GIT_DIR" ]; then
echo >&2 "Not a git repository."
exit 1
fi
cd "$GIT_DIR/.."
REF=$(git symbolic-ref HEAD 2>/dev/null)
if [ -z "$REF" ]; then
echo >&2 "Not on a branch."
exit 1
fi
if test -n "`git diff HEAD`" ; then
echo "You have uncommited changes. Please commit or stash them first." >&2
exit 1
fi
who=$1
shift
SHA1s=
firstSHA1=
fail=false
for j in "$@"; do
if test -z "${j##*..*}"; then
if ! jj=`git rev-list $j 2> /dev/null`; then
echo "Cannot parse commit range $j." >&2
fail=true
continue
fi
j=$jj
fi
for ii in $j; do
if ! i=`git rev-parse --short $ii 2> /dev/null`; then
echo "Cannot parse commit id $ii." >&2
fail=true
continue
fi
if test -n "`git rev-list -1 $i ^HEAD`"; then
echo "Commit $i is not on current branch. Did you rebase it meanwhile?" >&2
fail=true
continue
fi
git log -1 --pretty=%b $i | egrep -q -i "^[-[:alpha:]]+-by: *$who\$" && hit=true || hit=false
if $hit && ! $remove; then
echo "Commit $i already noted as reviewed by $who."
elif ! $hit && $remove; then
echo "Commit $i not noted as reviewed by $who."
else
if test -z "$firstSHA1"; then
firstSHA1=`git rev-parse $i`
SHA1s=$i
else
firstSHA1=`git merge-base $firstSHA1 $i`
SHA1s="$SHA1s|$i"
fi
fi
done
done
if $fail; then
echo "Exiting due to fatal errors." >&2
exit 1
fi
if test -z "$SHA1s"; then
echo "No commits to change." >&2
exit 0
fi
# This would be pretty much bullet-proof, but also a lot slower.
#if test -z "$(git rev-list -1 $firstSHA1 --not $(git for-each-ref --format='%(objectname)' refs/remotes/))"; then
# echo "$firstSHA1 has already been pushed - cannot edit it." >&2
# exit 1
#fi
# This should be Good Enough (TM), and it is rather fast.
if ! $force && test -n "$(git rev-list -1 $firstSHA1^..@{upstream})"; then
echo "Commit `git rev-parse --short $firstSHA1` has already been pushed - cannot edit it." >&2
exit 1
fi
if ! $remove; then
script='s/^\\(Reviewed-by:\\) *\\(pending\\|tbd\\|TBD\\)\$/\\1 '"$who"'/;t nx
\${
/^[-[:alpha:]]\+:/!a\\
a\\
Reviewed-by: '"$who"'
}
b
:nx;n;b nx'
else
script='/^[-[:alpha:]]\\+-by: *'"$who"'\$/d'
fi
git filter-branch --force --original refs/note-review-backup --msg-filter '
if echo $GIT_COMMIT | egrep -q "^('"$SHA1s"')"; then
sed "'"$script"'"
else
cat
fi
' $firstSHA1^..$REF || exit 1
rm -rf $GIT_DIR/refs/note-review-backup # we have the reflog, so what
|