Files
dotfiles/.config/zsh/autoload/git/git-checkout-worktree

42 lines
1.2 KiB
Bash
Executable File

#!/usr/bin/env zsh
# Checks out the first argument in a worktree at a temporary directory. Then
# spawns an interactive shell inside of it.
# When the shell closes the worktree is tried to be removed. Until that works
# without problems (e.g. dirty), a new shell is spawned to resolve all conflicts
# (e.g. stashing). Finally the temporary directory is deleted.
#
# Instead of dropping in an interactive shell, the commands to execute can be
# passed via stdin.
# TODO: If any conflicts arise, all further shells should be interactive instead
# of looping forever.
emulate -L zsh -o err_return -o no_unset
local REPO_NAME WORKTREE_PATH
REPO_NAME="${$(git rev-parse --show-toplevel):t}"
WORKTREE_PATH="$(mktemp -d -p "" "worktree.XXX.$REPO_NAME.$1")"
trap '
errc=$?
<&2 printf "Exiting abnormally. Check and possibly remove '$WORKTREE_PATH' manually.\n"
return $errc
' INT QUIT TERM EXIT
git worktree add "$WORKTREE_PATH" "$1"
pushd -q "$WORKTREE_PATH"
# Restart the shell until every the worktree is removed
while [[ -e "$WORKTREE_PATH" ]]; do
"$SHELL" && errc=$? || errc=$?
git worktree remove "$WORKTREE_PATH" || true
done
# Reset traps
trap '-' INT QUIT TERM EXIT
popd -q || true
git worktree prune
return $errc