blob: a8e5666b4b1c3b77d5359ec8e7a188b9827a98ba [file] [log] [blame]
#!/bin/sh
set -e
usage()
{
cat <<EOUSAGE
Usage: git-if-needed command /path/to/file.patch
git-if-needed [-S] -s /path/to/series command
Options:
-S short paths: only use the last component of the patch path
-s series file: apply all the patches in that file
Examples:
git if-needed am /path/to/local.patch
git if-needed -s /path/to/many-patches/series am
EOUSAGE
}
apply_single()
{
local cmd="$1" fname="$2"
if [ ! -e "$fname" ] || [ ! -f "$fname" ] || [ ! -r "$fname" ]; then
echo "Not a readable regular file: $fname" 1>&2
exit 1
fi
local chgid=''
chgid="$(awk -- '/^[[:space:]]*Change-Id:[[:space:]]+I[0-9a-f]+$/ { print $2 }' "$fname")"
if ! expr "x$chgid" : 'xI[0-9a-f][0-9a-f]*$' > /dev/null; then
echo "Expected a single Change-Id line in $fname" 1>&2
exit 1
fi
if git --no-pager log | grep -Eqe "^[[:space:]]+Change-Id:[[:space:]]+${chgid}\$"; then
echo "# Change $chgid already present in the Git history"
elif git --no-pager "$cmd" -- "$fname"; then
echo "# 'git $cmd $fname' succeeded"
else
echo "# 'git $cmd $fname' failed"
git --no-pager status || echo "# 'git status' also failed"
exit 1
fi
}
apply_series()
{
local cmd="$1" series="$2" short="$3"
series="$(readlink -f -- "$series")"
series_dir="$(dirname -- "$series")"
curdir="$(readlink -f .)"
while read -r filename; do
dirname="$(dirname -- "$filename")"
if [ -n "$short" ]; then
dirname="$(basename -- "$dirname")"
fi
cd -- "$dirname"
apply_single "$cmd" "$series_dir/$filename"
cd -- "$curdir"
done < "$series"
}
unset series short
while getopts 'Ss:' o; do
case "$o" in
S)
short=1
;;
s)
series="$OPTARG"
;;
*)
usage 1>&2
exit 1
;;
esac
done
shift "$((OPTIND - 1))"
if [ -n "$series" ]; then
if [ "$#" -ne 1 ]; then
usage 1>&2
exit 1
fi
cmd="$1"
apply_series "$cmd" "$series" "$short"
exit 0
fi
if [ "$#" -ne 2 ]; then
usage 1>&2
exit 1
fi
cmd="$1"
fname="$2"
apply_single "$cmd" "$fname"