#!/bin/bash # Finds commits with a review tag ("R=foo@example.com") and adds them as # gerrit reviewer. # # Author: Peter Wu # http://stackoverflow.com/q/24576855/427545 # # Requirements: git, awk, ssh, bash cd "$(git rev-parse --show-toplevel)" user= host= port=29418 project= # Load host from gitreview file if any [ ! -f .gitreview ] || eval $(awk -F= ' $1 == "host" && $2 ~ /^[a-zA-Z0-9][a-zA-Z0-9.-]*$/ { print "host=" $2 } $1 == "port" && $2 ~ /^[0-9]{1,5}$/ { print "port=" $2 } $1 == "project" && $2 ~ /^[a-zA-Z0-9._][a-zA-Z0-9._-]*$/ { print "project=" $2 } ' .gitreview) # Load settings from git config eval $(git remote -v show -n | awk -vorighost=$host '/fetch\)$/ && $2 ~ /^ssh:/ { split($2, url, /[/:@]+/); # Apply settings on first result, or if the host matches if (!got_one || orighost == url[3]) { if (url[2] ~ /^[a-zA-Z0-9][a-zA-Z0-9.-]*$/) print "user=" url[2]; if (url[3] ~ /^[a-zA-Z0-9][a-zA-Z0-9.-]*$/) print "host=" url[3]; if (url[4] ~ /^[0-9]{1,5}$/) print "port=" url[4]; got_one = 1; } }') find_reviewers() { local commit=$1 git show --no-patch --format=%b "$commit" | awk -F= '/^R=[a-zA-Z0-9@._+-]+$/ { print $2 }' } set_reviewer() { local cmd reviewer local commit=$1 # Commit or Change-Id shift # Remaining arguments: reviewers # https://review.openstack.org/Documentation/cmd-set-reviewers.html cmd='gerrit set-reviewers' [ -z "$project" ] || cmd="$cmd --project $project" for reviewer; do cmd="$cmd -a $reviewer" done cmd="$cmd -- $commit" echo "$cmd" >&2 ssh -p $port "$user@$host" "$cmd" } check_commits() { local revlist=$1 commits count=0 retval=0 # One is not going to push that many commits/reviews at a time... commits="$(git rev-list --reverse --max-count=100 $revlist --)" || return 1 if [ -z "$commits" ]; then echo "No commits found" >&2 return 1 fi for commit in $commits; do reviewers=$(find_reviewers $commit) if [ -n "$reviewers" ]; then echo "Adding reviewers for $commit..." >&2 if ! set_reviewer $commit $reviewers; then echo >&2 echo "Run 'git review' if you get a 'no such change' error" >&2 retval=1 break fi ((count++)) fi done printf 'Touched %d commits' $count >&2 if [ $retval -eq 0 ]; then echo . >&2 else echo ", but stopped due to an error" >&2 fi return $retval } if [ -z "$user" ] || [ -z "$host" ]; then echo "Warning: gerrit is not configured" >&2 exit 1 fi case ${0##*/} in post-review) # TODO # maybe read https://review.openstack.org/Documentation/cmd-query.html # if pre: # create temp file with possibly unprocessed commits echo "$0: Not implemented" >&2 ;; pre-review) # TODO # elif post: # read temp file # for each reviewer in temp file: # ssh user@host -p port 'gerrit command to set reviewer' echo "$0: Not implemented" >&2 ;; *) if [[ $1 == *..* ]]; then check_commits "$1" else echo "Usage: $0 " >&2 echo "To review changes on this branch since master: $0 master.." >&2 exit 1 fi ;; esac