Commit bab6ddc7 authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Do submodule updates in a temp worktree

This removes the need for stashing (nice!) and ensures that the update
checks happen and are pushed regardless of the status of the main
worktree (presumably $HOME).

The main worktree update then just needs to merge the changes if it can
then update all submodules.
parent 110ca86d
Loading
Loading
Loading
Loading
+27 −32
Original line number Diff line number Diff line
@@ -69,27 +69,25 @@ update_worktree()
	if [ -z "$upstream" ]; then
		return 0
	fi
	local stash=`git stash create`
	local original=`git rev-parse HEAD`
	git reset --hard HEAD
	git fetch origin
	test -n "$stash" && git stash apply $stash
	git merge --ff-only $upstream || git reset $original
}

update_submodules()
{
	if git merge --ff --no-edit $upstream; then
		git submodule sync --recursive
		git submodule update --init --recursive

	# do not attempt automatic upgrading if not on master branch
	if [ master != `get_branch` ]; then
		return 0
	else
		git reset $original
	fi
}

update_repos()
(
	git fetch origin

	# stash after sync-update to avoid poisoning the stash
	local stash=`git stash create`
	git reset --hard HEAD
	local worktree=`mktemp -d`
	git worktree add -f $worktree --detach origin/master
	cd $worktree

	git submodule sync --recursive
	git submodule update --init --recursive

	git submodule foreach '
		setting="submodule.${name}.auto-update";
@@ -97,6 +95,7 @@ update_submodules()
		git checkout origin/${branch:-master} || exit 1
		cd ${toplevel};
		git add ${path}'

	local updates="`git status --short -uno`"
	if [ -n "$updates" ]; then
		git commit -F- <<-END_MESSAGE
@@ -109,21 +108,17 @@ update_submodules()
			  time:   `date`
			  host:   `hostname -f`
		END_MESSAGE
	fi
	if [ -n "$stash" ] && ! git stash apply $stash; then
		local msg="Submodule update: uncommited changes (unstash failed)"
		git stash store -m "$msg" $stash
		echo "Failed to unstash changes, the stash has been left on the" \
		     "stack. ($stash)" >&2
		echo "Automatic merge has not been pushed, please check for" \
		     "conflicts and push manually" >&2
	elif ! git push origin master:master; then
		echo "Automatic merge push failed, this may mean the remote" \
		     "'origin' has not been set" >&2

		if git push origin HEAD:master; then
			echo >&2 "Submodules have been updated and pushed to origin"
		else
		echo "Submodules have been updated, merged and pushed to origin" >&2
			echo >&2 "Automatic push failed, this may mean the remote" \
		             "'origin' has not been set"
		fi
}
	fi

	cd && rm -r $worktree
)

do_update()
{
@@ -150,8 +145,8 @@ do_update()

	(cd ~
		set -eu
		update_worktree &&
		update_submodules
		update_repos &&
		update_worktree
	) || return

	touch "$timestamp"