#!/usr/bin/env bash
#
# Push changes to a remote GIT repository.
# Copyright (c) Petr Baudis, 2005.
#
# It will push your commits to the remote repository, provided that
# your commits follow the last commit in the remote repository.
# Note that if the remote repository is associated with a working
# tree copy, this command won't update that. Use cg-reset at the
# remote side to bring it in sync (but throw away any local changes
# in that tree).
#
# Takes the branch name as an argument, defaulting to "origin".
#
# OPTIONS
# -------
# -t TAG::
#	Tells cg-push to also push the given tag. Note that in the
#	future, cg-push should push tags automatically. Also note
#	that even if you pass `cg-push` the '-t' arguments, your
#	HEAD is still pushed as well in addition to the tags.

USAGE="cg-push [BRANCH_NAME] [-t TAG]..."

. ${COGITO_LIB}cg-Xlib || exit 1

tags=()
while optparse; do
	if optparse -t=; then
		tags[${#tags[@]}]="refs/tags/$OPTARG"
	else
		optfail
	fi
done

name=${ARGS[0]}

[ "$name" ] || { [ -s $_git/branches/origin ] && name=origin; }
[ "$name" ] || die "where to push to?"
uri=$(cat "$_git/branches/$name" 2>/dev/null) || die "unknown branch: $name"

rembranch=master
if echo "$uri" | grep -q '#'; then
	rembranch=$(echo $uri | cut -d '#' -f 2)
	uri=$(echo $uri | cut -d '#' -f 1)
fi
sprembranch=":refs/heads/$rembranch"

if echo "$uri" | grep -q "^http://"; then
	die "pushing over HTTP not supported yet"
elif echo "$uri" | grep -q "^git+ssh://"; then
	git-send-pack "$(echo "$uri" | sed 's#^git+ssh://\([^/]*\)\(/.*\)$#\1:\2#')" $_git_head$sprembranch "${tags[@]}"
elif echo "$uri" | grep -q "^rsync://"; then
        die "pushing over rsync not supported"
elif echo "$uri" | grep -q ":"; then
	echo "WARNING: I guessed the host:path syntax was used and fell back to the git+ssh protocol."
	echo "WARNING: The host:path syntax is evil because it is implicit. Please just use a URI."
	git-send-pack "$uri" $_git_head$sprembranch "${tags[@]}"
else
	remgit="$uri"; [ -d "$remgit/.git" ] && remgit="$remgit/.git"
	if is_same_repo "$_git_objects" "$remgit/objects"; then
		remid="$(cat "$remgit"/refs/heads/$rembranch)" || die "$remgit: no branch $master"
		if [ "$remid" != "$(git-merge-base "$remid" "$(cg-object-id -c)")" ]; then
			echo "ERROR: Remote '$rembranch' has some changes you don't have in your '$_git_head'" >&2
			echo "Try to cg-update from it first, then push." >&2
			exit 1
		fi

		[ -x "$remgit/hooks/update" ] && "$remgit/hooks/update" "$rembranch" "$remid" "$(cg-object-id -c)"
		cg-object-id -c >"$remgit"/refs/heads/$rembranch
		for tag in "${tags[@]}"; do
			cat "$_git"/refs/tags/"$tag" >"$remgit"/refs/tags/"$tag"
		done
		[ -x "$remgit/hooks/post-update" ] && "$remgit/hooks/post-update" "$rembranch"
	else
		git-send-pack "$uri" $_git_head$sprembranch "${tags[@]}"
	fi
fi
