thiagowfx's avatar

¬ just serendipity 🍀 (not just serendipity)

git: cd from worktree to main checkout

• 230 words • 2 min

Previously.

Problem statement: make my cdg shortcut jump from a linked Git worktree back to the main checkout when already at the worktree root.

The shortcut originally stopped at the current checkout’s root:

shell
alias cdg='cd "$(git root)"'

I wanted two consecutive calls from a worktree subdirectory to behave like the following:

text
worktree/subdirectory
        ↓ cdg
worktree (at the root)
        ↓ cdg
main checkout (at the root)

An alias cannot succinctly express the necessary conditional behavior, whereas an external script cannot change its parent shell’s working directory. A shell function can:

shell
cdg() {
	# This file is sourced by bash and zsh, both of which support local.
	# shellcheck disable=SC3043
	local line main_is_bare main_worktree root worktrees

	root=$(git rev-parse --path-format=absolute --show-toplevel) || return

	if [ "$(pwd -P)" != "$root" ]; then
		cd "$root" || return
		return
	fi

	worktrees=$(git worktree list --porcelain) || return
	main_worktree=
	main_is_bare=false
	while IFS= read -r line; do
		case "$line" in
			worktree\ *) main_worktree=${line#worktree } ;;
			bare) main_is_bare=true ;;
			'') break ;;
		esac
	done <<-EOF
	$worktrees
	EOF

	if [ "$main_is_bare" = false ] && [ -n "$main_worktree" ] && [ "$main_worktree" != "$root" ]; then
		cd "$main_worktree" || return
	fi
}

The first entry from git worktree list --porcelain is the main checkout. At its root, cdg remains a no-op. If that entry is a bare repository, it also stays put instead of entering the Git directory.