Skip to content

Instantly share code, notes, and snippets.

@programaker
Last active February 19, 2026 09:26
Show Gist options
  • Select an option

  • Save programaker/37cac1aaabce5a6c80777b290b8a1c6c to your computer and use it in GitHub Desktop.

Select an option

Save programaker/37cac1aaabce5a6c80777b290b8a1c6c to your computer and use it in GitHub Desktop.
Script to clone or init a repository in a git-worktree setup
#!/bin/zsh
# Usage:
# gitwt <git-uri> Clone an existing repo into a worktree setup
# gitwt -c <project-name> Create a new project from scratch with worktree setup
#
# Examples:
# gitwt git@github.com:commercetools/the-repo-i-want-to-clone.git
# gitwt -c my-new-project
set -euo pipefail
function usage() {
echo "Usage:"
echo " gitwt <git-uri> Clone a repo into a worktree setup"
echo " gitwt -c <project-name> Create a new project with worktree setup"
echo ""
echo "Examples:"
echo " gitwt git@github.com:org/repo.git"
echo " gitwt -c my-new-project"
}
function check_dir() {
local name="$1"
if [[ -d "$name" ]]; then
echo "Error: directory '$name' already exists"
exit 1
fi
}
function link_bare() {
echo "gitdir: ./.bare" > .git
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
}
function create_project() {
local project_name="$1"
local default_branch="main"
local worktree_dir="${project_name}_${default_branch}"
check_dir "$project_name"
echo "Creating new worktree project '$project_name'..."
mkdir "$project_name"
cd "$project_name"
git init --bare .bare
link_bare
git worktree add "$worktree_dir" -b "$default_branch"
echo ""
echo "Done! Your worktree project is ready:"
echo " $project_name/"
echo " .bare/ (git database)"
echo " .git (pointer to .bare)"
echo " $worktree_dir/ (worktree on $default_branch branch)"
echo ""
echo "Next steps:"
echo " cd $project_name/$worktree_dir"
echo " have fun!"
}
function clone_repo() {
local uri="$1"
# Extract repo name from URI
# Handles both SSH (git@github.com:org/repo.git) and HTTPS (https://github.com/org/repo.git)
local repo_name="${uri:t:r}"
if [[ -z "$repo_name" ]]; then
echo "Error: could not extract repository name from '$uri'"
exit 1
fi
check_dir "$repo_name"
echo "Setting up bare worktree repo for '$repo_name'..."
mkdir "$repo_name"
cd "$repo_name"
git clone --bare "$uri" .bare
link_bare
local default_branch=$(git -C .bare symbolic-ref --short HEAD)
local worktree_dir="${repo_name}_${default_branch}"
git worktree add "$worktree_dir" "$default_branch"
git branch --set-upstream-to="origin/$default_branch" "$default_branch"
echo ""
echo "Done! Your worktree repo is ready:"
echo " $repo_name/"
echo " .bare/ (git database)"
echo " .git (pointer to .bare)"
echo " $worktree_dir/ (worktree on $default_branch branch)"
echo ""
echo "Next steps:"
echo " cd $repo_name/$worktree_dir"
echo " have fun!"
}
# --- Main ---
if [[ $# -eq 2 && "$1" == "-c" ]]; then
create_project "$2"
elif [[ $# -eq 1 && "$1" != "-c" ]]; then
clone_repo "$1"
else
usage
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment