Files
zsh/worktree/worktree.plugin.zsh

73 lines
2.2 KiB
Bash

worktree() {
if [[ "$1" == "" ]]; then
echo "usage: worktree {add,remove} <branch>"
return 1
elif [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
echo "usage: worktree {add,remove} <branch>
Manage git worktrees by branch name."
return 0
fi
local cmd=$1
local branch=$2
if [[ -z "$branch" ]]; then
print -P "%F{red}error:%f missing <branch> argument"
return 1
fi
if ! git rev-parse --git-dir &>/dev/null; then
print -P "%F{red}error:%f not a git repository"
return 1
fi
if [[ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]] && \
[[ "$(git rev-parse --absolute-git-dir)" != "$(git rev-parse --show-toplevel)/.git" ]]
then
print -P "%F{red}error:%f must be run from the main clone, not a worktree"
return 1
fi
case $cmd in
add)
local root=$(git rev-parse --show-toplevel)
local wt_dest=${root:h}/${root:t}@${branch}
git worktree add "$wt_dest" "$branch"
if [ -f $root/.enter ] && [ -f $root/.exit ]; then
ln -s $root/.enter $wt_dest/.enter
ln -s $root/.exit $wt_dest/.exit
_autoenv_authorized $PWD/.enter yes
_autoenv_authorized $PWD/.exit yes
fi
;;
rm|remove)
local wt_path
wt_path=$(git worktree list --porcelain | awk -v b="$branch" \
'/^worktree /{ sub(/^worktree /, ""); p=$0 } /^branch refs\/heads\//{ sub(/^branch refs\/heads\//, ""); if($0==b) print p }')
if [[ -z "$wt_path" ]]; then
print -P "%F{red}error:%f no worktree for branch: $branch"
return 1
fi
if [[ -f "$wt_path/BUILD" ]] || [[ -f "$wt_path/WORKSPACE" ]]; then
if (( $+commands[bazel] )); then
bazel --output_base="$wt_path" clean --expunge
elif [[ -x "$wt_path/bazelw" ]]; then
"$wt_path/bazelw" clean --expunge
fi
fi
git worktree remove "$wt_path" || return 1
local root=$(git rev-parse --show-toplevel)
local parent=${wt_path:h}
while [[ "$parent" != "${root:h}" ]] && [[ -d "$parent" ]]; do
rmdir "$parent" 2>/dev/null || break
parent=${parent:h}
done
;;
*)
print -P "%F{red}error:%f unknown command: $cmd"
return 1
;;
esac
}