Revision control

++ #! /bin/sh
++ # Copyright (C) 2015 The Qt Company Ltd.
++ #
++ # 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