Migrate git eclasses to eclass-overlay

Multiple copies of these eclasses exist between portage-stable and
chromiumos-overlay. We want to move them here so that only one version
of these eclasses is ever used and needs to be maintained.

All three eclasses were taken from portage-stable. git-2.eclass was
amended to allow EAPI 6 for this migration, as the version in
chromiumos-overlay did not have this restriction.

BUG=chromium:989082
TEST=precq

Cq-Depend: chrome-internal:1549011
Change-Id: I66a115ff549ebe9b6d61b18029c8a5431e802d2e
Reviewed-on: https://chromium-review.googlesource.com/1725151
Tested-by: Chris McDonald <cjmcdonald@chromium.org>
Commit-Ready: Chris McDonald <cjmcdonald@chromium.org>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/eclass/git-2.eclass b/eclass/git-2.eclass
new file mode 100644
index 0000000..34a5527
--- /dev/null
+++ b/eclass/git-2.eclass
@@ -0,0 +1,602 @@
+# Copyright 1999-2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: git-2.eclass
+# @MAINTAINER:
+# maintainer-needed@gentoo.org
+# @BLURB: Eclass for fetching and unpacking git repositories.
+# @DESCRIPTION:
+# Eclass for easing maintenance of live ebuilds using git as remote repository.
+# Eclass support working with git submodules and branching.
+#
+# This eclass is DEPRECATED. Please use git-r3 instead.
+
+# This eclass support all EAPIs.
+EXPORT_FUNCTIONS src_unpack
+
+DEPEND="dev-vcs/git"
+
+# @ECLASS-VARIABLE: EGIT_SOURCEDIR
+# @DESCRIPTION:
+# This variable specifies destination where the cloned
+# data are copied to.
+#
+# EGIT_SOURCEDIR="${S}"
+
+# @ECLASS-VARIABLE: EGIT_STORE_DIR
+# @DESCRIPTION:
+# Storage directory for git sources.
+#
+# EGIT_STORE_DIR="${DISTDIR}/egit-src"
+
+# @ECLASS-VARIABLE: EGIT_HAS_SUBMODULES
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If non-empty this variable enables support for git submodules in our
+# checkout. Also this makes the checkout to be non-bare for now.
+
+# @ECLASS-VARIABLE: EGIT_OPTIONS
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Variable specifying additional options for fetch command.
+
+# @ECLASS-VARIABLE: EGIT_MASTER
+# @DESCRIPTION:
+# Variable for specifying master branch.
+# Useful when upstream don't have master branch or name it differently.
+#
+# EGIT_MASTER="master"
+
+# @ECLASS-VARIABLE: EGIT_PROJECT
+# @DESCRIPTION:
+# Variable specifying name for the folder where we check out the git
+# repository. Value of this variable should be unique in the
+# EGIT_STORE_DIR as otherwise you would override another repository.
+#
+# EGIT_PROJECT="${EGIT_REPO_URI##*/}"
+
+# @ECLASS-VARIABLE: EGIT_DIR
+# @DESCRIPTION:
+# Directory where we want to store the git data.
+# This variable should not be overridden.
+#
+# EGIT_DIR="${EGIT_STORE_DIR}/${EGIT_PROJECT}"
+
+# @ECLASS-VARIABLE: EGIT_REPO_URI
+# @REQUIRED
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# URI for the repository
+# e.g. http://foo, git://bar
+#
+# It can be overridden via env using packagename_LIVE_REPO
+# variable.
+#
+# Support multiple values:
+# EGIT_REPO_URI="git://a/b.git http://c/d.git"
+
+# @ECLASS-VARIABLE: EVCS_OFFLINE
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If non-empty this variable prevents performance of any online
+# operations.
+
+# @ECLASS-VARIABLE: EGIT_BRANCH
+# @DESCRIPTION:
+# Variable containing branch name we want to check out.
+# It can be overridden via env using packagename_LIVE_BRANCH
+# variable.
+#
+# EGIT_BRANCH="${EGIT_MASTER}"
+
+# @ECLASS-VARIABLE: EGIT_COMMIT
+# @DESCRIPTION:
+# Variable containing commit hash/tag we want to check out.
+# It can be overridden via env using packagename_LIVE_COMMIT
+# variable.
+#
+# EGIT_COMMIT="${EGIT_BRANCH}"
+
+# @ECLASS-VARIABLE: EGIT_REPACK
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If non-empty this variable specifies that repository will be repacked to
+# save space. However this can take a REALLY LONG time with VERY big
+# repositories.
+
+# @ECLASS-VARIABLE: EGIT_PRUNE
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If non-empty this variable enables pruning all loose objects on each fetch.
+# This is useful if upstream rewinds and rebases branches often.
+
+# @ECLASS-VARIABLE: EGIT_NONBARE
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If non-empty this variable specifies that all checkouts will be done using
+# non bare repositories. This is useful if you can't operate with bare
+# checkouts for some reason.
+
+# @ECLASS-VARIABLE: EGIT_NOUNPACK
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If non-empty this variable bans unpacking of ${A} content into the srcdir.
+# Default behavior is to unpack ${A} content.
+
+# @FUNCTION: git-2_init_variables
+# @INTERNAL
+# @DESCRIPTION:
+# Internal function initializing all git variables.
+# We define it in function scope so user can define
+# all the variables before and after inherit.
+git-2_init_variables() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local esc_pn liverepo livebranch livecommit
+	esc_pn=${PN//[-+]/_}
+
+	: ${EGIT_SOURCEDIR="${S}"}
+
+	: ${EGIT_STORE_DIR:="${PORTAGE_ACTUAL_DISTDIR-${DISTDIR}}/egit-src"}
+
+	: ${EGIT_HAS_SUBMODULES:=}
+
+	: ${EGIT_OPTIONS:=}
+
+	: ${EGIT_MASTER:=master}
+
+	liverepo=${esc_pn}_LIVE_REPO
+	EGIT_REPO_URI=${!liverepo:-${EGIT_REPO_URI}}
+	[[ ${EGIT_REPO_URI} ]] || die "EGIT_REPO_URI must have some value"
+
+	: ${EVCS_OFFLINE:=}
+
+	livebranch=${esc_pn}_LIVE_BRANCH
+	[[ ${!livebranch} ]] && ewarn "QA: using \"${esc_pn}_LIVE_BRANCH\" variable, you won't get any support"
+	EGIT_BRANCH=${!livebranch:-${EGIT_BRANCH:-${EGIT_MASTER}}}
+
+	livecommit=${esc_pn}_LIVE_COMMIT
+	[[ ${!livecommit} ]] && ewarn "QA: using \"${esc_pn}_LIVE_COMMIT\" variable, you won't get any support"
+	EGIT_COMMIT=${!livecommit:-${EGIT_COMMIT:-${EGIT_BRANCH}}}
+
+	: ${EGIT_REPACK:=}
+
+	: ${EGIT_PRUNE:=}
+}
+
+# @FUNCTION: git-2_submodules
+# @INTERNAL
+# @DESCRIPTION:
+# Internal function wrapping the submodule initialisation and update.
+git-2_submodules() {
+	debug-print-function ${FUNCNAME} "$@"
+	if [[ ${EGIT_HAS_SUBMODULES} ]]; then
+		if [[ ${EVCS_OFFLINE} ]]; then
+			# for submodules operations we need to be online
+			debug-print "${FUNCNAME}: not updating submodules in offline mode"
+			return 1
+		fi
+
+		debug-print "${FUNCNAME}: working in \"${1}\""
+		pushd "${EGIT_DIR}" > /dev/null || die
+
+		debug-print "${FUNCNAME}: git submodule init"
+		git submodule init || die
+		debug-print "${FUNCNAME}: git submodule sync"
+		git submodule sync || die
+		debug-print "${FUNCNAME}: git submodule update"
+		git submodule update || die
+
+		popd > /dev/null || die
+	fi
+}
+
+# @FUNCTION: git-2_branch
+# @INTERNAL
+# @DESCRIPTION:
+# Internal function that changes branch for the repo based on EGIT_COMMIT and
+# EGIT_BRANCH variables.
+git-2_branch() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local branchname src
+
+	debug-print "${FUNCNAME}: working in \"${EGIT_SOURCEDIR}\""
+	pushd "${EGIT_SOURCEDIR}" > /dev/null || die
+
+	local branchname=branch-${EGIT_BRANCH} src=origin/${EGIT_BRANCH}
+	if [[ ${EGIT_COMMIT} != ${EGIT_BRANCH} ]]; then
+		branchname=tree-${EGIT_COMMIT}
+		src=${EGIT_COMMIT}
+	fi
+	debug-print "${FUNCNAME}: git checkout -b ${branchname} ${src}"
+	git checkout -b ${branchname} ${src} \
+		|| die "${FUNCNAME}: changing the branch failed"
+
+	popd > /dev/null || die
+}
+
+# @FUNCTION: git-2_gc
+# @INTERNAL
+# @DESCRIPTION:
+# Internal function running garbage collector on checked out tree.
+git-2_gc() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local args
+
+	if [[ ${EGIT_REPACK} || ${EGIT_PRUNE} ]]; then
+		pushd "${EGIT_DIR}" > /dev/null || die
+		ebegin "Garbage collecting the repository"
+		[[ ${EGIT_PRUNE} ]] && args='--prune'
+		debug-print "${FUNCNAME}: git gc ${args}"
+		git gc ${args}
+		eend $?
+		popd > /dev/null || die
+	fi
+}
+
+# @FUNCTION: git-2_prepare_storedir
+# @INTERNAL
+# @DESCRIPTION:
+# Internal function preparing directory where we are going to store SCM
+# repository.
+git-2_prepare_storedir() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local clone_dir
+
+	# initial clone, we have to create master git storage directory and play
+	# nicely with sandbox
+	if [[ ! -d ${EGIT_STORE_DIR} ]]; then
+		debug-print "${FUNCNAME}: Creating git main storage directory"
+		addwrite /
+		mkdir -m 775 -p "${EGIT_STORE_DIR}" \
+			|| die "${FUNCNAME}: can't mkdir \"${EGIT_STORE_DIR}\""
+	fi
+
+	# allow writing into EGIT_STORE_DIR
+	addwrite "${EGIT_STORE_DIR}"
+
+	# calculate git.eclass store dir for data
+	# We will try to clone the old repository,
+	# and we will remove it if we don't need it anymore.
+	EGIT_OLD_CLONE=
+	if [[ ${EGIT_STORE_DIR} == */egit-src ]]; then
+		local old_store_dir=${EGIT_STORE_DIR/%egit-src/git-src}
+		local old_location=${old_store_dir}/${EGIT_PROJECT:-${PN}}
+
+		if [[ -d ${old_location} ]]; then
+			EGIT_OLD_CLONE=${old_location}
+			# required to remove the old clone
+			addwrite "${old_store_dir}"
+		fi
+	fi
+
+	# calculate the proper store dir for data
+	# If user didn't specify the EGIT_DIR, we check if he did specify
+	# the EGIT_PROJECT or get the folder name from EGIT_REPO_URI.
+	EGIT_REPO_URI=${EGIT_REPO_URI%/}
+	if [[ ! ${EGIT_DIR} ]]; then
+		if [[ ${EGIT_PROJECT} ]]; then
+			clone_dir=${EGIT_PROJECT}
+		else
+			local strippeduri=${EGIT_REPO_URI%/.git}
+			clone_dir=${strippeduri##*/}
+		fi
+		EGIT_DIR=${EGIT_STORE_DIR}/${clone_dir}
+
+		if [[ ${EGIT_OLD_CLONE} && ! -d ${EGIT_DIR} ]]; then
+			elog "${FUNCNAME}: ${CATEGORY}/${PF} will be cloned from old location."
+			elog "It will be necessary to rebuild the package to fetch updates."
+			EGIT_REPO_URI="${EGIT_OLD_CLONE} ${EGIT_REPO_URI}"
+		fi
+	fi
+	export EGIT_DIR=${EGIT_DIR}
+	debug-print "${FUNCNAME}: Storing the repo into \"${EGIT_DIR}\"."
+}
+
+# @FUNCTION: git-2_move_source
+# @INTERNAL
+# @DESCRIPTION:
+# Internal function moving sources from the EGIT_DIR to EGIT_SOURCEDIR dir.
+git-2_move_source() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	debug-print "${FUNCNAME}: ${MOVE_COMMAND} \"${EGIT_DIR}\" \"${EGIT_SOURCEDIR}\""
+	pushd "${EGIT_DIR}" > /dev/null || die
+	mkdir -p "${EGIT_SOURCEDIR}" \
+		|| die "${FUNCNAME}: failed to create ${EGIT_SOURCEDIR}"
+	${MOVE_COMMAND} "${EGIT_SOURCEDIR}" \
+		|| die "${FUNCNAME}: sync to \"${EGIT_SOURCEDIR}\" failed"
+	popd > /dev/null || die
+}
+
+# @FUNCTION: git-2_initial_clone
+# @INTERNAL
+# @DESCRIPTION:
+# Internal function running initial clone on specified repo_uri.
+git-2_initial_clone() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local repo_uri
+
+	EGIT_REPO_URI_SELECTED=""
+	for repo_uri in ${EGIT_REPO_URI}; do
+		debug-print "${FUNCNAME}: git clone ${EGIT_LOCAL_OPTIONS} \"${repo_uri}\" \"${EGIT_DIR}\""
+		if git clone ${EGIT_LOCAL_OPTIONS} "${repo_uri}" "${EGIT_DIR}"; then
+			# global variable containing the repo_name we will be using
+			debug-print "${FUNCNAME}: EGIT_REPO_URI_SELECTED=\"${repo_uri}\""
+			EGIT_REPO_URI_SELECTED="${repo_uri}"
+			break
+		fi
+	done
+
+	[[ ${EGIT_REPO_URI_SELECTED} ]] \
+		|| die "${FUNCNAME}: can't fetch from ${EGIT_REPO_URI}"
+}
+
+# @FUNCTION: git-2_update_repo
+# @INTERNAL
+# @DESCRIPTION:
+# Internal function running update command on specified repo_uri.
+git-2_update_repo() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local repo_uri
+
+	if [[ ${EGIT_LOCAL_NONBARE} ]]; then
+		# checkout master branch and drop all other local branches
+		git checkout ${EGIT_MASTER} || die "${FUNCNAME}: can't checkout master branch ${EGIT_MASTER}"
+		for x in $(git branch | grep -v "* ${EGIT_MASTER}" | tr '\n' ' '); do
+			debug-print "${FUNCNAME}: git branch -D ${x}"
+			git branch -D ${x} > /dev/null
+		done
+	fi
+
+	EGIT_REPO_URI_SELECTED=""
+	for repo_uri in ${EGIT_REPO_URI}; do
+		# git urls might change, so reset it
+		git config remote.origin.url "${repo_uri}"
+
+		debug-print "${EGIT_UPDATE_CMD}"
+		if ${EGIT_UPDATE_CMD} > /dev/null; then
+			# global variable containing the repo_name we will be using
+			debug-print "${FUNCNAME}: EGIT_REPO_URI_SELECTED=\"${repo_uri}\""
+			EGIT_REPO_URI_SELECTED="${repo_uri}"
+			break
+		fi
+	done
+
+	[[ ${EGIT_REPO_URI_SELECTED} ]] \
+		|| die "${FUNCNAME}: can't update from ${EGIT_REPO_URI}"
+}
+
+# @FUNCTION: git-2_fetch
+# @INTERNAL
+# @DESCRIPTION:
+# Internal function fetching repository from EGIT_REPO_URI and storing it in
+# specified EGIT_STORE_DIR.
+git-2_fetch() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local oldsha cursha repo_type
+
+	[[ ${EGIT_LOCAL_NONBARE} ]] && repo_type="non-bare repository" || repo_type="bare repository"
+
+	if [[ ! -d ${EGIT_DIR} ]]; then
+		git-2_initial_clone
+		pushd "${EGIT_DIR}" > /dev/null || die
+		cursha=$(git rev-parse ${UPSTREAM_BRANCH})
+		echo "GIT NEW clone -->"
+		echo "   repository:               ${EGIT_REPO_URI_SELECTED}"
+		echo "   at the commit:            ${cursha}"
+
+		popd > /dev/null || die
+	elif [[ ${EVCS_OFFLINE} ]]; then
+		pushd "${EGIT_DIR}" > /dev/null || die
+		cursha=$(git rev-parse ${UPSTREAM_BRANCH})
+		echo "GIT offline update -->"
+		echo "   repository:               $(git config remote.origin.url)"
+		echo "   at the commit:            ${cursha}"
+		popd > /dev/null || die
+	else
+		pushd "${EGIT_DIR}" > /dev/null || die
+		oldsha=$(git rev-parse ${UPSTREAM_BRANCH})
+		git-2_update_repo
+		cursha=$(git rev-parse ${UPSTREAM_BRANCH})
+
+		# fetch updates
+		echo "GIT update -->"
+		echo "   repository:               ${EGIT_REPO_URI_SELECTED}"
+		# write out message based on the revisions
+		if [[ "${oldsha}" != "${cursha}" ]]; then
+			echo "   updating from commit:     ${oldsha}"
+			echo "   to commit:                ${cursha}"
+		else
+			echo "   at the commit:            ${cursha}"
+		fi
+
+		# print nice statistic of what was changed
+		git --no-pager diff --stat ${oldsha}..${UPSTREAM_BRANCH}
+		popd > /dev/null || die
+	fi
+	# export the version the repository is at
+	export EGIT_VERSION="${cursha}"
+	# log the repo state
+	[[ ${EGIT_COMMIT} != ${EGIT_BRANCH} ]] \
+		&& echo "   commit:                   ${EGIT_COMMIT}"
+	echo "   branch:                   ${EGIT_BRANCH}"
+	echo "   storage directory:        \"${EGIT_DIR}\""
+	echo "   checkout type:            ${repo_type}"
+
+	# Cleanup after git.eclass
+	if [[ ${EGIT_OLD_CLONE} ]]; then
+		einfo "${FUNCNAME}: removing old clone in ${EGIT_OLD_CLONE}."
+		rm -rf "${EGIT_OLD_CLONE}"
+	fi
+}
+
+# @FUNCTION: git_bootstrap
+# @INTERNAL
+# @DESCRIPTION:
+# Internal function that runs bootstrap command on unpacked source.
+git-2_bootstrap() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	# @ECLASS-VARIABLE: EGIT_BOOTSTRAP
+	# @DESCRIPTION:
+	# Command to be executed after checkout and clone of the specified
+	# repository.
+	# enviroment the package will fail if there is no update, thus in
+	# combination with --keep-going it would lead in not-updating
+	# pakcages that are up-to-date.
+	if [[ ${EGIT_BOOTSTRAP} ]]; then
+		pushd "${EGIT_SOURCEDIR}" > /dev/null || die
+		einfo "Starting bootstrap"
+
+		if [[ -f ${EGIT_BOOTSTRAP} ]]; then
+			# we have file in the repo which we should execute
+			debug-print "${FUNCNAME}: bootstraping with file \"${EGIT_BOOTSTRAP}\""
+
+			if [[ -x ${EGIT_BOOTSTRAP} ]]; then
+				eval "./${EGIT_BOOTSTRAP}" \
+					|| die "${FUNCNAME}: bootstrap script failed"
+			else
+				eerror "\"${EGIT_BOOTSTRAP}\" is not executable."
+				eerror "Report upstream, or bug ebuild maintainer to remove bootstrap command."
+				die "\"${EGIT_BOOTSTRAP}\" is not executable"
+			fi
+		else
+			# we execute some system command
+			debug-print "${FUNCNAME}: bootstraping with commands \"${EGIT_BOOTSTRAP}\""
+
+			eval "${EGIT_BOOTSTRAP}" \
+				|| die "${FUNCNAME}: bootstrap commands failed"
+		fi
+
+		einfo "Bootstrap finished"
+		popd > /dev/null || die
+	fi
+}
+
+# @FUNCTION: git-2_migrate_repository
+# @INTERNAL
+# @DESCRIPTION:
+# Internal function migrating between bare and normal checkout repository.
+# This is based on usage of EGIT_SUBMODULES, at least until they
+# start to work with bare checkouts sanely.
+# This function also set some global variables that differ between
+# bare and non-bare checkout.
+git-2_migrate_repository() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local bare returnstate
+
+	# first find out if we have submodules
+	# or user explicitly wants us to use non-bare clones
+	if ! [[ ${EGIT_HAS_SUBMODULES} || ${EGIT_NONBARE} ]]; then
+		bare=1
+	fi
+
+	# test if we already have some repo and if so find out if we have
+	# to migrate the data
+	if [[ -d ${EGIT_DIR} ]]; then
+		if [[ ${bare} && -d ${EGIT_DIR}/.git ]]; then
+			debug-print "${FUNCNAME}: converting \"${EGIT_DIR}\" to bare copy"
+
+			ebegin "Converting \"${EGIT_DIR}\" from non-bare to bare copy"
+			mv "${EGIT_DIR}/.git" "${EGIT_DIR}.bare"
+			export GIT_DIR="${EGIT_DIR}.bare"
+			git config core.bare true > /dev/null
+			returnstate=$?
+			unset GIT_DIR
+			rm -rf "${EGIT_DIR}"
+			mv "${EGIT_DIR}.bare" "${EGIT_DIR}"
+			eend ${returnstate}
+		elif [[ ! ${bare} && ! -d ${EGIT_DIR}/.git ]]; then
+			debug-print "${FUNCNAME}: converting \"${EGIT_DIR}\" to non-bare copy"
+
+			ebegin "Converting \"${EGIT_DIR}\" from bare to non-bare copy"
+			git clone -l "${EGIT_DIR}" "${EGIT_DIR}.nonbare" > /dev/null
+			returnstate=$?
+			rm -rf "${EGIT_DIR}"
+			mv "${EGIT_DIR}.nonbare" "${EGIT_DIR}"
+			eend ${returnstate}
+		fi
+	fi
+	if [[ ${returnstate} -ne 0 ]]; then
+		debug-print "${FUNCNAME}: converting \"${EGIT_DIR}\" failed, removing to start from scratch"
+
+		# migration failed, remove the EGIT_DIR to play it safe
+		einfo "Migration failed, removing \"${EGIT_DIR}\" to start from scratch."
+		rm -rf "${EGIT_DIR}"
+	fi
+
+	# set various options to work with both targets
+	if [[ ${bare} ]]; then
+		debug-print "${FUNCNAME}: working in bare repository for \"${EGIT_DIR}\""
+		EGIT_LOCAL_OPTIONS+="${EGIT_OPTIONS} --bare"
+		MOVE_COMMAND="git clone -l -s -n ${EGIT_DIR// /\\ }"
+		EGIT_UPDATE_CMD="git fetch -t -f -u origin ${EGIT_BRANCH}:${EGIT_BRANCH}"
+		UPSTREAM_BRANCH="${EGIT_BRANCH}"
+		EGIT_LOCAL_NONBARE=
+	else
+		debug-print "${FUNCNAME}: working in bare repository for non-bare \"${EGIT_DIR}\""
+		MOVE_COMMAND="cp -pPR ."
+		EGIT_LOCAL_OPTIONS="${EGIT_OPTIONS}"
+		EGIT_UPDATE_CMD="git pull -f -u ${EGIT_OPTIONS}"
+		UPSTREAM_BRANCH="origin/${EGIT_BRANCH}"
+		EGIT_LOCAL_NONBARE="true"
+	fi
+}
+
+# @FUNCTION: git-2_cleanup
+# @INTERNAL
+# @DESCRIPTION:
+# Internal function cleaning up all the global variables
+# that are not required after the unpack has been done.
+git-2_cleanup() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	# Here we can unset only variables that are GLOBAL
+	# defined by the eclass, BUT NOT subject to change
+	# by user (like EGIT_PROJECT).
+	# If ebuild writer polutes his environment it is
+	# his problem only.
+	unset EGIT_DIR
+	unset MOVE_COMMAND
+	unset EGIT_LOCAL_OPTIONS
+	unset EGIT_UPDATE_CMD
+	unset UPSTREAM_BRANCH
+	unset EGIT_LOCAL_NONBARE
+}
+
+# @FUNCTION: git-2_src_unpack
+# @DESCRIPTION:
+# Default git src_unpack function.
+git-2_src_unpack() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	git-2_init_variables
+	git-2_prepare_storedir
+	git-2_migrate_repository
+	git-2_fetch "$@"
+	git-2_gc
+	git-2_submodules
+	git-2_move_source
+	git-2_branch
+	git-2_bootstrap
+	git-2_cleanup
+	echo ">>> Unpacked to ${EGIT_SOURCEDIR}"
+
+	# Users can specify some SRC_URI and we should
+	# unpack the files too.
+	if [[ ! ${EGIT_NOUNPACK} ]]; then
+		if has ${EAPI:-0} 0 1; then
+			[[ ${A} ]] && unpack ${A}
+		else
+			default_src_unpack
+		fi
+	fi
+}
diff --git a/eclass/git-r3.eclass b/eclass/git-r3.eclass
new file mode 100644
index 0000000..7fe9bcb
--- /dev/null
+++ b/eclass/git-r3.eclass
@@ -0,0 +1,1104 @@
+# Copyright 1999-2018 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: git-r3.eclass
+# @MAINTAINER:
+# MichaƂ Górny <mgorny@gentoo.org>
+# @BLURB: Eclass for fetching and unpacking git repositories.
+# @DESCRIPTION:
+# Third generation eclass for easing maintenance of live ebuilds using
+# git as remote repository.
+
+case "${EAPI:-0}" in
+	0|1|2|3)
+		die "Unsupported EAPI=${EAPI} (obsolete) for ${ECLASS}"
+		;;
+	4|5|6|7)
+		;;
+	*)
+		die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
+		;;
+esac
+
+EXPORT_FUNCTIONS src_unpack
+
+if [[ ! ${_GIT_R3} ]]; then
+
+if [[ ! ${_INHERITED_BY_GIT_2} ]]; then
+	if [[ ${EAPI:-0} != [0123456] ]]; then
+		BDEPEND=">=dev-vcs/git-1.8.2.1[curl]"
+	else
+		DEPEND=">=dev-vcs/git-1.8.2.1[curl]"
+	fi
+fi
+
+# @ECLASS-VARIABLE: EGIT_CLONE_TYPE
+# @DESCRIPTION:
+# Type of clone that should be used against the remote repository.
+# This can be either of: 'mirror', 'single', 'shallow'.
+#
+# This is intended to be set by user in make.conf. Ebuilds are supposed
+# to set EGIT_MIN_CLONE_TYPE if necessary instead.
+#
+# The 'mirror' type clones all remote branches and tags with complete
+# history and all notes. EGIT_COMMIT can specify any commit hash.
+# Upstream-removed branches and tags are purged from the local clone
+# while fetching. This mode is suitable for cloning the local copy
+# for development or hosting a local git mirror. However, clones
+# of repositories with large diverged branches may quickly grow large.
+#
+# The 'single+tags' type clones the requested branch and all tags
+# in the repository. All notes are fetched as well. EGIT_COMMIT
+# can safely specify hashes throughout the current branch and all tags.
+# No purging of old references is done (if you often switch branches,
+# you may need to remove stale branches yourself). This mode is intended
+# mostly for use with broken git servers such as Google Code that fail
+# to fetch tags along with the branch in 'single' mode.
+#
+# The 'single' type clones only the requested branch or tag. Tags
+# referencing commits throughout the branch history are fetched as well,
+# and all notes. EGIT_COMMIT can safely specify only hashes
+# in the current branch. No purging of old references is done (if you
+# often switch branches, you may need to remove stale branches
+# yourself). This mode is suitable for general use.
+#
+# The 'shallow' type clones only the newest commit on requested branch
+# or tag. EGIT_COMMIT can only specify tags, and since the history is
+# unavailable calls like 'git describe' will not reference prior tags.
+# No purging of old references is done. This mode is intended mostly for
+# embedded systems with limited disk space.
+: ${EGIT_CLONE_TYPE:=single}
+
+# @ECLASS-VARIABLE: EGIT_MIN_CLONE_TYPE
+# @DESCRIPTION:
+# 'Minimum' clone type supported by the ebuild. Takes same values
+# as EGIT_CLONE_TYPE. When user sets a type that's 'lower' (that is,
+# later on the list) than EGIT_MIN_CLONE_TYPE, the eclass uses
+# EGIT_MIN_CLONE_TYPE instead.
+#
+# This variable is intended to be used by ebuilds only. Users are
+# supposed to set EGIT_CLONE_TYPE instead.
+#
+# A common case is to use 'single' whenever the build system requires
+# access to full branch history, or 'single+tags' when Google Code
+# or a similar remote is used that does not support shallow clones
+# and fetching tags along with commits. Please use sparingly, and to fix
+# fatal errors rather than 'non-pretty versions'.
+: ${EGIT_MIN_CLONE_TYPE:=shallow}
+
+# @ECLASS-VARIABLE: EGIT3_STORE_DIR
+# @DESCRIPTION:
+# Storage directory for git sources.
+#
+# This is intended to be set by user in make.conf. Ebuilds must not set
+# it.
+#
+# EGIT3_STORE_DIR=${DISTDIR}/git3-src
+
+# @ECLASS-VARIABLE: EGIT_MIRROR_URI
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# 'Top' URI to a local git mirror. If specified, the eclass will try
+# to fetch from the local mirror instead of using the remote repository.
+#
+# The mirror needs to follow EGIT3_STORE_DIR structure. The directory
+# created by eclass can be used for that purpose.
+#
+# Example:
+# @CODE
+# EGIT_MIRROR_URI="git://mirror.lan/"
+# @CODE
+
+# @ECLASS-VARIABLE: EGIT_REPO_URI
+# @REQUIRED
+# @DESCRIPTION:
+# URIs to the repository, e.g. https://foo. If multiple URIs are
+# provided, the eclass will consider the remaining URIs as fallbacks
+# to try if the first URI does not work. For supported URI syntaxes,
+# read the manpage for git-clone(1).
+#
+# URIs should be using https:// whenever possible. http:// and git://
+# URIs are completely unsecured and their use (even if only as
+# a fallback) renders the ebuild completely vulnerable to MITM attacks.
+#
+# It can be overridden via env using ${PN}_LIVE_REPO variable.
+#
+# Can be a whitespace-separated list or an array.
+#
+# Example:
+# @CODE
+# EGIT_REPO_URI="https://a/b.git https://c/d.git"
+# @CODE
+
+# @ECLASS-VARIABLE: EVCS_OFFLINE
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If non-empty, this variable prevents any online operations.
+
+# @ECLASS-VARIABLE: EVCS_UMASK
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Set this variable to a custom umask. This is intended to be set by
+# users. By setting this to something like 002, it can make life easier
+# for people who do development as non-root (but are in the portage
+# group), and then switch over to building with FEATURES=userpriv.
+# Or vice-versa. Shouldn't be a security issue here as anyone who has
+# portage group write access already can screw the system over in more
+# creative ways.
+
+# @ECLASS-VARIABLE: EGIT_BRANCH
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# The branch name to check out. If unset, the upstream default (HEAD)
+# will be used.
+#
+# It can be overridden via env using ${PN}_LIVE_BRANCH variable.
+
+# @ECLASS-VARIABLE: EGIT_COMMIT
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# The tag name or commit identifier to check out. If unset, newest
+# commit from the branch will be used. Note that if set to a commit
+# not on HEAD branch, EGIT_BRANCH needs to be set to a branch on which
+# the commit is available.
+#
+# It can be overridden via env using ${PN}_LIVE_COMMIT variable.
+
+# @ECLASS-VARIABLE: EGIT_COMMIT_DATE
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Attempt to check out the repository state for the specified timestamp.
+# The date should be in format understood by 'git rev-list'. The commits
+# on EGIT_BRANCH will be considered.
+#
+# The eclass will select the last commit with commit date preceding
+# the specified date. When merge commits are found, only first parents
+# will be considered in order to avoid switching into external branches
+# (assuming that merges are done correctly). In other words, each merge
+# will be considered alike a single commit with date corresponding
+# to the merge commit date.
+#
+# It can be overridden via env using ${PN}_LIVE_COMMIT_DATE variable.
+
+# @ECLASS-VARIABLE: EGIT_CHECKOUT_DIR
+# @DESCRIPTION:
+# The directory to check the git sources out to.
+#
+# EGIT_CHECKOUT_DIR=${WORKDIR}/${P}
+
+# @ECLASS-VARIABLE: EGIT_SUBMODULES
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# An array of inclusive and exclusive wildcards on submodule names,
+# stating which submodules are fetched and checked out. Exclusions
+# start with '-', and exclude previously matched submodules.
+#
+# If unset, all submodules are enabled. Empty list disables all
+# submodules. In order to use an exclude-only list, start the array
+# with '*'.
+#
+# Remember that wildcards need to be quoted in order to prevent filename
+# expansion.
+#
+# Examples:
+# @CODE
+# # Disable all submodules
+# EGIT_SUBMODULES=()
+#
+# # Include only foo and bar
+# EGIT_SUBMODULES=( foo bar )
+#
+# # Use all submodules except for test-* but include test-lib
+# EGIT_SUBMODULES=( '*' '-test-*' test-lib )
+# @CODE
+
+# @FUNCTION: _git-r3_env_setup
+# @INTERNAL
+# @DESCRIPTION:
+# Set the eclass variables as necessary for operation. This can involve
+# setting EGIT_* to defaults or ${PN}_LIVE_* variables.
+_git-r3_env_setup() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	# check the clone type
+	case "${EGIT_CLONE_TYPE}" in
+		mirror|single+tags|single|shallow)
+			;;
+		*)
+			die "Invalid EGIT_CLONE_TYPE=${EGIT_CLONE_TYPE}"
+	esac
+	case "${EGIT_MIN_CLONE_TYPE}" in
+		shallow)
+			;;
+		single)
+			if [[ ${EGIT_CLONE_TYPE} == shallow ]]; then
+				einfo "git-r3: ebuild needs to be cloned in '\e[1msingle\e[22m' mode, adjusting"
+				EGIT_CLONE_TYPE=single
+			fi
+			;;
+		single+tags)
+			if [[ ${EGIT_CLONE_TYPE} == shallow || ${EGIT_CLONE_TYPE} == single ]]; then
+				einfo "git-r3: ebuild needs to be cloned in '\e[1msingle+tags\e[22m' mode, adjusting"
+				EGIT_CLONE_TYPE=single+tags
+			fi
+			;;
+		mirror)
+			if [[ ${EGIT_CLONE_TYPE} != mirror ]]; then
+				einfo "git-r3: ebuild needs to be cloned in '\e[1mmirror\e[22m' mode, adjusting"
+				EGIT_CLONE_TYPE=mirror
+			fi
+			;;
+		*)
+			die "Invalid EGIT_MIN_CLONE_TYPE=${EGIT_MIN_CLONE_TYPE}"
+	esac
+
+	if [[ ${EGIT_SUBMODULES[@]+1} && $(declare -p EGIT_SUBMODULES) != "declare -a"* ]]
+	then
+		die 'EGIT_SUBMODULES must be an array.'
+	fi
+
+	local esc_pn livevar
+	esc_pn=${PN//[-+]/_}
+	[[ ${esc_pn} == [0-9]* ]] && esc_pn=_${esc_pn}
+
+	livevar=${esc_pn}_LIVE_REPO
+	EGIT_REPO_URI=${!livevar-${EGIT_REPO_URI}}
+	[[ ${!livevar} ]] \
+		&& ewarn "Using ${livevar}, no support will be provided"
+
+	livevar=${esc_pn}_LIVE_BRANCH
+	EGIT_BRANCH=${!livevar-${EGIT_BRANCH}}
+	[[ ${!livevar} ]] \
+		&& ewarn "Using ${livevar}, no support will be provided"
+
+	livevar=${esc_pn}_LIVE_COMMIT
+	EGIT_COMMIT=${!livevar-${EGIT_COMMIT}}
+	[[ ${!livevar} ]] \
+		&& ewarn "Using ${livevar}, no support will be provided"
+
+	livevar=${esc_pn}_LIVE_COMMIT_DATE
+	EGIT_COMMIT_DATE=${!livevar-${EGIT_COMMIT_DATE}}
+	[[ ${!livevar} ]] \
+		&& ewarn "Using ${livevar}, no support will be provided"
+
+	if [[ ${EGIT_COMMIT} && ${EGIT_COMMIT_DATE} ]]; then
+		die "EGIT_COMMIT and EGIT_COMMIT_DATE can not be specified simultaneously"
+	fi
+
+	# Migration helpers. Remove them when git-2 is removed.
+
+	if [[ ${EGIT_SOURCEDIR} ]]; then
+		eerror "EGIT_SOURCEDIR has been replaced by EGIT_CHECKOUT_DIR. While updating"
+		eerror "your ebuild, please check whether the variable is necessary at all"
+		eerror "since the default has been changed from \${S} to \${WORKDIR}/\${P}."
+		eerror "Therefore, proper setting of S may be sufficient."
+		die "EGIT_SOURCEDIR has been replaced by EGIT_CHECKOUT_DIR."
+	fi
+
+	if [[ ${EGIT_MASTER} ]]; then
+		eerror "EGIT_MASTER has been removed. Instead, the upstream default (HEAD)"
+		eerror "is used by the eclass. Please remove the assignment or use EGIT_BRANCH"
+		eerror "as necessary."
+		die "EGIT_MASTER has been removed."
+	fi
+
+	if [[ ${EGIT_HAS_SUBMODULES} ]]; then
+		eerror "EGIT_HAS_SUBMODULES has been removed. The eclass no longer needs"
+		eerror "to switch the clone type in order to support submodules and therefore"
+		eerror "submodules are detected and fetched automatically. If you need to"
+		eerror "disable or filter submodules, see EGIT_SUBMODULES."
+		die "EGIT_HAS_SUBMODULES is no longer necessary."
+	fi
+
+	if [[ ${EGIT_PROJECT} ]]; then
+		eerror "EGIT_PROJECT has been removed. Instead, the eclass determines"
+		eerror "the local clone path using path in canonical EGIT_REPO_URI."
+		eerror "If the current algorithm causes issues for you, please report a bug."
+		die "EGIT_PROJECT is no longer necessary."
+	fi
+
+	if [[ ${EGIT_BOOTSTRAP} ]]; then
+		eerror "EGIT_BOOTSTRAP has been removed. Please create proper src_prepare()"
+		eerror "instead."
+		die "EGIT_BOOTSTRAP has been removed."
+	fi
+
+	if [[ ${EGIT_NOUNPACK} ]]; then
+		eerror "EGIT_NOUNPACK has been removed. The eclass no longer calls default"
+		eerror "unpack function. If necessary, please declare proper src_unpack()."
+		die "EGIT_NOUNPACK has been removed."
+	fi
+}
+
+# @FUNCTION: _git-r3_set_gitdir
+# @USAGE: <repo-uri>
+# @INTERNAL
+# @DESCRIPTION:
+# Obtain the local repository path and set it as GIT_DIR. Creates
+# a new repository if necessary.
+#
+# <repo-uri> may be used to compose the path. It should therefore be
+# a canonical URI to the repository.
+_git-r3_set_gitdir() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local repo_name=${1#*://*/}
+
+	# strip the trailing slash
+	repo_name=${repo_name%/}
+
+	# strip common prefixes to make paths more likely to match
+	# e.g. git://X/Y.git vs https://X/git/Y.git
+	# (but just one of the prefixes)
+	case "${repo_name}" in
+		# gnome.org... who else?
+		browse/*) repo_name=${repo_name#browse/};;
+		# cgit can proxy requests to git
+		cgit/*) repo_name=${repo_name#cgit/};;
+		# pretty common
+		git/*) repo_name=${repo_name#git/};;
+		# gentoo.org
+		gitroot/*) repo_name=${repo_name#gitroot/};;
+		# sourceforge
+		p/*) repo_name=${repo_name#p/};;
+		# kernel.org
+		pub/scm/*) repo_name=${repo_name#pub/scm/};;
+	esac
+	# ensure a .git suffix, same reason
+	repo_name=${repo_name%.git}.git
+	# now replace all the slashes
+	repo_name=${repo_name//\//_}
+
+	local distdir=${PORTAGE_ACTUAL_DISTDIR:-${DISTDIR}}
+	: ${EGIT3_STORE_DIR:=${distdir}/git3-src}
+
+	GIT_DIR=${EGIT3_STORE_DIR}/${repo_name}
+
+	if [[ ! -d ${EGIT3_STORE_DIR} && ! ${EVCS_OFFLINE} ]]; then
+		(
+			addwrite /
+			mkdir -p "${EGIT3_STORE_DIR}"
+		) || die "Unable to create ${EGIT3_STORE_DIR}"
+	fi
+
+	addwrite "${EGIT3_STORE_DIR}"
+	if [[ ! -d ${GIT_DIR} ]]; then
+		if [[ ${EVCS_OFFLINE} ]]; then
+			eerror "A clone of the following repository is required to proceed:"
+			eerror "  ${1}"
+			eerror "However, networking activity has been disabled using EVCS_OFFLINE and there"
+			eerror "is no local clone available."
+			die "No local clone of ${1}. Unable to proceed with EVCS_OFFLINE."
+		fi
+
+		local saved_umask
+		if [[ ${EVCS_UMASK} ]]; then
+			saved_umask=$(umask)
+			umask "${EVCS_UMASK}" || die "Bad options to umask: ${EVCS_UMASK}"
+		fi
+		mkdir "${GIT_DIR}" || die
+		git init --bare || die
+		if [[ ${saved_umask} ]]; then
+			umask "${saved_umask}" || die
+		fi
+	fi
+}
+
+# @FUNCTION: _git-r3_set_submodules
+# @USAGE: <file-contents>
+# @INTERNAL
+# @DESCRIPTION:
+# Parse .gitmodules contents passed as <file-contents>
+# as in "$(cat .gitmodules)"). Composes a 'submodules' array that
+# contains in order (name, URL, path) for each submodule.
+_git-r3_set_submodules() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local data=${1}
+
+	# ( name url path ... )
+	submodules=()
+
+	local l
+	while read l; do
+		# submodule.<path>.path=<path>
+		# submodule.<path>.url=<url>
+		[[ ${l} == submodule.*.url=* ]] || continue
+
+		l=${l#submodule.}
+		local subname=${l%%.url=*}
+
+		# filter out on EGIT_SUBMODULES
+		if declare -p EGIT_SUBMODULES &>/dev/null; then
+			local p l_res res=
+			for p in "${EGIT_SUBMODULES[@]}"; do
+				if [[ ${p} == -* ]]; then
+					p=${p#-}
+					l_res=
+				else
+					l_res=1
+				fi
+
+				[[ ${subname} == ${p} ]] && res=${l_res}
+			done
+
+			if [[ ! ${res} ]]; then
+				einfo "Skipping submodule \e[1m${subname}\e[22m"
+				continue
+			fi
+		fi
+
+		# skip modules that have 'update = none', bug #487262.
+		local upd=$(echo "${data}" | git config -f /dev/fd/0 \
+			submodule."${subname}".update)
+		[[ ${upd} == none ]] && continue
+
+		# https://github.com/git/git/blob/master/refs.c#L31
+		# we are more restrictive than git itself but that should not
+		# cause any issues, #572312, #606950
+		# TODO: check escaped names for collisions
+		local enc_subname=${subname//[^a-zA-Z0-9-]/_}
+
+		submodules+=(
+			"${enc_subname}"
+			"$(echo "${data}" | git config -f /dev/fd/0 \
+				submodule."${subname}".url || die)"
+			"$(echo "${data}" | git config -f /dev/fd/0 \
+				submodule."${subname}".path || die)"
+		)
+	done < <(echo "${data}" | git config -f /dev/fd/0 -l || die)
+}
+
+# @FUNCTION: _git-r3_set_subrepos
+# @USAGE: <submodule-uri> <parent-repo-uri>...
+# @INTERNAL
+# @DESCRIPTION:
+# Create 'subrepos' array containing absolute (canonical) submodule URIs
+# for the given <submodule-uri>. If the URI is relative, URIs will be
+# constructed using all <parent-repo-uri>s. Otherwise, this single URI
+# will be placed in the array.
+_git-r3_set_subrepos() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local suburl=${1}
+	subrepos=( "${@:2}" )
+
+	if [[ ${suburl} == ./* || ${suburl} == ../* ]]; then
+		# drop all possible trailing slashes for consistency
+		subrepos=( "${subrepos[@]%%/}" )
+
+		while true; do
+			if [[ ${suburl} == ./* ]]; then
+				suburl=${suburl:2}
+			elif [[ ${suburl} == ../* ]]; then
+				suburl=${suburl:3}
+
+				# XXX: correctness checking
+
+				# drop the last path component
+				subrepos=( "${subrepos[@]%/*}" )
+				# and then the trailing slashes, again
+				subrepos=( "${subrepos[@]%%/}" )
+			else
+				break
+			fi
+		done
+
+		# append the preprocessed path to the preprocessed URIs
+		subrepos=( "${subrepos[@]/%//${suburl}}")
+	else
+		subrepos=( "${suburl}" )
+	fi
+}
+
+
+# @FUNCTION: _git-r3_is_local_repo
+# @USAGE: <repo-uri>
+# @INTERNAL
+# @DESCRIPTION:
+# Determine whether the given URI specifies a local (on-disk)
+# repository.
+_git-r3_is_local_repo() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local uri=${1}
+
+	[[ ${uri} == file://* || ${uri} == /* ]]
+}
+
+# @FUNCTION: git-r3_fetch
+# @USAGE: [<repo-uri> [<remote-ref> [<local-id> [<commit-date>]]]]
+# @DESCRIPTION:
+# Fetch new commits to the local clone of repository.
+#
+# <repo-uri> specifies the repository URIs to fetch from, as a space-
+# -separated list. The first URI will be used as repository group
+# identifier and therefore must be used consistently. When not
+# specified, defaults to ${EGIT_REPO_URI}.
+#
+# <remote-ref> specifies the remote ref or commit id to fetch.
+# It is preferred to use 'refs/heads/<branch-name>' for branches
+# and 'refs/tags/<tag-name>' for tags. Other options are 'HEAD'
+# for upstream default branch and hexadecimal commit SHA1. Defaults
+# to the first of EGIT_COMMIT, EGIT_BRANCH or literal 'HEAD' that
+# is set to a non-null value.
+#
+# <local-id> specifies the local branch identifier that will be used to
+# locally store the fetch result. It should be unique to multiple
+# fetches within the repository that can be performed at the same time
+# (including parallel merges). It defaults to ${CATEGORY}/${PN}/${SLOT%/*}.
+# This default should be fine unless you are fetching multiple trees
+# from the same repository in the same ebuild.
+#
+# <commit-id> requests attempting to use repository state as of specific
+# date. For more details, see EGIT_COMMIT_DATE.
+#
+# The fetch operation will affect the EGIT_STORE only. It will not touch
+# the working copy, nor export any environment variables.
+# If the repository contains submodules, they will be fetched
+# recursively.
+git-r3_fetch() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	# process repos first since we create repo_name from it
+	local repos
+	if [[ ${1} ]]; then
+		repos=( ${1} )
+	elif [[ $(declare -p EGIT_REPO_URI) == "declare -a"* ]]; then
+		repos=( "${EGIT_REPO_URI[@]}" )
+	else
+		repos=( ${EGIT_REPO_URI} )
+	fi
+
+	[[ ${repos[@]} ]] || die "No URI provided and EGIT_REPO_URI unset"
+
+	local r
+	for r in "${repos[@]}"; do
+		if [[ ${r} == git:* || ${r} == http:* ]]; then
+			ewarn "git-r3: ${r%%:*} protocol is completely unsecure and may render the ebuild"
+			ewarn "easily susceptible to MITM attacks (even if used only as fallback). Please"
+			ewarn "use https instead."
+			ewarn "[URI: ${r}]"
+		fi
+	done
+
+	local -x GIT_DIR
+	_git-r3_set_gitdir "${repos[0]}"
+
+	# prepend the local mirror if applicable
+	if [[ ${EGIT_MIRROR_URI} ]]; then
+		repos=(
+			"${EGIT_MIRROR_URI%/}/${GIT_DIR##*/}"
+			"${repos[@]}"
+		)
+	fi
+
+	# get the default values for the common variables and override them
+	local branch_name=${EGIT_BRANCH}
+	local commit_id=${2:-${EGIT_COMMIT}}
+	local commit_date=${4:-${EGIT_COMMIT_DATE}}
+
+	# support new override API for EAPI 6+
+	if ! has "${EAPI:-0}" 0 1 2 3 4 5; then
+		# get the name and do some more processing:
+		# 1) kill .git suffix,
+		# 2) underscore (remaining) non-variable characters,
+		# 3) add preceding underscore if it starts with a digit,
+		# 4) uppercase.
+		local override_name=${GIT_DIR##*/}
+		override_name=${override_name%.git}
+		override_name=${override_name//[^a-zA-Z0-9_]/_}
+		override_name=${override_name^^}
+
+		local varmap=(
+			REPO:repos
+			BRANCH:branch_name
+			COMMIT:commit_id
+			COMMIT_DATE:commit_date
+		)
+
+		local localvar livevar live_warn=
+		for localvar in "${varmap[@]}"; do
+			livevar=EGIT_OVERRIDE_${localvar%:*}_${override_name}
+			localvar=${localvar#*:}
+
+			if [[ -n ${!livevar} ]]; then
+				[[ ${localvar} == repos ]] && repos=()
+				live_warn=1
+				ewarn "Using ${livevar}=${!livevar}"
+				declare "${localvar}=${!livevar}"
+			fi
+		done
+
+		if [[ ${live_warn} ]]; then
+			ewarn "No support will be provided."
+		fi
+	fi
+
+	# set final variables after applying overrides
+	local branch=${branch_name:+refs/heads/${branch_name}}
+	local remote_ref=${commit_id:-${branch:-HEAD}}
+	local local_id=${3:-${CATEGORY}/${PN}/${SLOT%/*}}
+	local local_ref=refs/git-r3/${local_id}/__main__
+
+	# try to fetch from the remote
+	local success saved_umask
+	if [[ ${EVCS_UMASK} ]]; then
+		saved_umask=$(umask)
+		umask "${EVCS_UMASK}" || die "Bad options to umask: ${EVCS_UMASK}"
+	fi
+	for r in "${repos[@]}"; do
+		if [[ ! ${EVCS_OFFLINE} ]]; then
+			einfo "Fetching \e[1m${r}\e[22m ..."
+
+			local fetch_command=( git fetch "${r}" )
+			local clone_type=${EGIT_CLONE_TYPE}
+
+			if [[ ${clone_type} == mirror ]]; then
+				fetch_command+=(
+					--prune
+					# mirror the remote branches as local branches
+					"+refs/heads/*:refs/heads/*"
+					# pull tags explicitly in order to prune them properly
+					"+refs/tags/*:refs/tags/*"
+					# notes in case something needs them
+					"+refs/notes/*:refs/notes/*"
+					# and HEAD in case we need the default branch
+					# (we keep it in refs/git-r3 since otherwise --prune interferes)
+					"+HEAD:refs/git-r3/HEAD"
+				)
+			else # single or shallow
+				local fetch_l fetch_r
+
+				if [[ ${remote_ref} == HEAD ]]; then
+					# HEAD
+					fetch_l=HEAD
+				elif [[ ${remote_ref} == refs/* ]]; then
+					# regular branch, tag or some other explicit ref
+					fetch_l=${remote_ref}
+				else
+					# tag or commit id...
+					# let ls-remote figure it out
+					local tagref=$(git ls-remote "${r}" "refs/tags/${remote_ref}")
+
+					# if it was a tag, ls-remote obtained a hash
+					if [[ ${tagref} ]]; then
+						# tag
+						fetch_l=refs/tags/${remote_ref}
+					else
+						# commit id
+						# so we need to fetch the whole branch
+						if [[ ${branch} ]]; then
+							fetch_l=${branch}
+						else
+							fetch_l=HEAD
+						fi
+
+						# fetching by commit in shallow mode? can't do.
+						if [[ ${clone_type} == shallow ]]; then
+							clone_type=single
+						fi
+					fi
+				fi
+
+				# checkout by date does not make sense in shallow mode
+				if [[ ${commit_date} && ${clone_type} == shallow ]]; then
+					clone_type=single
+				fi
+
+				if [[ ${fetch_l} == HEAD ]]; then
+					fetch_r=refs/git-r3/HEAD
+				else
+					fetch_r=${fetch_l}
+				fi
+
+				fetch_command+=(
+					"+${fetch_l}:${fetch_r}"
+				)
+
+				if [[ ${clone_type} == single+tags ]]; then
+					fetch_command+=(
+						# pull tags explicitly as requested
+						"+refs/tags/*:refs/tags/*"
+					)
+				fi
+			fi
+
+			if [[ ${clone_type} == shallow ]]; then
+				if _git-r3_is_local_repo; then
+					# '--depth 1' causes sandbox violations with local repos
+					# bug #491260
+					clone_type=single
+				elif [[ ! $(git rev-parse --quiet --verify "${fetch_r}") ]]
+				then
+					# use '--depth 1' when fetching a new branch
+					fetch_command+=( --depth 1 )
+				fi
+			else # non-shallow mode
+				if [[ -f ${GIT_DIR}/shallow ]]; then
+					fetch_command+=( --unshallow )
+				fi
+			fi
+
+			set -- "${fetch_command[@]}"
+			echo "${@}" >&2
+			"${@}" || continue
+
+			if [[ ${clone_type} == mirror || ${fetch_l} == HEAD ]]; then
+				# update our HEAD to match our remote HEAD ref
+				git symbolic-ref HEAD refs/git-r3/HEAD \
+						|| die "Unable to update HEAD"
+			fi
+		fi
+
+		# now let's see what the user wants from us
+		if [[ ${commit_date} ]]; then
+			local dated_commit_id=$(
+				git rev-list --first-parent --before="${commit_date}" \
+					-n 1 "${remote_ref}"
+			)
+			if [[ ${?} -ne 0 ]]; then
+				die "Listing ${remote_ref} failed (wrong ref?)."
+			elif [[ ! ${dated_commit_id} ]]; then
+				die "Unable to find commit for date ${commit_date}."
+			else
+				set -- git update-ref --no-deref "${local_ref}" "${dated_commit_id}"
+			fi
+		else
+			local full_remote_ref=$(
+				git rev-parse --verify --symbolic-full-name "${remote_ref}"
+			)
+
+			if [[ ${full_remote_ref} ]]; then
+				# when we are given a ref, create a symbolic ref
+				# so that we preserve the actual argument
+				set -- git symbolic-ref "${local_ref}" "${full_remote_ref}"
+			else
+				# otherwise, we were likely given a commit id
+				set -- git update-ref --no-deref "${local_ref}" "${remote_ref}"
+			fi
+		fi
+
+		echo "${@}" >&2
+		if ! "${@}"; then
+			if [[ ${EVCS_OFFLINE} ]]; then
+				eerror "A clone of the following repository is required to proceed:"
+				eerror "  ${r}"
+				eerror "However, networking activity has been disabled using EVCS_OFFLINE and the local"
+				eerror "clone does not have requested ref:"
+				eerror "  ${remote_ref}"
+				die "Local clone of ${r} does not have requested ref: ${remote_ref}. Unable to proceed with EVCS_OFFLINE."
+			else
+				die "Referencing ${remote_ref} failed (wrong ref?)."
+			fi
+		fi
+
+		success=1
+		break
+	done
+	if [[ ${saved_umask} ]]; then
+		umask "${saved_umask}" || die
+	fi
+	[[ ${success} ]] || die "Unable to fetch from any of EGIT_REPO_URI"
+
+	# submodules can reference commits in any branch
+	# always use the 'mirror' mode to accomodate that, bug #503332
+	local EGIT_CLONE_TYPE=mirror
+
+	# recursively fetch submodules
+	if git cat-file -e "${local_ref}":.gitmodules &>/dev/null; then
+		local submodules
+		_git-r3_set_submodules \
+			"$(git cat-file -p "${local_ref}":.gitmodules || die)"
+
+		while [[ ${submodules[@]} ]]; do
+			local subname=${submodules[0]}
+			local url=${submodules[1]}
+			local path=${submodules[2]}
+
+			# use only submodules for which path does exist
+			# (this is in par with 'git submodule'), bug #551100
+			# note: git cat-file does not work for submodules
+			if [[ $(git ls-tree -d "${local_ref}" "${path}") ]]
+			then
+				local commit=$(git rev-parse "${local_ref}:${path}" || die)
+
+				if [[ ! ${commit} ]]; then
+					die "Unable to get commit id for submodule ${subname}"
+				fi
+
+				local subrepos
+				_git-r3_set_subrepos "${url}" "${repos[@]}"
+
+				git-r3_fetch "${subrepos[*]}" "${commit}" "${local_id}/${subname}"
+			fi
+
+			submodules=( "${submodules[@]:3}" ) # shift
+		done
+	fi
+}
+
+# @FUNCTION: git-r3_checkout
+# @USAGE: [<repo-uri> [<checkout-path> [<local-id> [<checkout-paths>...]]]]
+# @DESCRIPTION:
+# Check the previously fetched tree to the working copy.
+#
+# <repo-uri> specifies the repository URIs, as a space-separated list.
+# The first URI will be used as repository group identifier
+# and therefore must be used consistently with git-r3_fetch.
+# The remaining URIs are not used and therefore may be omitted.
+# When not specified, defaults to ${EGIT_REPO_URI}.
+#
+# <checkout-path> specifies the path to place the checkout. It defaults
+# to ${EGIT_CHECKOUT_DIR} if set, otherwise to ${WORKDIR}/${P}.
+#
+# <local-id> needs to specify the local identifier that was used
+# for respective git-r3_fetch.
+#
+# If <checkout-paths> are specified, then the specified paths are passed
+# to 'git checkout' to effect a partial checkout. Please note that such
+# checkout will not cause the repository to switch branches,
+# and submodules will be skipped at the moment. The submodules matching
+# those paths might be checked out in a future version of the eclass.
+#
+# The checkout operation will write to the working copy, and export
+# the repository state into the environment. If the repository contains
+# submodules, they will be checked out recursively.
+git-r3_checkout() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local repos
+	if [[ ${1} ]]; then
+		repos=( ${1} )
+	elif [[ $(declare -p EGIT_REPO_URI) == "declare -a"* ]]; then
+		repos=( "${EGIT_REPO_URI[@]}" )
+	else
+		repos=( ${EGIT_REPO_URI} )
+	fi
+
+	local out_dir=${2:-${EGIT_CHECKOUT_DIR:-${WORKDIR}/${P}}}
+	local local_id=${3:-${CATEGORY}/${PN}/${SLOT%/*}}
+	local checkout_paths=( "${@:4}" )
+
+	local -x GIT_DIR
+	_git-r3_set_gitdir "${repos[0]}"
+
+	einfo "Checking out \e[1m${repos[0]}\e[22m to \e[1m${out_dir}\e[22m ..."
+
+	if ! git cat-file -e refs/git-r3/"${local_id}"/__main__; then
+		die "Logic error: no local clone of ${repos[0]}. git-r3_fetch not used?"
+	fi
+	local remote_ref=$(
+		git symbolic-ref --quiet refs/git-r3/"${local_id}"/__main__
+	)
+	local new_commit_id=$(
+		git rev-parse --verify refs/git-r3/"${local_id}"/__main__
+	)
+
+	git-r3_sub_checkout() {
+		local orig_repo=${GIT_DIR}
+		local -x GIT_DIR=${out_dir}/.git
+		local -x GIT_WORK_TREE=${out_dir}
+
+		mkdir -p "${out_dir}" || die
+
+		# use git init+fetch instead of clone since the latter doesn't like
+		# non-empty directories.
+
+		git init --quiet || die
+		# setup 'alternates' to avoid copying objects
+		echo "${orig_repo}/objects" > "${GIT_DIR}"/objects/info/alternates || die
+		# now copy the refs
+		cp -R "${orig_repo}"/refs/* "${GIT_DIR}"/refs/ || die
+		if [[ -f ${orig_repo}/packed-refs ]]; then
+			cp "${orig_repo}"/packed-refs "${GIT_DIR}"/packed-refs || die
+		fi
+
+		# (no need to copy HEAD, we will set it via checkout)
+
+		if [[ -f ${orig_repo}/shallow ]]; then
+			cp "${orig_repo}"/shallow "${GIT_DIR}"/ || die
+		fi
+
+		set -- git checkout --quiet
+		if [[ ${remote_ref} ]]; then
+			set -- "${@}" "${remote_ref#refs/heads/}"
+		else
+			set -- "${@}" "${new_commit_id}"
+		fi
+		if [[ ${checkout_paths[@]} ]]; then
+			set -- "${@}" -- "${checkout_paths[@]}"
+		fi
+		echo "${@}" >&2
+		"${@}" || die "git checkout ${remote_ref:-${new_commit_id}} failed"
+	}
+	git-r3_sub_checkout
+	unset -f git-r3_sub_checkout
+
+	local old_commit_id=$(
+		git rev-parse --quiet --verify refs/git-r3/"${local_id}"/__old__
+	)
+	if [[ ! ${old_commit_id} ]]; then
+		echo "GIT NEW branch -->"
+		echo "   repository:               ${repos[0]}"
+		echo "   at the commit:            ${new_commit_id}"
+	else
+		# diff against previous revision
+		echo "GIT update -->"
+		echo "   repository:               ${repos[0]}"
+		# write out message based on the revisions
+		if [[ "${old_commit_id}" != "${new_commit_id}" ]]; then
+			echo "   updating from commit:     ${old_commit_id}"
+			echo "   to commit:                ${new_commit_id}"
+
+			set -- git --no-pager diff --stat \
+				${old_commit_id}..${new_commit_id}
+			if [[ ${checkout_paths[@]} ]]; then
+				set -- "${@}" -- "${checkout_paths[@]}"
+			fi
+			"${@}"
+		else
+			echo "   at the commit:            ${new_commit_id}"
+		fi
+	fi
+	git update-ref --no-deref refs/git-r3/"${local_id}"/{__old__,__main__} || die
+
+	# recursively checkout submodules
+	if [[ -f ${out_dir}/.gitmodules && ! ${checkout_paths} ]]; then
+		local submodules
+		_git-r3_set_submodules \
+			"$(<"${out_dir}"/.gitmodules)"
+
+		while [[ ${submodules[@]} ]]; do
+			local subname=${submodules[0]}
+			local url=${submodules[1]}
+			local path=${submodules[2]}
+
+			# use only submodules for which path does exist
+			# (this is in par with 'git submodule'), bug #551100
+			if [[ -d ${out_dir}/${path} ]]; then
+				local subrepos
+				_git-r3_set_subrepos "${url}" "${repos[@]}"
+
+				git-r3_checkout "${subrepos[*]}" "${out_dir}/${path}" \
+					"${local_id}/${subname}"
+			fi
+
+			submodules=( "${submodules[@]:3}" ) # shift
+		done
+	fi
+
+	# keep this *after* submodules
+	export EGIT_DIR=${GIT_DIR}
+	export EGIT_VERSION=${new_commit_id}
+}
+
+# @FUNCTION: git-r3_peek_remote_ref
+# @USAGE: [<repo-uri> [<remote-ref>]]
+# @DESCRIPTION:
+# Peek the reference in the remote repository and print the matching
+# (newest) commit SHA1.
+#
+# <repo-uri> specifies the repository URIs to fetch from, as a space-
+# -separated list. When not specified, defaults to ${EGIT_REPO_URI}.
+#
+# <remote-ref> specifies the remote ref to peek.  It is preferred to use
+# 'refs/heads/<branch-name>' for branches and 'refs/tags/<tag-name>'
+# for tags. Alternatively, 'HEAD' may be used for upstream default
+# branch. Defaults to the first of EGIT_COMMIT, EGIT_BRANCH or literal
+# 'HEAD' that is set to a non-null value.
+#
+# The operation will be done purely on the remote, without using local
+# storage. If commit SHA1 is provided as <remote-ref>, the function will
+# fail due to limitations of git protocol.
+#
+# On success, the function returns 0 and writes hexadecimal commit SHA1
+# to stdout. On failure, the function returns 1.
+git-r3_peek_remote_ref() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local repos
+	if [[ ${1} ]]; then
+		repos=( ${1} )
+	elif [[ $(declare -p EGIT_REPO_URI) == "declare -a"* ]]; then
+		repos=( "${EGIT_REPO_URI[@]}" )
+	else
+		repos=( ${EGIT_REPO_URI} )
+	fi
+
+	local branch=${EGIT_BRANCH:+refs/heads/${EGIT_BRANCH}}
+	local remote_ref=${2:-${EGIT_COMMIT:-${branch:-HEAD}}}
+
+	[[ ${repos[@]} ]] || die "No URI provided and EGIT_REPO_URI unset"
+
+	local r success
+	for r in "${repos[@]}"; do
+		einfo "Peeking \e[1m${remote_ref}\e[22m on \e[1m${r}\e[22m ..." >&2
+
+		local lookup_ref
+		if [[ ${remote_ref} == refs/* || ${remote_ref} == HEAD ]]
+		then
+			lookup_ref=${remote_ref}
+		else
+			# ls-remote by commit is going to fail anyway,
+			# so we may as well pass refs/tags/ABCDEF...
+			lookup_ref=refs/tags/${remote_ref}
+		fi
+
+		# split on whitespace
+		local ref=(
+			$(git ls-remote "${r}" "${lookup_ref}")
+		)
+
+		if [[ ${ref[0]} ]]; then
+			echo "${ref[0]}"
+			return 0
+		fi
+	done
+
+	return 1
+}
+
+git-r3_src_fetch() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	if [[ ! ${EGIT3_STORE_DIR} && ${EGIT_STORE_DIR} ]]; then
+		ewarn "You have set EGIT_STORE_DIR but not EGIT3_STORE_DIR. Please consider"
+		ewarn "setting EGIT3_STORE_DIR for git-r3.eclass. It is recommended to use"
+		ewarn "a different directory than EGIT_STORE_DIR to ease removing old clones"
+		ewarn "when git-2 eclass becomes deprecated."
+	fi
+
+	_git-r3_env_setup
+	git-r3_fetch
+}
+
+git-r3_src_unpack() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	_git-r3_env_setup
+	git-r3_src_fetch
+	git-r3_checkout
+}
+
+# https://bugs.gentoo.org/show_bug.cgi?id=482666
+git-r3_pkg_needrebuild() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local new_commit_id=$(git-r3_peek_remote_ref)
+	[[ ${new_commit_id} && ${EGIT_VERSION} ]] || die "Lookup failed"
+
+	if [[ ${EGIT_VERSION} != ${new_commit_id} ]]; then
+		einfo "Update from \e[1m${EGIT_VERSION}\e[22m to \e[1m${new_commit_id}\e[22m"
+	else
+		einfo "Local and remote at \e[1m${EGIT_VERSION}\e[22m"
+	fi
+
+	[[ ${EGIT_VERSION} != ${new_commit_id} ]]
+}
+
+# 'export' locally until this gets into EAPI
+pkg_needrebuild() { git-r3_pkg_needrebuild; }
+
+_GIT_R3=1
+fi
diff --git a/eclass/git.eclass b/eclass/git.eclass
new file mode 100644
index 0000000..3088709
--- /dev/null
+++ b/eclass/git.eclass
@@ -0,0 +1,470 @@
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/eclass/git.eclass,v 1.58 2011/12/14 23:40:18 vapier Exp $
+
+# @DEPRECATED
+# This eclass has been superseded by git-2 eclass.
+# Please modify your ebuilds to use that one instead.
+
+# @ECLASS: git.eclass
+# @MAINTAINER:
+# Donnie Berkholz <dberkholz@gentoo.org>
+# @BLURB: Fetching and unpacking of git repositories
+# @DESCRIPTION:
+# The git eclass provides functions to fetch, patch and bootstrap
+# software sources from git repositories and is based on the subversion eclass.
+# It is necessary to define at least the EGIT_REPO_URI variable.
+# @THANKS TO:
+# Fernando J. Pereda <ferdy@gentoo.org>
+
+inherit eutils
+
+EGIT="git.eclass"
+
+# We DEPEND on a not too ancient git version
+DEPEND=">=dev-vcs/git-1.6"
+
+EXPORTED_FUNCTIONS="src_unpack"
+case "${EAPI:-0}" in
+	4|3|2) EXPORTED_FUNCTIONS="${EXPORTED_FUNCTIONS} src_prepare" ;;
+	1|0) ;;
+	*) die "EAPI=${EAPI} is not supported" ;;
+esac
+EXPORT_FUNCTIONS ${EXPORTED_FUNCTIONS}
+
+# define some nice defaults but only if nothing is set already
+: ${HOMEPAGE:=http://git-scm.com/}
+
+# @ECLASS-VARIABLE: EGIT_QUIET
+# @DESCRIPTION:
+# Set to non-empty value to supress some eclass messages.
+: ${EGIT_QUIET:=${ESCM_QUIET}}
+
+# @ECLASS-VARIABLE: EGIT_STORE_DIR
+# @DESCRIPTION:
+# Storage directory for git sources.
+# Can be redefined.
+: ${EGIT_STORE_DIR:="${PORTAGE_ACTUAL_DISTDIR-${DISTDIR}}/git-src"}
+
+# @ECLASS-VARIABLE: EGIT_UNPACK_DIR
+# @DESCRIPTION:
+# Directory to unpack git sources in.
+
+# @ECLASS-VARIABLE: EGIT_HAS_SUBMODULES
+# @DESCRIPTION:
+# Set this to non-empty value to enable submodule support (slower).
+: ${EGIT_HAS_SUBMODULES:=}
+
+# @ECLASS-VARIABLE: EGIT_FETCH_CMD
+# @DESCRIPTION:
+# Command for cloning the repository.
+: ${EGIT_FETCH_CMD:="git clone"}
+
+# @ECLASS-VARIABLE: EGIT_UPDATE_CMD
+# @DESCRIPTION:
+# Git fetch command.
+if [[ -n ${EGIT_HAS_SUBMODULES} ]]; then
+	EGIT_UPDATE_CMD="git pull -f -u"
+else
+	EGIT_UPDATE_CMD="git fetch -f -u"
+fi
+
+# @ECLASS-VARIABLE: EGIT_DIFFSTAT_CMD
+# @DESCRIPTION:
+# Git command for diffstat.
+EGIT_DIFFSTAT_CMD="git --no-pager diff --stat"
+
+# @ECLASS-VARIABLE: EGIT_OPTIONS
+# @DESCRIPTION:
+# This variable value is passed to clone and fetch.
+: ${EGIT_OPTIONS:=}
+
+# @ECLASS-VARIABLE: EGIT_MASTER
+# @DESCRIPTION:
+# Variable for specifying master branch.
+# Usefull when upstream don't have master branch.
+: ${EGIT_MASTER:=master}
+
+# @ECLASS-VARIABLE: EGIT_REPO_URI
+# @DESCRIPTION:
+# URI for the repository
+# e.g. http://foo, git://bar
+# Supported protocols:
+#   http://
+#   https://
+#   git://
+#   git+ssh://
+#   rsync://
+#   ssh://
+eval X="\$${PN//[-+]/_}_LIVE_REPO"
+if [[ ${X} = "" ]]; then
+	: ${EGIT_REPO_URI:=}
+else
+	EGIT_REPO_URI="${X}"
+fi
+# @ECLASS-VARIABLE: EGIT_PROJECT
+# @DESCRIPTION:
+# Project name, it must be unique across EGIT_STORE_DIR.
+# Git eclass will check out the git repository into ${EGIT_STORE_DIR}/${EGIT_PROJECT}/${EGIT_REPO_URI##*/}
+# Default is ${PN}.
+: ${EGIT_PROJECT:=${PN}}
+
+# @ECLASS-VARIABLE: EGIT_BOOTSTRAP
+# @DESCRIPTION:
+# bootstrap script or command like autogen.sh or etc...
+: ${EGIT_BOOTSTRAP:=}
+
+# @ECLASS-VARIABLE: EGIT_OFFLINE
+# @DESCRIPTION:
+# Set this variable to a non-empty value to disable the automatic updating of
+# an GIT source tree. This is intended to be set outside the git source
+# tree by users.
+: ${EGIT_OFFLINE:=${ESCM_OFFLINE}}
+
+# @ECLASS-VARIABLE: EGIT_PATCHES
+# @DESCRIPTION:
+# Similar to PATCHES array from base.eclass
+# Only difference is that this patches are applied before bootstrap.
+# Please take note that this variable should be bash array.
+
+# @ECLASS-VARIABLE: EGIT_BRANCH
+# @DESCRIPTION:
+# git eclass can fetch any branch in git_fetch().
+eval X="\$${PN//[-+]/_}_LIVE_BRANCH"
+if [[ "${X}" = "" ]]; then
+	: ${EGIT_BRANCH:=master}
+else
+	EGIT_BRANCH="${X}"
+fi
+
+# @ECLASS-VARIABLE: EGIT_COMMIT
+# @DESCRIPTION:
+# git eclass can checkout any commit.
+eval X="\$${PN//[-+]/_}_LIVE_COMMIT"
+if [[ "${X}" = "" ]]; then
+	: ${EGIT_COMMIT:=${EGIT_BRANCH}}
+else
+	EGIT_COMMIT="${X}"
+fi
+
+# @ECLASS-VARIABLE: EGIT_REPACK
+# @DESCRIPTION:
+# Set to non-empty value to repack objects to save disk space. However this can
+# take a long time with VERY big repositories.
+: ${EGIT_REPACK:=}
+
+# @ECLASS-VARIABLE: EGIT_PRUNE
+# @DESCRIPTION:
+# Set to non-empty value to prune loose objects on each fetch. This is useful
+# if upstream rewinds and rebases branches often.
+: ${EGIT_PRUNE:=}
+
+# @FUNCTION: git_submodules
+# @DESCRIPTION:
+# Internal function wrapping the submodule initialisation and update
+git_submodules() {
+	if [[ -n ${EGIT_HAS_SUBMODULES} ]]; then
+		debug-print "git submodule init"
+		git submodule init
+		debug-print "git submodule sync"
+		git submodule sync
+		debug-print "git submodule update"
+		git submodule update
+	fi
+}
+
+# @FUNCTION: git_branch
+# @DESCRIPTION:
+# Internal function that changes branch for the repo based on EGIT_TREE and
+# EGIT_BRANCH variables.
+git_branch() {
+	local branchname=branch-${EGIT_BRANCH} src=origin/${EGIT_BRANCH}
+	if [[ "${EGIT_COMMIT}" != "${EGIT_BRANCH}" ]]; then
+		branchname=tree-${EGIT_COMMIT}
+		src=${EGIT_COMMIT}
+	fi
+	debug-print "git checkout -b ${branchname} ${src}"
+	git checkout -b ${branchname} ${src} &> /dev/null
+
+	unset branchname src
+}
+
+# @FUNCTION: git_fetch
+# @DESCRIPTION:
+# Gets repository from EGIT_REPO_URI and store it in specified EGIT_STORE_DIR
+git_fetch() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	eqawarn "git.eclass is deprecated."
+	eqawarn "Please update your ebuilds to use git-2 instead. For details, see"
+	eqawarn "http://archives.gentoo.org/gentoo-dev/msg_b7ba363cae580845819ae3501fb157e9.xml"
+
+	local GIT_DIR EGIT_CLONE_DIR oldsha1 cursha1 extra_clone_opts upstream_branch
+	[[ -z ${EGIT_HAS_SUBMODULES} ]] && export GIT_DIR
+
+	# choose if user wants elog or just einfo.
+	if [[ -n ${EGIT_QUIET} ]]; then
+		elogcmd="einfo"
+	else
+		elogcmd="elog"
+	fi
+
+	# If we have same branch and the tree we can do --depth 1 clone
+	# which outputs into really smaller data transfers.
+	# Sadly we can do shallow copy for now because quite a few packages need .git
+	# folder.
+	#[[ ${EGIT_COMMIT} = ${EGIT_BRANCH} ]] && \
+	#	EGIT_FETCH_CMD="${EGIT_FETCH_CMD} --depth 1"
+	if [[ -n ${EGIT_TREE} ]] ; then
+		EGIT_COMMIT=${EGIT_TREE}
+		ewarn "QA: Usage of deprecated EGIT_TREE variable detected."
+		ewarn "QA: Use EGIT_COMMIT variable instead."
+	fi
+
+	# EGIT_REPO_URI is empty.
+	[[ -z ${EGIT_REPO_URI} ]] && die "${EGIT}: EGIT_REPO_URI is empty."
+
+	# check for the protocol or pull from a local repo.
+	if [[ -z ${EGIT_REPO_URI%%:*} ]] ; then
+		case ${EGIT_REPO_URI%%:*} in
+			git*|http|https|rsync|ssh) ;;
+			*) die "${EGIT}: protocol for fetch from "${EGIT_REPO_URI%:*}" is not yet implemented in eclass." ;;
+		esac
+	fi
+
+	# initial clone, we have to create master git storage directory and play
+	# nicely with sandbox
+	if [[ ! -d ${EGIT_STORE_DIR} ]] ; then
+		debug-print "${FUNCNAME}: initial clone. creating git directory"
+		addwrite /
+		mkdir -m 775 -p "${EGIT_STORE_DIR}" \
+			|| die "${EGIT}: can't mkdir ${EGIT_STORE_DIR}."
+		export SANDBOX_WRITE="${SANDBOX_WRITE%%:/}"
+	fi
+
+	cd -P "${EGIT_STORE_DIR}" || die "${EGIT}: can't chdir to ${EGIT_STORE_DIR}"
+	EGIT_STORE_DIR=${PWD}
+
+	# allow writing into EGIT_STORE_DIR
+	addwrite "${EGIT_STORE_DIR}"
+
+	[[ -z ${EGIT_REPO_URI##*/} ]] && EGIT_REPO_URI="${EGIT_REPO_URI%/}"
+	EGIT_CLONE_DIR="${EGIT_PROJECT}"
+
+	debug-print "${FUNCNAME}: EGIT_OPTIONS = \"${EGIT_OPTIONS}\""
+
+	GIT_DIR="${EGIT_STORE_DIR}/${EGIT_CLONE_DIR}"
+	# we also have to remove all shallow copied repositories
+	# and fetch them again
+	if [[ -e "${GIT_DIR}/shallow" ]]; then
+		rm -rf "${GIT_DIR}"
+		einfo "The ${EGIT_CLONE_DIR} was shallow copy. Refetching."
+	fi
+	# repack from bare copy to normal one
+	if [[ -n ${EGIT_HAS_SUBMODULES} ]] && [[ -d ${GIT_DIR} && ! -d ${GIT_DIR}/.git ]]; then
+		rm -rf "${GIT_DIR}"
+		einfo "The ${EGIT_CLONE_DIR} was bare copy. Refetching."
+	fi
+	if [[ -z ${EGIT_HAS_SUBMODULES} ]] && [[ -d ${GIT_DIR} && -d ${GIT_DIR}/.git ]]; then
+		rm -rf "${GIT_DIR}"
+		einfo "The ${EGIT_CLONE_DIR} was not a bare copy. Refetching."
+	fi
+
+	if [[ -n ${EGIT_HAS_SUBMODULES} ]]; then
+		upstream_branch=origin/${EGIT_BRANCH}
+	else
+		upstream_branch=${EGIT_BRANCH}
+		extra_clone_opts=--bare
+	fi
+
+	if [[ ! -d ${GIT_DIR} ]] ; then
+		# first clone
+		${elogcmd} "GIT NEW clone -->"
+		${elogcmd} "   repository: 		${EGIT_REPO_URI}"
+
+		debug-print "${EGIT_FETCH_CMD} ${extra_clone_opts} ${EGIT_OPTIONS} \"${EGIT_REPO_URI}\" ${GIT_DIR}"
+		${EGIT_FETCH_CMD} ${extra_clone_opts} ${EGIT_OPTIONS} "${EGIT_REPO_URI}" ${GIT_DIR} \
+			|| die "${EGIT}: can't fetch from ${EGIT_REPO_URI}."
+
+		pushd "${GIT_DIR}" &> /dev/null
+		cursha1=$(git rev-parse ${upstream_branch})
+		${elogcmd} "   at the commit:		${cursha1}"
+
+		git_submodules
+		popd &> /dev/null
+	elif [[ -n ${EGIT_OFFLINE} ]] ; then
+		pushd "${GIT_DIR}" &> /dev/null
+		cursha1=$(git rev-parse ${upstream_branch})
+		${elogcmd} "GIT offline update -->"
+		${elogcmd} "   repository: 		${EGIT_REPO_URI}"
+		${elogcmd} "   at the commit:		${cursha1}"
+		popd &> /dev/null
+	else
+		pushd "${GIT_DIR}" &> /dev/null
+		# Git urls might change, so unconditionally set it here
+		git config remote.origin.url "${EGIT_REPO_URI}"
+
+		# fetch updates
+		${elogcmd} "GIT update -->"
+		${elogcmd} "   repository: 		${EGIT_REPO_URI}"
+
+		oldsha1=$(git rev-parse ${upstream_branch})
+
+		if [[ -n ${EGIT_HAS_SUBMODULES} ]]; then
+			debug-print "${EGIT_UPDATE_CMD} ${EGIT_OPTIONS}"
+			# fix branching
+			git checkout ${EGIT_MASTER}
+			for x in $(git branch |grep -v "* ${EGIT_MASTER}" |tr '\n' ' '); do
+				git branch -D ${x}
+			done
+			${EGIT_UPDATE_CMD} ${EGIT_OPTIONS} \
+				|| die "${EGIT}: can't update from ${EGIT_REPO_URI}."
+		else
+			debug-print "${EGIT_UPDATE_CMD} ${EGIT_OPTIONS} origin ${EGIT_BRANCH}:${EGIT_BRANCH}"
+			${EGIT_UPDATE_CMD} ${EGIT_OPTIONS} origin ${EGIT_BRANCH}:${EGIT_BRANCH} \
+				|| die "${EGIT}: can't update from ${EGIT_REPO_URI}."
+		fi
+
+		git_submodules
+		cursha1=$(git rev-parse ${upstream_branch})
+
+		# write out message based on the revisions
+		if [[ "${oldsha1}" != "${cursha1}" ]]; then
+			${elogcmd} "   updating from commit:	${oldsha1}"
+			${elogcmd} "   to commit:		${cursha1}"
+		else
+			${elogcmd} "   at the commit: 		${cursha1}"
+			# @ECLASS-VARIABLE: LIVE_FAIL_FETCH_IF_REPO_NOT_UPDATED
+			# @DESCRIPTION:
+			# If this variable is set to TRUE in make.conf or somewhere in
+			# enviroment the package will fail if there is no update, thus in
+			# combination with --keep-going it would lead in not-updating
+			# pakcages that are up-to-date.
+			# TODO: this can lead to issues if more projects/packages use same repo
+			[[ ${LIVE_FAIL_FETCH_IF_REPO_NOT_UPDATED} = true ]] && \
+				debug-print "${FUNCNAME}: Repository \"${EGIT_REPO_URI}\" is up-to-date. Skipping." && \
+				die "${EGIT}: Repository \"${EGIT_REPO_URI}\" is up-to-date. Skipping."
+		fi
+		${EGIT_DIFFSTAT_CMD} ${oldsha1}..${upstream_branch}
+		popd &> /dev/null
+	fi
+
+	pushd "${GIT_DIR}" &> /dev/null
+	if [[ -n ${EGIT_REPACK} ]] || [[ -n ${EGIT_PRUNE} ]]; then
+		ebegin "Garbage collecting the repository"
+		local args
+		[[ -n ${EGIT_PRUNE} ]] && args='--prune'
+		git gc ${args}
+		eend $?
+	fi
+	popd &> /dev/null
+
+	# export the git version
+	export EGIT_VERSION="${cursha1}"
+
+	# log the repo state
+	[[ "${EGIT_COMMIT}" != "${EGIT_BRANCH}" ]] && ${elogcmd} "   commit:			${EGIT_COMMIT}"
+	${elogcmd} "   branch: 			${EGIT_BRANCH}"
+	${elogcmd} "   storage directory: 	\"${GIT_DIR}\""
+
+	if [[ -n ${EGIT_HAS_SUBMODULES} ]]; then
+		pushd "${GIT_DIR}" &> /dev/null
+		debug-print "rsync -rlpgo . \"${EGIT_UNPACK_DIR:-${S}}\""
+		time rsync -rlpgo . "${EGIT_UNPACK_DIR:-${S}}"
+		popd &> /dev/null
+	else
+		unset GIT_DIR
+		debug-print "git clone -l -s -n \"${EGIT_STORE_DIR}/${EGIT_CLONE_DIR}\" \"${EGIT_UNPACK_DIR:-${S}}\""
+		git clone -l -s -n "${EGIT_STORE_DIR}/${EGIT_CLONE_DIR}" "${EGIT_UNPACK_DIR:-${S}}"
+	fi
+
+	pushd "${EGIT_UNPACK_DIR:-${S}}" &> /dev/null
+	git_branch
+	# submodules always reqire net (thanks to branches changing)
+	[[ -z ${EGIT_OFFLINE} ]] && git_submodules
+	popd &> /dev/null
+
+	echo ">>> Unpacked to ${EGIT_UNPACK_DIR:-${S}}"
+}
+
+# @FUNCTION: git_bootstrap
+# @DESCRIPTION:
+# Runs bootstrap command if EGIT_BOOTSTRAP variable contains some value
+# Remember that what ever gets to the EGIT_BOOTSTRAP variable gets evaled by bash.
+git_bootstrap() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	if [[ -n ${EGIT_BOOTSTRAP} ]] ; then
+		pushd "${S}" > /dev/null
+		einfo "Starting bootstrap"
+
+		if [[ -f ${EGIT_BOOTSTRAP} ]]; then
+			# we have file in the repo which we should execute
+			debug-print "$FUNCNAME: bootstraping with file \"${EGIT_BOOTSTRAP}\""
+
+			if [[ -x ${EGIT_BOOTSTRAP} ]]; then
+				eval "./${EGIT_BOOTSTRAP}" \
+					|| die "${EGIT}: bootstrap script failed"
+			else
+				eerror "\"${EGIT_BOOTSTRAP}\" is not executable."
+				eerror "Report upstream, or bug ebuild maintainer to remove bootstrap command."
+				die "${EGIT}: \"${EGIT_BOOTSTRAP}\" is not executable."
+			fi
+		else
+			# we execute some system command
+			debug-print "$FUNCNAME: bootstraping with commands \"${EGIT_BOOTSTRAP}\""
+
+			eval "${EGIT_BOOTSTRAP}" \
+				|| die "${EGIT}: bootstrap commands failed."
+
+		fi
+
+		einfo "Bootstrap finished"
+		popd > /dev/null
+	fi
+}
+
+# @FUNCTION: git_apply_patches
+# @DESCRIPTION:
+# Apply patches from EGIT_PATCHES bash array.
+# Preferred is using the variable as bash array but for now it allows to write
+# it also as normal space separated string list. (This part of code should be
+# removed when all ebuilds get converted on bash array).
+git_apply_patches() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	pushd "${EGIT_UNPACK_DIR:-${S}}" > /dev/null
+	if [[ ${#EGIT_PATCHES[@]} -gt 1 ]] ; then
+		for i in "${EGIT_PATCHES[@]}"; do
+			debug-print "$FUNCNAME: git_autopatch: patching from ${i}"
+			epatch "${i}"
+		done
+	elif [[ -n ${EGIT_PATCHES} ]]; then
+		# no need for loop if space separated string is passed.
+		debug-print "$FUNCNAME: git_autopatch: patching from ${EGIT_PATCHES}"
+		epatch "${EGIT_PATCHES}"
+	fi
+
+	popd > /dev/null
+}
+
+# @FUNCTION: git_src_unpack
+# @DESCRIPTION:
+# src_upack function, calls src_prepare one if EAPI!=2.
+git_src_unpack() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	git_fetch || die "${EGIT}: unknown problem in git_fetch()."
+
+	has src_prepare ${EXPORTED_FUNCTIONS} || git_src_prepare
+}
+
+# @FUNCTION: git_src_prepare
+# @DESCRIPTION:
+# src_prepare function for git stuff. Patches, bootstrap...
+git_src_prepare() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	git_apply_patches
+	git_bootstrap
+}