#!/bin/bash
# Simple shell script for importing a collection of Debian source packages
# into a git repository.
#
# Copyright(C) 2007, Ron <ron@debian.org>
# This script is distributed according to the terms of the GNU GPL.

set -e

UPSTREAM_BRANCH="upstream"
DEBIAN_BRANCH="master"

UPSTREAM_TAG_PREFIX="v"
DEBIAN_TAG_PREFIX="v"

# We default to the linux kernel style tags, but people who prefer the
# git-buildpackage style and like slashes in their tags can do this:
#UPSTREAM_TAG_PREFIX="$UPSTREAM_BRANCH/"
#DEBIAN_TAG_PREFIX="debian/"


usage()
{
    cat 1>&2 <<EOF

git-debimport path-prefix

 This program will take all files that match \${path-prefix}_*.diff.gz, and the
 list of corresponding orig.tar.gz files, and create a git repository from them.

  For example:
  $ mkdir mydestdir && cd mydestdir
  $ git-debimport ../mysrcdir/mypackagename

EOF

    exit $1
}

# This function replaces all consecutive illegal constructs in a git refname
# with a single '_'.  The rules for git refnames are described in the manual
# page for git-check-ref-format(1).
sanitise_git_ref()
{
    (
	shopt -s extglob

	ref="${1//\/.//_}"				# rule 1.
	ref="${ref//../_}"				# rule 2.
	ref="${ref//[[:cntrl:][:space:]:~^?*[]/_}"	# rule 3.
	ref="${ref%%+(/)}"				# rule 4.
	ref="${ref//+(_)_/_}"

	echo "$ref"
    )
}


[ $# -gt 0 ] && [ $# -lt 2 ] || usage 1


PACKAGES_DIR="${1%/*}"
PACKAGE_NAME="${1##*/}"
PACKAGE_DIFFS="$(find $PACKAGES_DIR -type f -name ${PACKAGE_NAME}_*.diff.gz | sort)"
CACHE_DIR="../${PACKAGE_NAME}-import-cache"

if [ -z "$PACKAGE_DIFFS" ]; then
    echo "No ${1}_*.diff.gz files found, aborting."
    exit 1
fi

if [ -e "$PACKAGE_NAME" ]; then
    echo "A $PACKAGE_NAME dir already exists, please (re)move it first"
    exit 1
fi

mkdir "$PACKAGE_NAME"
cd "$PACKAGE_NAME"
git init

for f in $PACKAGE_DIFFS; do

    DEBIAN_VERSION="${f%.diff.gz}"
    DEBIAN_VERSION="${DEBIAN_VERSION##*_}"
    UPSTREAM_VERSION="${DEBIAN_VERSION%-*}"

    if [ -z "$LAST_UPSTREAM_VERSION" ]; then
    	echo "Initial import of $PACKAGES_DIR/${PACKAGE_NAME}_${UPSTREAM_VERSION}.orig.tar.gz"

	rm -rf "$CACHE_DIR"
	mkdir -p "$CACHE_DIR/${PACKAGE_NAME}-${UPSTREAM_VERSION}.orig"
	tar -xf "../$PACKAGES_DIR/${PACKAGE_NAME}_${UPSTREAM_VERSION}.orig.tar.gz" \
	     -C "$CACHE_DIR/${PACKAGE_NAME}-${UPSTREAM_VERSION}.orig" --strip 1
	for i in $(ls -A "$CACHE_DIR/${PACKAGE_NAME}-${UPSTREAM_VERSION}.orig"); do
	    cp -al "$CACHE_DIR/${PACKAGE_NAME}-${UPSTREAM_VERSION}.orig/$i" .
	done

	DATE=$(file -L ../$PACKAGES_DIR/${PACKAGE_NAME}_${UPSTREAM_VERSION}.orig.tar.gz | sed -n "s/.*, last modified: \([^,]*\),*.*/\1/p")

	git add .
	GIT_AUTHOR_DATE="$DATE" GIT_COMMITTER_DATE="$DATE" \
	    git commit -a -m "git-debimport ${PACKAGE_NAME}_${UPSTREAM_VERSION}.orig.tar.gz"
	git checkout -b "$UPSTREAM_BRANCH"
	git tag $(sanitise_git_ref "$UPSTREAM_TAG_PREFIX$UPSTREAM_VERSION")

	LAST_UPSTREAM_VERSION="$UPSTREAM_VERSION"
    fi

    if [ "$LAST_UPSTREAM_VERSION" != "$UPSTREAM_VERSION" ]; then
    	echo "Importing $PACKAGES_DIR/${PACKAGE_NAME}_${UPSTREAM_VERSION}.orig.tar.gz"

	git checkout "$UPSTREAM_BRANCH"
	for i in $(ls -A); do
	    if [ "$i" != ".git" ]; then rm -rf $i; fi
	done

	rm -rf "$CACHE_DIR"
	mkdir -p "$CACHE_DIR/${PACKAGE_NAME}-${UPSTREAM_VERSION}.orig"
	tar -xf "../$PACKAGES_DIR/${PACKAGE_NAME}_${UPSTREAM_VERSION}.orig.tar.gz" \
	     -C "$CACHE_DIR/${PACKAGE_NAME}-${UPSTREAM_VERSION}.orig" --strip 1
	for i in $(ls -A "$CACHE_DIR/${PACKAGE_NAME}-${UPSTREAM_VERSION}.orig"); do
	    cp -al "$CACHE_DIR/${PACKAGE_NAME}-${UPSTREAM_VERSION}.orig/$i" .
	done

	DATE=$(file -L ../$PACKAGES_DIR/${PACKAGE_NAME}_${UPSTREAM_VERSION}.orig.tar.gz | sed -n "s/.*, last modified: \([^,]*\),*.*/\1/p")

	git add .
	GIT_AUTHOR_DATE="$DATE" GIT_COMMITTER_DATE="$DATE" \
	    git commit -a -m "git-debimport ${PACKAGE_NAME}_${UPSTREAM_VERSION}.orig.tar.gz"
	git tag $(sanitise_git_ref "$UPSTREAM_TAG_PREFIX$UPSTREAM_VERSION")

	LAST_UPSTREAM_VERSION="$UPSTREAM_VERSION"
    fi

    echo "Importing $f"

    git checkout "$DEBIAN_BRANCH"
    for i in $(ls -A); do
	if [ "$i" != ".git" ]; then rm -rf $i; fi
    done

    for i in $(ls -A "$CACHE_DIR/${PACKAGE_NAME}-${UPSTREAM_VERSION}.orig"); do
	cp -al "$CACHE_DIR/${PACKAGE_NAME}-${UPSTREAM_VERSION}.orig/$i" .
    done
    zcat "../$f" | patch -p1
    chmod 755 debian/rules

    DATE=$(dpkg-parsechangelog | sed -n 's/Date: //p')
    AUTHOR=$(dpkg-parsechangelog | sed -n 's/Maintainer: //p' | cut -d\< -f1)
    EMAIL=\<$(dpkg-parsechangelog | sed -n 's/Maintainer: //p' | cut -d\< -f2)

    git add .
    GIT_AUTHOR_NAME="$AUTHOR" GIT_COMMITTER_NAME="$AUTHOR" \
    GIT_AUTHOR_EMAIL="$EMAIL" GIT_COMMITTER_EMAIL="$EMAIL" \
    GIT_AUTHOR_DATE="$DATE" GIT_COMMITTER_DATE="$DATE" \
	git commit -a -m "git-debimport ${PACKAGE_NAME}_${DEBIAN_VERSION}.diff.gz"
    git tag $(sanitise_git_ref "$DEBIAN_TAG_PREFIX$DEBIAN_VERSION")

done

rm -rf "$CACHE_DIR"
git merge -s ours "$UPSTREAM_BRANCH"

echo "All done!"

