#!/bin/sh

# patch2quilt
# Copyright (c) 2011, Frank Terbeck <ft@bewatermyfriend.org>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# Often, we may want to backport a patch from upstream to our package. If
# that's just a matter of cherry-picking a patch from upstream, this script can
# help. We don't really want to git cherry-pick, but rather add a new patch to
# our quilt series. In short, this script automates doing that.
#
# Call it like this:
#   % ./debian/patch2quilt ../0000-git-patch.patch 0010-quilt-patch.diff
#
# Where `../0000-git-patch.patch' is a patch from git; `0010-quilt-patch.diff'
# is the to-be-added quilt patch. The script now does this:
#
#  - Reset and clean the repository to a clean state.
#  - Push the entire quilt series.
#  - Add `0010-quilt-patch.diff' as a new patch in the quilt series.
#  - Check which files are touched by `../0000-git-patch.patch' and add those
#    to the newly added quilt patch.
#  - Apply the git patch.
#  - Refresh the quilt patch.
#  - Pop the entire quilt series again.
#  - Open the new quilt patch in ${VISUAL:-${EDITOR:-vi}} to add annotation.
#
# That's all.
#
# Note: If the patch file is located in the current repository, it will be
#       deleted when the repository is cleaned up initially. So don't do that.
#
#       Also, if we're just cherry picking stuff from upstream git, there are
#       likely changes to ChangeLog, which will not apply cleanly. Just throw
#       away all such hunks from the patch beforehand.
#
# `patch2quilt' requires `quilt', `git' and `diffstat' available.
#
# Call this script *only* from the git repository's base directory.

QUILT_PATCHES=debian/patches
export QUILT_PATCHES

if [ ! -d "${QUILT_PATCHES}" ]; then
    printf 'No such directory: `%s'\''\n' "${QUILT_PATCHES}"
    printf 'Quilt patches directory not found. Giving up.\n'
    exit 1
fi

if [ $# -ne 2 ]; then
    printf 'usage: patch2quilt <git-patch> <quilt-patch>\n'
    exit 1
fi

gitpatch="$1"
quiltpatch="$2"

git clean -xdf || exit 1
git reset --hard || exit 1

quilt push -a || exit 1

quilt new "${quiltpatch}" || exit 1

diffstat -l -p1 "${gitpatch}" | while IFS= read -r file; do
    quilt add "${file}" || exit 1
done

git apply "${gitpatch}" || exit 1

quilt refresh || exit 1

quilt pop -a || exit 1

${VISUAL:-${EDITOR:-vi}} "${QUILT_PATCHES}/${quiltpatch}"

printf -- '\n---------------------------------------'
printf -- '---------------------------------------\n'
printf '\n  New quilt patch `%s'\'' added.  You\n' "${quiltpatch}"
printf '  should add it and its series file to git and commit the result.\n'
printf '\n  Like this:\n\n'
printf '    %% git add "%s"\n' "${QUILT_PATCHES}/series"
printf '    %% git add "%s"\n' "${QUILT_PATCHES}/${quiltpatch}"
printf '    %% git commit\n'
printf '\n  Write a useful commit message.'
printf '  Don'\''t forget `Closes:'\'' mentions!\n\n'

exit 0
