mcpField
G
git-worktree

git-worktree

github.com/julianobarbosa开发15109 次安装今天更新
代码仓库

关于 git-worktree

git-worktree 是通过 Git worktree 管理并行开发环境的技能,适合需要同时处理多个功能或运行多个 Claude Code 实例的开发者。它将 worktree 操作与 tmux 或 iTerm2 终端集成,便于隔离工作目录并切换任务。

主要功能

  1. 01创建和管理 Git worktree
  2. 02集成 tmux 窗口或会话
  3. 03集成 iTerm2 标签页
  4. 04支持并行 Claude Code 开发
  5. 05提供清理与故障排查流程

适用场景

  1. 01并行开发多个功能分支
  2. 02避免切换分支或暂存未提交修改
  3. 03在合并后清理 worktree

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/julianobarbosa/claude-code-skills --skill git-worktree

安装后在 Claude Code 中输入/git-worktree确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
functions.sh
iterm2-config.md
tmux-config.md

详细介绍

Git Worktree 技能

使用 git worktree 管理并行开发环境,并与终端无缝集成。

概览

Git worktree 支持从单个仓库创建多个工作目录:

  • 无需切换分支即可隔离开发功能
  • 并行运行多个 Claude Code 实例
  • 无需暂存未提交的更改即可切换上下文
  • 将实验性工作干净地分隔开

快速命令

wt - Worktree 管理器

wt 命令可创建 worktree,并自动与终端集成:

# Create worktree with tmux window
wt add-new-feature

# This will:
# 1. Create git worktree named 'add-new-feature'
# 2. Create new tmux window in current session
# 3. Rename window to 'add-new-feature'
# 4. Change directory to the worktree

tmux 集成

工作流:创建 Worktree + tmux 窗口
# Function for ~/.zshrc or ~/.bashrc
wt() {
    local name="$1"
    local base_branch="${2:-main}"
    local repo_root=$(git rev-parse --show-toplevel 2>/dev/null)
    local worktree_path="$repo_root/.worktrees/$name"

    # Validate we're in a git repo
    if [[ -z "$repo_root" ]]; then
        echo "Error: Not in a git repository"
        return 1
    fi

    # Create worktree directory
    mkdir -p "$repo_root/.worktrees"

    # Create worktree with new branch
    if git worktree add -b "$name" "$worktree_path" "$base_branch" 2>/dev/null; then
        echo "Created worktree: $worktree_path"
    elif git worktree add "$worktree_path" "$name" 2>/dev/null; then
        echo "Attached to existing branch: $name"
    else
        echo "Error: Failed to create worktree"
        return 1
    fi

    # tmux integration
    if [[ -n "$TMUX" ]]; then
        # Create new window with worktree name
        tmux new-window -n "$name" -c "$worktree_path"
        echo "Created tmux window: $name"
    else
        # Not in tmux, just cd
        cd "$worktree_path"
        echo "Changed to: $worktree_path"
    fi
}

# Remove worktree and tmux window
wt-rm() {
    local name="$1"
    local repo_root=$(git rev-parse --show-toplevel 2>/dev/null)
    local worktree_path="$repo_root/.worktrees/$name"

    # Remove git worktree
    git worktree remove "$worktree_path" --force 2>/dev/null

    # Close tmux window if exists
    if [[ -n "$TMUX" ]]; then
        tmux kill-window -t "$name" 2>/dev/null
    fi

    # Optionally delete branch
    git branch -d "$name" 2>/dev/null

    echo "Removed worktree: $name"
}

# List all worktrees
wt-ls() {
    git worktree list
}
tmux 会话管理
# Create dedicated tmux session per project
wt-session() {
    local name="$1"
    local repo_root=$(git rev-parse --show-toplevel 2>/dev/null)
    local worktree_path="$repo_root/.worktrees/$name"

    # Create worktree first
    wt "$name"

    # Create new tmux session (or attach if exists)
    if tmux has-session -t "$name" 2>/dev/null; then
        tmux attach-session -t "$name"
    else
        tmux new-session -d -s "$name" -c "$worktree_path"
        tmux attach-session -t "$name"
    fi
}

iTerm2 集成

iTerm2 标签页的 AppleScript
# Function for ~/.zshrc
wt-iterm() {
    local name="$1"
    local base_branch="${2:-main}"
    local repo_root=$(git rev-parse --show-toplevel 2>/dev/null)
    local worktree_path="$repo_root/.worktrees/$name"

    # Create worktree
    mkdir -p "$repo_root/.worktrees"
    git worktree add -b "$name" "$worktree_path" "$base_branch" 2>/dev/null || \
    git worktree add "$worktree_path" "$name" 2>/dev/null

    # Open in new iTerm2 tab
    osascript <<EOF
tell application "iTerm2"
    tell current window
        create tab with default profile
        tell current session
            write text "cd '$worktree_path' && clear"
        end tell
    end tell
end tell
EOF

    echo "Created worktree with iTerm2 tab: $name"
}

# Open worktree in new iTerm2 window
wt-iterm-window() {
    local name="$1"
    local base_branch="${2:-main}"
    local repo_root=$(git rev-parse --show-toplevel 2>/dev/null)
    local worktree_path="$repo_root/.worktrees/$name"

    # Create worktree
    mkdir -p "$repo_root/.worktrees"
    git worktree add -b "$name" "$worktree_path" "$base_branch" 2>/dev/null || \
    git worktree add "$worktree_path" "$name" 2>/dev/null

    # Open in new iTerm2 window
    osascript <<EOF
tell application "iTerm2"
    create window with default profile
    tell current session of current window
        write text "cd '$worktree_path' && clear"
    end tell
end tell
EOF

    echo "Created worktree with iTerm2 window: $name"
}
iTerm2 配置集成

为 worktree 创建专用的 iTerm2 配置:

{
  "Name": "Worktree",
  "Badge Text": "WT: \\(session.name)",
  "Working Directory": "$HOME/.worktrees",
  "Custom Directory": "Yes"
}

配置

环境变量
# Add to ~/.zshrc or ~/.bashrc

# Preferred terminal for worktree operations (auto-detected if not set)
export WORKTREE_TERMINAL="tmux"  # or "iterm2" or "auto"

# Auto-install dependencies after creating worktree
export WORKTREE_AUTO_INSTALL=true
Worktree 位置

Worktree 存储在项目目录内:

~/Repos/github/my-project/
├── .worktrees/
│   ├── feature-auth/      # worktree for feature-auth branch
│   ├── bugfix-login/      # worktree for bugfix-login branch
│   └── add-new-skill/     # worktree for add-new-skill branch
├── src/
├── package.json
└── ...
Shell 配置

函数定义在 ~/.zsh/functions.zsh 中(已由你的 zshrc 加载):

# Functions location: ~/.zsh/functions.zsh

# Aliases
alias wt='wt'
alias wtl='wt-ls'
alias wtr='wt-rm'
alias wts='wt-session'

# Completion for wt commands
_wt_completion() {
    local branches=$(git branch --format='%(refname:short)' 2>/dev/null)
    local worktrees=$(git worktree list --porcelain 2>/dev/null | grep '^worktree' | cut -d' ' -f2 | xargs -I{} basename {})
    _alternative \
        "branches:branch:($branches)" \
        "worktrees:worktree:($worktrees)"
}
compdef _wt_completion wt wt-rm

Git Worktree 命令参考

创建 Worktree
# Create worktree with new branch from current HEAD
git worktree add ../feature-x -b feature-x

# Create worktree from specific branch
git worktree add ../hotfix hotfix-branch

# Create worktree from remote branch
git worktree add ../upstream upstream/main

# Create worktree at specific commit
git worktree add ../review abc123
管理 Worktree
# List all worktrees
git worktree list

# Show worktree details (porcelain format)
git worktree list --porcelain

# Lock worktree (prevent pruning)
git worktree lock ../feature-x --reason "WIP"

# Unlock worktree
git worktree unlock ../feature-x

# Remove worktree
git worktree remove ../feature-x

# Force remove (discards changes)
git worktree remove ../feature-x --force

# Prune stale worktrees
git worktree prune
高级操作
# Move worktree to new location
git worktree move ../old-path ../new-path

# Repair worktree after manual move
git worktree repair ../moved-worktree

并行 Claude 开发

运行多个实例
# Create worktrees for parallel development
wt feature-auth
wt feature-api
wt bugfix-login

# Each worktree gets its own:
# - tmux window / iTerm2 tab
# - Git index and working directory
# - Port allocation (if configured)
# - Claude Code instance
端口管理
# Configure port pools per worktree
export WORKTREE_PORT_BASE=8100
export WORKTREE_PORTS_PER_TREE=2

# Calculate ports for worktree
get_worktree_ports() {
    local index=$(git worktree list | grep -n "$PWD" | cut -d: -f1)
    local base=$((WORKTREE_PORT_BASE + (index - 1) * WORKTREE_PORTS_PER_TREE))
    echo "Dev server: $base, API: $((base + 1))"
}

清理工作流

合并并清理
# After PR merge, clean up worktree
wt-cleanup() {
    local name="$1"
    local repo_root=$(git rev-parse --show-toplevel 2>/dev/null)
    local worktree_path="$repo_root/.worktrees/$name"

    # Switch to main worktree
    cd "$repo_root"

    # Update main
    git fetch origin
    git pull origin main

    # Remove worktree
    git worktree remove "$worktree_path" --force

    # Delete branch if merged
    if git branch --merged | grep -q "$name"; then
        git branch -d "$name"
        echo "Branch $name was merged and deleted"
    else
        echo "Branch $name not yet merged, kept locally"
    fi

    # Close tmux window
    [[ -n "$TMUX" ]] && tmux kill-window -t "$name" 2>/dev/null
}
批量清理
# Remove all worktrees with merged branches
wt-cleanup-merged() {
    local main_dir=$(git worktree list | head -1 | awk '{print $1}')

    git worktree list | tail -n +2 | while read -r line; do
        local wt_path=$(echo "$line" | awk '{print $1}')
        local wt_branch=$(echo "$line" | awk '{print $3}' | tr -d '[]')

        if git branch --merged main | grep -q "$wt_branch"; then
            echo "Removing merged worktree: $wt_branch"
            git worktree remove "$wt_path" --force
            git branch -d "$wt_branch"
        fi
    done
}

故障排除

常见问题

Worktree 已存在:

# List existing worktrees
git worktree list

# Remove stale entry
git worktree prune

分支已在其他位置检出:

# Error: 'branch' is already checked out at '/path'
# Solution: Use a different branch name or remove existing worktree
git worktree remove /path/to/existing

tmux 窗口名称冲突:

# Rename existing window first
tmux rename-window -t old-name new-name

# Or kill conflicting window
tmux kill-window -t conflicting-name

iTerm2 AppleScript 错误:

# Ensure iTerm2 is running
open -a iTerm

# Grant automation permissions
# System Preferences > Security & Privacy > Privacy > Automation

参考资料

外部链接


注意事项

  • 主仓库工作树中的 Worktree 路径会让外层 git status 产生混淆——内层 worktree 中的文件会在父目录中显示为未跟踪文件。
  • 任何 worktree 中已检出的分支都无法通过 git branch -d 删除——必须先移除该 worktree。
  • Worktree 共享 .git/config——每个 worktree 的配置需要显式使用 git config --worktree。
  • git worktree prune 会移除孤立记录,但不会删除目录——修剪后需手动清理目录。
  • 锁定 worktree 不会阻止文件系统操作——git worktree lock 只会阻止 git worktree remove;rm -rf 仍然有效。
  • macOS 不区分大小写的文件系统与 worktree:路径仅大小写不同的两个 worktree 可能导致不可预测的 git 行为。

评论

支持 Markdown