Fix endless loop when commands are passed via stdin that result in the worktree not being removable. Fix by then dropping into an interactive shell.
42 lines
1.3 KiB
Bash
Executable File
42 lines
1.3 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. If any conflicts arise, all further shells are interactive.
|
|
# TODO: Override with flag that just `stash -u`
|
|
|
|
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"
|
|
|
|
"$SHELL" && errc=$? || errc=$?
|
|
|
|
# Restart the shell (forcefully interactive) until the worktree is removed
|
|
until [[ ! -e "$WORKTREE_PATH" ]] || git worktree remove "$WORKTREE_PATH"; do
|
|
[[ -t 0 ]] || >&2 printf "Dropping into interactive shell to resolve conflicts\n"
|
|
"$SHELL" -i && errc=$? || errc=$?
|
|
done
|
|
|
|
# Reset traps and PWD
|
|
trap '-' INT QUIT TERM EXIT
|
|
popd -q || true
|
|
|
|
git worktree prune
|
|
return $errc
|