#!/bin/sh

# Script to maintain a (target) tree based on the main kernel
# Author: Amit Kucheria (amit@ubuntu.com)
# Date: 11/07/08

# Assumptions:
#  1. Every rebase during devel-cycle is an ABI bump
#  2. The target tree's patches are always on top
#  3. As a consequence of 2., tags are not really useful
#  4. autogenerated patches are marked with AUTO; others are marked with SAUCE
#  5. Keep things in a state that they can be merged back into the main tree at the end of the dev cycle

targetDir=${1:?"Usage: $0 <target kernel dir> <remote-tag to rebase on>"}
remoteTag=${2:?"Usage: $0 <target kernel dir> <remote-tag to rebase on>"}

rebasing=".git/rebase-apply"

# Configuration variables
release="jaunty"
basever="2.6.28"
patchDir=$targetDir/patches
masterTree=git://zinc.ubuntu.com/ubuntu/ubuntu-$release.git
masterName=ubuntu-$release
baseTag="LPIA-Ubuntu-$basever-0.0"
tmpTag="tmplpia"

remoteBranch=auto-tmp-remote
git=`which git`

mkdir -p $patchDir
cd $targetDir
rm -rf "$rebasing/"

echo "* Check for uncommitted files..."
$git status | grep -q "nothing to commit"
if [ ! $? -eq "0" ]; then
	echo "\tUncommitted changes found!\n\tClean out your tree before running this script. Exiting."
	exit 1;
fi
$git checkout master
$git reset --hard

echo "\n"
echo "* Fetching Ubuntu master tree..."
$git branch -r | grep $masterName
if [ $? -eq "0" ]; then
	echo "\t$masterName is already used as a branch name in your tree. Please change the \$masterName variable in this script."
	exit 1;
fi
$git remote add -f -t master $masterName $masterTree
$git checkout -b $remoteBranch $masterName/master
$git reset --hard $remoteTag
$git checkout master

echo "\n"
echo "* Exporting current work as patches..."
$git format-patch -o $patchDir $baseTag
# Deleting tags is evil...
#$git tag -l | grep "Ubuntu-2.6.2*" | xargs $git tag -d
#$git tag -l | grep "Ubuntu-LPIA-2.6.2*" | xargs $git tag -d
$git tag -d $tmpTag

# Debugging
mkdir -p .patches
cp $patchDir/*.patch .patches
# end Debugging

echo "* Cleaning up patches..."
# Remove auto-generated patches
find $patchDir -type f -name "*UBUNTU-AUTO*" -print0 | xargs -0 rm -f

# Remove updates to debian/control, debian/control.stub and di/kernel-versions
for i in "$patchDir"/*.patch
do
	awk '
		BEGIN						{ on=1 }
		/Subject:/		{ sub("UBUNTU: SAUCE: Ubuntu-2\\.6\\.",
					  "UBUNTU: LPIA-Ubuntu-2.6.", $0); }
		/^diff --git a\/debian\/control /		{ on=0; next }
		/^diff --git a\/debian\/control.stub /		{ on=0; next }
		/^diff --git a\/debian\/d-i\/kernel-versions /	{ on=0; next }
		/^diff /					{ on=1 }
		(on == 1)					{ print }
	' <"$i" >"$i.new"
	mv "$i.new" "$i"
	# If the patch is now empty just remove it.
	if ! grep ^diff "$i"; then
		rm -f "$i"
	fi
done

echo "\n"
echo "* Starting rebase"
$git checkout $remoteBranch

# Disable all git hooks
$git config --bool ubuntu.flavour-changes-ok true
$git config --bool ubuntu.allow-non-sauce-commit true
$git config --bool ubuntu.others-changes-ok true

$git tag -m "Tip of ubuntu git on which we apply patches" $tmpTag

# Tag our base point on the tree.
echo "AUTO #0"
$git commit --allow-empty -s -m "UBUNTU: $baseTag"

# Move debian/ out of the way
echo "AUTO #1"
rm -rf debian-main/
$git mv debian/ debian-main/
$git commit -s -m "UBUNTU: AUTO: Move upstream debian/ dir out of the way for a lpia-specific debian/"
$git status

# Disable all git hooks
$git config --bool ubuntu.flavour-changes-ok true
$git config --bool ubuntu.allow-non-sauce-commit true
$git config --bool ubuntu.others-changes-ok true

# Copy debian-main/ to debian/
echo "AUTO #2"
cp -a debian-main/ debian/
$git add debian/
$git commit -a -s -m "UBUNTU: AUTO: Create a new debian/"
$git status

# Disable all git hooks
$git config --bool ubuntu.flavour-changes-ok true
$git config --bool ubuntu.allow-non-sauce-commit true
$git config --bool ubuntu.others-changes-ok true

# Delete upstream ABI, extra arch/flavours
echo "AUTO #3"
$git rm -r debian/abi/\*
$git rm -r debian/config/\*
$git rm debian/control.d/vars.generic debian/control.d/vars.server
$git rm debian/rules.d/amd64.mk debian/rules.d/i386.mk
$git commit -a -s -m "UBUNTU: AUTO: Delete unncessary ABI/arch/flavours"
$git status

# Disable all git hooks
$git config --bool ubuntu.flavour-changes-ok true
$git config --bool ubuntu.allow-non-sauce-commit true
$git config --bool ubuntu.others-changes-ok true

# Start new changelog
echo "AUTO #4"
$git mv debian/changelog debian/changelog.$release
DEBEMAIL="Ubuntu Kernel Team <kernel-team@lists.ubuntu.com>" \
	EDITOR=: dch --create --package linux-lpia --newversion $basever-0.0

# Need to change timestamp else patches fail -- use the timestamp of the first
# entry from the main changelog.
ts_current=`tail -n1 debian/changelog | sed 's/.*>  \(.*\)$/\1/'`
ts_desired=`tail -n1 debian/changelog.$release | sed 's/.*>  \(.*\)$/\1/'`
sed -i -e "s/${ts_current}/${ts_desired}/" debian/changelog

currAbi=`head -n1 debian/changelog.$release | sed 's/.*('"$basever"'-\(.*\)\..*).*$$/\1/'`
sed -i -e "s/$basever-${currAbi}/$basever-1/g" debian/control.stub
sed -i -e "s/$basever-${currAbi}/$basever-1/g" debian/control
sed -i -e "s/$basever-${currAbi}/$basever-1/g" debian/d-i/kernel-versions
$git add debian/changelog debian/control.stub debian/control debian/d-i/kernel-versions
$git commit -a -s -m "UBUNTU: AUTO: Start new changelog and revert to known abi"
$git status

# Apply pending patches
$git am patches/*
if [ -d "$rebasing/" ]; then
    echo "\tFailed to apply patches"
    echo "\tPlease fix the patches on branch $remoteBranch and then sync to the master branch"
    exit 1;
fi

# Delete tags and recreate them on rebased tree
#git tag | grep LPIA | xargs git tag -d
#git tag -f -s -m $baseTag $baseTag $tmpTag
git tag -d $tmpTag

echo "\n"
echo "If the final result looks good, then do the following to make it permanent:"
echo " * Run debian/scripts/misc/retag-lpia to retag"
echo " * git checkout master"
echo " * git reset --hard $remoteBranch"
echo " * git remote rm $masterName"
echo " * rm -rf patches/"

