Skip to content

Instantly share code, notes, and snippets.

@collinvandyck
Last active June 18, 2025 18:44
Show Gist options
  • Select an option

  • Save collinvandyck/648fa902c3c307e0f5f2b97eed47993e to your computer and use it in GitHub Desktop.

Select an option

Save collinvandyck/648fa902c3c307e0f5f2b97eed47993e to your computer and use it in GitHub Desktop.
# an opinionated workflow on using git worktrees
worktrees() {
usage="usage: $(basename "$0")"
error() { echo >&2 "error: $*" }
root() { echo "$(git rev-parse --git-common-dir)/.." }
create-worktree() {
[[ $# -lt 1 ]] && error "$usage: create [name] [--force]" && return 1
name=$1; shift
br="-b"
commit=@
while [[ $# -gt 0 ]]; do
case $1 in
--force|-f) br="-B"
;;
*)
[[ "$commit" != "@" ]] && error "cannot pass more than one ref" && return 1
commit=$1
;;
esac
shift
done
branch="$USER/$name"
if [[ "$br" == "-b" ]] && git rev-parse $branch &>/dev/null; then
error "Branch $branch already exists. Use --force to override" && return 1
fi
root=$(root)
[[ ! -d "$root" ]] && error "not in a git repo!" && return 1
full_path="$root"/worktrees/"$name"
if [[ -d "$full_path" ]]; then
echo "Changing into existing worktree"
else
git worktree add "$full_path" "$br" "$branch" "$commit"
fi
cd "$full_path"
}
remove-worktree() {
[[ $# != 1 ]] && error "$usage: remove [name]" && return 1
root=$(root)
git worktree remove "$1"
cd $root
}
list-worktrees() {
git worktree list
}
case "$1" in
"create")
shift
create-worktree "$@"
;;
"remove")
shift
remove-worktree "$@"
;;
"list")
shift
list-worktrees "$@"
;;
*)
list-worktrees
;;
esac
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment