3 # Copyright (C) 2009 Google Inc.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 # To set user mappings, use this command:
21 # git config gnt-review.johndoe 'John Doe <johndoe@domain.tld>'
23 # To disable strict mode (enabled by default):
24 # git config gnt-review.strict false
26 # To enable strict mode:
27 # git config gnt-review.strict true
31 # Get absolute path to myself
33 me=$(readlink -f "$me_plain")
38 grep -q '^Reviewed-by: ' "$msgfile" && return
43 if ($sob == 0 and m/^Signed-off-by:/) {
46 } elsif ($sob == 1 and not m/^Signed-off-by:/) {
47 print "Reviewed-by: \n";
55 print "Reviewed-by: \n";
73 return $name unless $name;
75 my @cmd = ("git", "config", "--get", "gnt-review.$name");
77 open(my $fh, "-|", @cmd) or die "Command \"@cmd\" failed: $!";
78 my $output = do { local $/ = undef; <$fh> };
87 unless (defined $strict) {
88 @cmd = ("git", "config", "--get", "--bool", "gnt-review.strict");
90 open($fh, "-|", @cmd) or die "Command \"@cmd\" failed: $!";
91 $output = do { local $/ = undef; <$fh> };
94 $strict = ($? != 0 or not $output or $output !~ m/^false$/);
97 if ($strict and $name !~ m/^.+<.+\@.+>$/) {
105 if (m/^Reviewed-by:(.*)$/) {
107 # Ignore empty entries
110 # Normalize whitespace
111 $_ =~ s/(^\s+|\s+$)//g;
115 $_ = map_username($_);
122 @names = grep(!$saw{$_}++, @names);
125 foreach (sort @names) {
126 print "Reviewed-by: $_\n";
133 exit($error? 33 : 0);
138 [[ "$?" == 33 ]] && return 1
142 if ! grep -q '^Reviewed-by: ' "$msgfile"
144 echo 'Missing Reviewed-by: line' >&2
154 local editor=${EDITOR:-vi}
157 case "$(basename "$editor")" in
159 # Start edit mode at Reviewed-by: line
160 args='+/^Reviewed-by: +nohlsearch +startinsert!'
167 $editor $args "$filename"
174 trap "rm -f $tmpf" EXIT
176 cp "$msgfile" "$tmpf"
180 add_reviewed_by "$tmpf"
184 replace_users "$tmpf" && break
187 cp "$tmpf" "$msgfile"
191 local rev="$1" target_branch="$2"
193 echo "Copying commit $rev ..."
195 git cherry-pick -n "$rev"
196 GIT_EDITOR="$me --commit-editor \"\$@\"" git commit -c "$rev" -s
200 local range="$1" target_branch="$2"
202 if [[ -z "$target_branch" || "$range" != *..* ]]
204 echo "Usage: $me_plain <from..to> <target-branch>" >&2
208 git checkout "$target_branch"
209 local old_head=$(git rev-parse HEAD)
211 for rev in $(git rev-list --reverse "$range")
216 git log "$old_head..$target_branch"
219 if [[ "$1" == --commit-editor ]]