#!/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