#!/bin/bash
#############################################################################
# Copyright (c) 2009 Novell, Inc.
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# 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, contact Novell, Inc.
#
# To contact Novell about this file by physical or electronic mail,
# you may find current contact information at www.novell.com
#############################################################################
#
# Apply the patch series to a linux git repository. Note that the generated
# branch will differ each time, it is only meant as an alternative to quilt
# annotate and friends, it should not be pushed anywhere.
usage()
{
echo "Usage: $0 -g <mainline kernel git> [-b <branch>] [-v] [-f] [-s|-n] [-a] [-X]"
echo "branch is $branch by default"
}
die()
{
echo "$@" >&2
exit 1
}
# perform a git command in linux-2.6 git tree
l_git()
{
(cd "$git"; command git "$@")
}
. scripts/wd-functions.sh
branch="suse/$(get_branch_name)"
if test "$branch" = "suse/"; then
branch="suse/unknown"
fi
git=
verbose=false
force=false
skip=true
use_applied=false
skip_xen=false
last_patch=
. rpm/config.sh
# sles10 doesn't use pristine stable patches
case "$IBS_PROJECT" in
SUSE:SLE-10*)
skip=false
esac
options=$(getopt -n "$0" -o ab:g:vsnS:Xfh --long branch:,git:,verbose,use-applied,force,skip,no-skip,no-xen,symbols:,help -- "$@")
if test $? != 0; then
usage >&2
exit 1
fi
eval set -- "$options"
while test $# -gt 0; do
case "$1" in
-b | --branch)
branch=$2
shift 2
;;
-g | --git)
git=$2
shift 2
;;
-v | --verbose)
verbose=true
shift
;;
-f | --force)
force=true
shift
;;
-a | --use-applied)
use_applied=true
shift
;;
-s | --skip)
skip=true
shift
;;
-n | --no-skip)
skip=false
shift
;;
-X | --no-xen)
skip_xen=true
shift
;;
-S | --symbols)
EXTRA_SYMBOLS=$2
shift 2
;;
-h | --help)
usage
exit 0
;;
--)
shift
break
;;
esac
done
if test $# -gt 0; then
echo "$0: too many arguments"
usage >&2
exit 1
fi
if test -z "$git"; then
usage >&2
exit 1
fi
if [ -s extra-symbols ] ; then
EXTRA_SYMBOLS="$EXTRA_SYMBOLS $(cat extra-symbols)"
fi
if ! $skip; then
base="$SRCVERSION"
else
if test -x rpm/compute-PATCHVERSION.sh; then
base=$("$_")
else
base=$(scripts/compute-PATCHVERSION.sh)
fi
fi
if $use_applied ; then
cur_branch=$(l_git branch | sed -n 's/^\* //p')
if test "$cur_branch" != "$branch"; then
echo "branch is $cur_branch, cannot use current branch"
use_applied=false
fi
fi
if $use_applied ; then
last_patch=$(l_git show | sed -n 's/^ *Patch-name: //p')
if $force ; then
l_git reset --hard
fi
else
args=(--git "$git")
$verbose && args[${#args[@]}]="--verbose"
$force && args[${#args[@]}]="--force"
base_id=$("${0%/*}"/mainline-commit "${args[@]}" "$base") || exit
echo "base is $base (${base_id:0:7})"
# workaround "cannot delete branch which you are currently on" errors
l_git checkout -q HEAD^0 || exit
l_git branch -f "$branch" "$base_id" || exit
l_git checkout "$branch" || exit
fi
tmp=$(mktemp -d /dev/shm/series2git.XXXXXXXX) || exit
trap 'rm -rf "$tmp"' EXIT
ex_hdr()
{
local header=$1
shift
sed -n "s/^$header: *//p; T; q" "$@"
}
apply_patch()
{
local patch=$1
rm -rf "$tmp/backup"
mkdir "$tmp/backup"
patch -d "$git" -s --backup --prefix="$tmp/backup/" -p1 --force -i "$PWD/$patch" || return
l_git add $(find "$tmp/backup" -type f -printf '%P\n')
local from=$(ex_hdr From "$patch")
if test -z "$from"; then
from=$(ex_hdr Author "$patch")
fi
if test -z "$from"; then
from="Unknown Hero <unknown@example.com>"
fi
case "$from" in
*"<"*@*">")
GIT_AUTHOR_NAME=${from% <*}
GIT_AUTHOR_EMAIL="<${from##*<}"
;;
*@*)
GIT_AUTHOR_NAME=${from%%@*}
GIT_AUTHOR_NAME=${GIT_AUTHOR_NAME#<}
GIT_AUTHOR_EMAIL=$from
;;
*)
GIT_AUTHOR_NAME=$from
GIT_AUTHOR_EMAIL=
;;
esac
local subject=$(ex_hdr Subject "$patch" | sed -es'/\[[^]]*\] //')
GIT_AUTHOR_DATE=$(ex_hdr Date "$patch")
GIT_AUTHOR_DATE=$(ex_hdr Date "$patch" \
| perl -p -e 's/(\d\d:\d\d:\d\d) (\d{4})/$2 $1/;s/:$//')
if test -n "$GIT_AUTHOR_DATE"; then
GIT_AUTHOR_DATE=$(date -R -d"$GIT_AUTHOR_DATE" 2>/dev/null)
fi
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
(
echo "$subject"
echo
sed -r '/^(Subject|From|Date):/d; /^(---$|--- |diff |Index:)/ Q' "$patch"
echo
echo "Patch-name: $patch"
) | git stripspace | l_git commit -n -q -F -
}
scripts/guards $EXTRA_SYMBOLS < series.conf | while read patch; do
case "$patch" in
patches.kernel.org/patch-2.6.*.*-rc*)
;;
patches.kernel.org/*)
if $skip; then
echo "skipping $patch"
continue
fi
;;
patches.xen/*)
if $skip_xen; then
echo "skipping remaining Xen patches"
break
fi
;;
esac
if test -n "$last_patch"; then
if test "$patch" != "$last_patch" ; then
echo "skipping $patch"
continue
fi
echo "skipping $patch"
last_patch=
continue
fi
if $verbose; then
echo "[ $patch ]"
fi
apply_patch "$patch" || die "*** $patch failed ***"
if ! $verbose; then
echo -n "."
fi
done
echo
l_git checkout -f