Commit 42c067b7 authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Add review script



I've been using this script for a while to update commits before
pushing them to the main repository. It copies all commits in a
range to another branch using git cherry-pick and starts an editor
to modify the Reviewed-by: line(s) for each commit. The script is
certainly not perfect, but it does the job.
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent 4007f57d
#!/bin/bash
# Copyright (C) 2009 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# To set user mappings, use this command:
# git config gnt-review.johndoe 'John Doe <johndoe@domain.tld>'
set -e
# Get absolute path to myself
me_plain="$0"
me=$(readlink -f "$me_plain")
add_reviewed_by() {
local msgfile="$1"
grep -q '^Reviewed-by: ' "$msgfile" && return
perl -i -e '
my $sob = 0;
while (<>) {
if ($sob == 0 and m/^Signed-off-by:/) {
$sob = 1;
} elsif ($sob == 1 and not m/^Signed-off-by:/) {
print "Reviewed-by: \n";
$sob = -1;
}
print;
}
if ($sob == 1) {
print "Reviewed-by: \n";
}
' "$msgfile"
}
replace_users() {
local msgfile="$1"
perl -i -e '
sub map_username {
my ($name) = @_;
return $name unless $name;
my @cmd = ("git", "config", "--get", "gnt-review.$name");
open(my $fh, "-|", @cmd) or die "Command \"@cmd\" failed: $!";
my $output = do { local $/ = undef; <$fh> };
close($fh);
if ($? == 0) {
chomp $output;
$output =~ s/\s+/ /;
return $output;
}
return $name;
}
while (<>) {
if (m/^Reviewed-by:(.*)$/) {
my @names = grep {
# Ignore empty entries
!/^$/
} map {
# Normalize whitespace
$_ =~ s/(^\s+|\s+$)//g;
$_ =~ s/\s+/ /g;
# Map names
$_ = map_username($_);
$_;
} split(m/,/, $1);
foreach (sort @names) {
print "Reviewed-by: $_\n";
}
} else {
print;
}
}
' "$msgfile"
if ! grep -q '^Reviewed-by: ' "$msgfile"
then
echo 'Missing Reviewed-by: line' >&2
sleep 1
return 1
fi
return 0
}
run_editor() {
local filename="$1"
local editor=${EDITOR:-vi}
local args
case "$(basename "$editor")" in
vi* | *vim)
# Start edit mode at Reviewed-by: line
args='+/^Reviewed-by: +nohlsearch +startinsert!'
;;
*)
args=
;;
esac
$editor $args "$filename"
}
commit_editor() {
local msgfile="$1"
local tmpf=$(mktemp)
trap "rm -f $tmpf" EXIT
cp "$msgfile" "$tmpf"
while :
do
add_reviewed_by "$tmpf"
run_editor "$tmpf"
replace_users "$tmpf" && break
done
cp "$tmpf" "$msgfile"
}
copy_commit() {
local rev="$1" target_branch="$2"
echo "Copying commit $rev ..."
git cherry-pick -n "$rev"
GIT_EDITOR="$me --commit-editor \"\$@\"" git commit -c "$rev" -s
}
main() {
local range="$1" target_branch="$2"
if [[ -z "$target_branch" || "$range" != *..* ]]
then
echo "Usage: $me_plain <from..to> <target-branch>" >&2
exit 1
fi
git checkout "$target_branch"
local old_head=$(git rev-parse HEAD)
for rev in $(git rev-list --reverse "$range")
do
copy_commit "$rev"
done
git log "$old_head..$target_branch"
}
if [[ "$1" == --commit-editor ]]
then
shift
commit_editor "$@"
else
main "$@"
fi
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment