Pass all given arguments to `git worktree add`. This makes it possible to directly create a new branch with `-b` for example. As the arguments are not used anywhere else, this should not introduce any parsing issues.
57 lines
1.8 KiB
Bash
Executable File
57 lines
1.8 KiB
Bash
Executable File
#!/usr/bin/env zsh
|
|
|
|
# Create a temporary worktree.
|
|
#
|
|
# Useful for doing quick tasks on other branches without modifying the current
|
|
# working tree. So no broken/outdated symlinks to dotfiles or unnecessary
|
|
# recompiling after switching back for example.
|
|
#
|
|
# 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).
|
|
#
|
|
# 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`
|
|
#
|
|
# Examples for scripted usage:
|
|
# Merge branches without leaving the current one:
|
|
# % git-checkout-worktree main <<<"git merge dev"
|
|
#
|
|
# Same for rebase (as `git rebase dev feature` switches to `feature`):
|
|
# % git-checkout-worktree feature <<<"git rebase dev"
|
|
|
|
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" "$@"
|
|
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
|