Git Worktrees support #26084
Replies: 3 comments 1 reply
-
Can you provide a simple example for how to build a mini project demonstrating this setup and how you would like to use it? |
Beta Was this translation helpful? Give feedback.
-
@notpeter So, in my repo github.com/metta-systems/vesper I have many branches for parallel workstreams. They are all parts of the same project but they are wildly different in the state of completion and even starting point (some are rebased, some are still off of some older trees). One approach I tried was:
This is extremely unwieldy because of a few issues:
Another approachI've tried opening multiple zed windows, each in one of the workspace subpaths of .worktrees folder. That works a bit better, but all maintenance steps are still manual, and there are many zed windows around even though I usually work on one worktree at a time. What am I expecting?Native support for "git worktrees" - these are parts of git config, discoverable via git queries. Basically, I want to either replace branch selector or add one more selector next to it that would switch the active zed workspace to one of the defined git worktree locations (these can really be located ANYWHERE - as you specify the disk path for the subtree in the git cli). Also, I would like to see a native Zed support for creating a worktree - i.e. have a default path pattern where a new worktree would be created for branch X. |
Beta Was this translation helpful? Give feedback.
-
I'm a big fan of using worktrees for larger features, or those that succumb to scope creep. Not sure if it will help with implementation ideas, but below is the bashrc function I made to work with worktrees. All worktrees are stored in a directory next to the repo root directory. # Function to manage Git worktrees interactively (external directory structure, corrected exit path)
worktree() {
# Determine the common .git directory path
local common_git_dir
common_git_dir=$(git rev-parse --git-common-dir 2>/dev/null)
if [[ -z "$common_git_dir" ]]; then
echo "System Alert: Operation must be performed within a Git repository or its worktree." >&2
return 1
fi
# Determine the main repository root path from the common git directory
local main_repo_root_path
main_repo_root_path=$(dirname "$common_git_dir")
# Derive repository name and parent directory from the main repo root
local repo_name
repo_name=$(basename "$main_repo_root_path")
local parent_dir
parent_dir=$(dirname "$main_repo_root_path")
local worktree_base_dir="${parent_dir}/${repo_name}.worktrees"
# Simplified main branch detection (relative to the main repo context)
local main_branch
if git --git-dir="$common_git_dir" --work-tree="$main_repo_root_path" show-ref --verify --quiet refs/heads/main; then
main_branch="main"
else
main_branch="master" # Assumes master if main doesn't exist
fi
local target_name="$1"
if [[ -n "$target_name" ]]; then
# Handle Provided Worktree Name
local target_path="${worktree_base_dir}/${target_name}"
# Check if the absolute path exists in the worktree list
if git worktree list --porcelain | grep "^worktree " | cut -d ' ' -f 2- | grep -q "^${target_path}$"; then
echo "Navigating to existing worktree: $target_path"
cd "$target_path" || return 1
else
# Create new worktree
echo "Worktree '$target_name' not found at expected location. Creating..."
local branch_choice
# List branches from the main repository context
branch_choice=$(git --git-dir="$common_git_dir" --work-tree="$main_repo_root_path" branch --format='%(refname:short)' | fzf --height 15% --reverse --prompt="Select source branch for '$target_name': ")
if [[ -n "$branch_choice" ]]; then
# Ensure the base directory exists
mkdir -p "$worktree_base_dir" || { echo "System Alert: Failed to create base directory $worktree_base_dir" >&2; return 1; }
echo "Executing: git worktree add \"$target_path\" \"$branch_choice\""
# Run git worktree add from the main repo context for consistency
if git --git-dir="$common_git_dir" --work-tree="$main_repo_root_path" worktree add "$target_path" "$branch_choice"; then
echo "Worktree created. Navigating to $target_path"
cd "$target_path" || return 1
else
echo "System Alert: 'git worktree add' command failed." >&2
# Simple cleanup attempt
if [[ -d "$target_path" ]] && ! ls -A "$target_path" | grep -qv '.git'; then
rmdir "$target_path" 2>/dev/null
fi
return 1
fi
else
echo "Worktree creation cancelled."
return 1
fi
fi
else
# Handle No Worktree Name Provided
# List worktree *names* located in the designated external directory
local worktree_names
# Use porcelain format for more reliable parsing
worktree_names=$(git worktree list --porcelain | grep "^worktree " | cut -d ' ' -f 2- | awk -v base="$worktree_base_dir/" '$0 ~ "^" base { sub(base, "", $0); print $0 }')
local selection
local exit_option="Exit (Switch to '$main_branch' in main directory)"
local options="$exit_option\n$worktree_names"
selection=$(echo -e "$options" | fzf --height 25% --reverse --prompt="Select worktree or Exit: ")
if [[ "$selection" == "$exit_option" ]]; then
# Use the correctly identified main repository root path
echo "Navigating to main repository directory '$main_repo_root_path' and checking out '$main_branch'."
cd "$main_repo_root_path" && git switch -f "$main_branch"
elif [[ -n "$selection" ]]; then
# Selection is a worktree name, reconstruct the path
local selected_path="${worktree_base_dir}/${selection}"
if [[ -d "$selected_path" ]]; then
echo "Navigating to selected worktree: $selected_path"
cd "$selected_path" || return 1
else
echo "System Alert: Selected worktree path '$selected_path' not found." >&2
return 1
fi
else
echo "No selection made."
fi
fi
return 0
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Describe the feature
Similar to vscode gitlens extension, support checking out multiple branches into separate work folders and showing them all as multiple independent project trees within one window. (this uses
git worktree
commands underneath)Will add some screeenshots in a bit.
See: https://git-scm.com/docs/git-worktree
Beta Was this translation helpful? Give feedback.
All reactions