Last active
February 19, 2026 09:26
-
-
Save programaker/37cac1aaabce5a6c80777b290b8a1c6c to your computer and use it in GitHub Desktop.
Script to clone or init a repository in a git-worktree setup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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