#!/usr/bin/env bash
#
# Seek the working tree to a given commit.
# Copyright (c) Petr Baudis, 2005
#
# Takes the target commit ID to seek to as an argument.
# Seeking will bring the working tree from its current 'HEAD' to a given
# commit. Note that it changes just the 'HEAD' of the working tree, not
# the branch it is corresponding to. It will return to the 'HEAD' of
# the appropriate branch if passed no arguments.
#
# Therefore, for a quick excurse to the past of the 'master' branch:
#
#	$ cg-seek git-pasky-0.1
#	$ cg-diff this master	# will do the correct thing
#	$ cg-seek		# will restore what we had before
#
# For intuitiveness, specifying the branch name (`cg-seek master`) will do
# the right thing too. If you want to migrate your working tree to another
# branch, use `cg-clone`.

USAGE="cg-seek [COMMIT_ID]"
_git_requires_root=1

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

dstcommit=${ARGS[0]}


[ -s $_git/blocked ] && grep -vq '^seeked from ' $_git/blocked && die "action blocked: $(cat $_git/blocked)"

curcommit=$(cg-object-id -c) || exit 1

if [ "$dstcommit" ] && [ "$dstcommit" != "$_git_head" ]; then
	seek_mode=away
else
	seek_mode=back
	dstcommit=$(cg-object-id -c "$_git_head") || exit 1
fi

dstcommit=$(cg-object-id -c "$dstcommit") || exit 1
if [ "$curcommit" != "$dstcommit" ]; then
	tree_timewarp --no-head-update "along" "please rollback" $curcommit $dstcommit
fi

if [ "$seek_mode" = "away" ]; then
	echo "$_git_head" >$_git/head-name
	[ -s $_git/blocked ] || echo "seeked from $_git_head" >$_git/blocked
	# We hold this in a temporary branch so that some of the core
	# GIT tools (git checkout and git-fsck-objects) don't get confused.
	echo "$dstcommit" >$_git/refs/heads/cg-seek-point
	git-symbolic-ref HEAD "refs/heads/cg-seek-point"
else
	git-symbolic-ref HEAD "refs/heads/$_git_head"
	rm $_git/refs/heads/cg-seek-point $_git/head-name
	rm -f $_git/blocked
fi

echo "On commit $dstcommit"
