Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Initialize a new git worktree and branch for feature development or bug fixes. Use when: (1) Starting work on a new feature, (2) Beginning a bug fix, (3) Creating an isolated workspace for any task, (4) You want to work in parallel on multiple branches. This skill handles branch naming with conventional branch conventions, worktree creation, and remote push setup.
.claude/skills/aiskillstore-git-workspace-init/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-19 | ✗→✓ | ▲ Improved | 78% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 1626% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 239% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 160% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 281% | 0% |
Initialize an isolated git worktree with a properly named branch following conventional branch naming conventions.
Ask the user for or accept from command arguments:
| Type | Use Case | Example | |------|----------|---------| | feat | New feature | feat/user-authentication | | fix | Bug fix | fix/login-validation-error | | hotfix | Urgent production fix | hotfix/security-patch | | docs | Documentation | docs/api-reference | | refactor | Code restructuring | refactor/extract-service | | test | Test additions | test/auth-integration | | chore | Maintenance | chore/upgrade-dependencies | | perf | Performance improvement | perf/optimize-queries | | ci | CI/CD changes | ci/add-deploy-workflow | | style | Code style/formatting | style/apply-prettier |
A brief description that will become the branch name suffix:
Examples:
user-authenticationvalidation-errordark-modeFormat: <type>/<description>
bash# Examples feat/user-authentication fix/null-pointer-exception hotfix/xss-vulnerability docs/installation-guide refactor/extract-user-service
feat/Add-User → feat/add-userfix/login error → fix/login-errora-z, 0-9, -, /pythonimport re def generate_branch_name(task_type: str, description: str) -> str: """Generate conventional branch name from type and description.""" valid_types = ["feat", "fix", "hotfix", "docs", "refactor", "test", "chore", "perf", "ci", "style"] if task_type not in valid_types: raise ValueError(f"Invalid type '{task_type}'. Must be one of: {', '.join(valid_types)}") # Normalize description normalized = description.lower().strip() # Replace spaces and underscores with hyphens normalized = re.sub(r'[\s_]+', '-', normalized) # Remove invalid characters normalized = re.sub(r'[^a-z0-9-]', '', normalized) # Remove consecutive hyphens normalized = re.sub(r'-+', '-', normalized) # Trim hyphens from ends normalized = normalized.strip('-') return f"{task_type}/{normalized}"
Worktrees allow working on multiple branches simultaneously without stashing or switching.
Worktrees are created in a .worktrees directory at the repository root:
my-project/
├── .worktrees/
│ ├── feat-user-auth/ # Worktree for feat/user-auth
│ └── fix-login-error/ # Worktree for fix/login-error
├── src/
└── ...bash# Get repository root REPO_ROOT=$(git rev-parse --show-toplevel) # Define worktree directory (replace / with - for directory name) BRANCH_NAME="feat/user-authentication" WORKTREE_DIR="$REPO_ROOT/.worktrees/${BRANCH_NAME//\//-}" # Ensure .worktrees directory exists mkdir -p "$REPO_ROOT/.worktrees" # Create worktree with new branch from main/master git worktree add -b "$BRANCH_NAME" "$WORKTREE_DIR" origin/main
pythonimport subprocess import os def create_worktree(branch_name: str, base_branch: str = "main") -> str: """Create a new worktree for the given branch.""" # Get repo root result = subprocess.run( ["git", "rev-parse", "--show-toplevel"], capture_output=True, text=True, check=True ) repo_root = result.stdout.strip() # Create worktree directory name (replace / with -) worktree_dir_name = branch_name.replace("/", "-") worktree_path = os.path.join(repo_root, ".worktrees", worktree_dir_name) # Ensure .worktrees directory exists os.makedirs(os.path.join(repo_root, ".worktrees"), exist_ok=True) # Fetch latest from remote subprocess.run(["git", "fetch", "origin"], check=True) # Create worktree with new branch subprocess.run( ["git", "worktree", "add", "-b", branch_name, worktree_path, f"origin/{base_branch}"], check=True ) return worktree_path
Set up tracking with the remote repository:
bash# From within the new worktree cd "$WORKTREE_DIR" # Push and set upstream git push -u origin "$BRANCH_NAME"
pythondef push_branch(worktree_path: str, branch_name: str): """Push the new branch to remote with tracking.""" subprocess.run( ["git", "-C", worktree_path, "push", "-u", "origin", branch_name], check=True )
After creation, navigate to the new worktree:
bashcd "$WORKTREE_DIR" pwd git status
Important: Inform the user of the new workspace path so they can navigate there in their terminal.
pythonimport subprocess import os import re def generate_branch_name(task_type: str, description: str) -> str: """Generate conventional branch name.""" valid_types = ["feat", "fix", "hotfix", "docs", "refactor", "test", "chore", "perf", "ci", "style"] if task_type not in valid_types: raise ValueError(f"Invalid type. Must be one of: {', '.join(valid_types)}") normalized = description.lower().strip() normalized = re.sub(r'[\s_]+', '-', normalized) normalized = re.sub(r'[^a-z0-9-]', '', normalized) normalized = re.sub(r'-+', '-', normalized) normalized = normalized.strip('-') return f"{task_type}/{normalized}" def init_workspace(task_type: str, description: str, base_branch: str = "main") -> dict: """ Initialize a new git worktree with conventional branch naming. Args: task_type: Type of work (feat, fix, hotfix, docs, refactor, test, chore, perf, ci, style) description: Brief description of the task base_branch: Branch to base the new branch on (default: main) Returns: dict with branch_name, worktree_path, and success status """ # Generate branch name branch_name = generate_branch_name(task_type, description) print(f"Branch name: {branch_name}") # Get repo root result = subprocess.run( ["git", "rev-parse", "--show-toplevel"], capture_output=True, text=True, check=True ) repo_root = result.stdout.strip() # Create worktree path worktree_dir_name = branch_name.replace("/", "-") worktree_path = os.path.join(repo_root, ".worktrees", worktree_dir_name) # Ensure .worktrees exists os.makedirs(os.path.join(repo_root, ".worktrees"), exist_ok=True) # Fetch latest print("Fetching latest from origin...") subprocess.run(["git", "fetch", "origin"], check=True) # Create worktree with new branch print(f"Creating worktree at: {worktree_path}") subprocess.run( ["git", "worktree", "add", "-b", branch_name, worktree_path, f"origin/{base_branch}"], check=True ) # Push branch to remote print(f"Pushing {branch_name} to origin...") subprocess.run( ["git", "-C", worktree_path, "push", "-u", "origin", branch_name], check=True ) # Verify print(f"\nWorkspace initialized!") print(f" Branch: {branch_name}") print(f" Path: {worktree_path}") print(f"\nTo start working:") print(f" cd {worktree_path}") return { "branch_name": branch_name, "worktree_path": worktree_path, "success": True } # Example usage: # init_workspace("feat", "user authentication") # init_workspace("fix", "login validation error") # init_workspace("docs", "API reference update")
| Type | When to Use | |------|-------------| | feat | Adding new functionality | | fix | Fixing a bug | | hotfix | Urgent production fix | | docs | Documentation only | | refactor | Restructuring without behavior change | | test | Adding or fixing tests | | chore | Build, deps, tooling | | perf | Performance improvements | | ci | CI/CD pipeline changes | | style | Formatting, whitespace |
bash# List all worktrees git worktree list # Remove a worktree (when done) git worktree remove <path> # Prune stale worktrees git worktree prune
After your PR is merged:
bash# Remove the worktree git worktree remove .worktrees/feat-user-authentication # Delete the local branch (if not auto-deleted) git branch -d feat/user-authentication # Prune remote tracking branches git fetch --prune
bashfatal: A branch named 'feat/user-auth' already exists.
Solution: Choose a more specific name or check if work is already in progress.
bashfatal: '<path>' already exists
Solution: The worktree already exists. Use git worktree list to find it.
bashfatal: No configured push destination.
Solution: Add a remote first: git remote add origin <url>
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 19,390 | 13,457 | -31% | 1 | 1 | 0% | 585 | 3,154 | +439% | 0 | 0 | — |
case-19 | fail→pass | 39,963 | 30,150 | -25% | 1 | 1 | 0% | 3,004 | 5,349 | +78% | 0 | 0 | — |
case-02 | fail→pass | 13,061 | 8,516 | -35% | 1 | 1 | 0% | 196 | 3,382 | +1626% | 0 | 0 | — |
case-03 | fail→fail | 31,429 | 28,689 | -9% | 1 | 1 | 0% | 337 | 3,212 | +853% | 0 | 0 | — |
case-04 | fail→fail | 32,083 | 23,874 | -26% | 1 | 1 | 0% | 234 | 3,256 | +1291% | 0 | 0 | — |
case-05 | fail→fail | 11,384 | 25,408 | +123% | 1 | 1 | 0% | 1,055 | 3,348 | +217% | 0 | 0 | — |
case-06 | fail→pass | 6,770 | 19,722 | +191% | 1 | 1 | 0% | 992 | 3,362 | +239% | 0 | 0 | — |
case-07 | fail→pass | 12,618 | 31,778 | +152% | 1 | 1 | 0% | 1,491 | 3,875 | +160% | 0 | 0 | — |
case-08 | fail→fail | 20,034 | 39,117 | +95% | 1 | 1 | 0% | 375 | 3,313 | +783% | 0 | 0 | — |
case-09 | fail→fail | 33,570 | 8,645 | -74% | 1 | 1 | 0% | 375 | 3,292 | +778% | 0 | 0 | — |
case-10 | fail→fail | 39,675 | 17,240 | -57% | 1 | 1 | 0% | 228 | 3,142 | +1278% | 0 | 0 | — |
case-11 | fail→fail | 12,759 | 19,519 | +53% | 1 | 1 | 0% | 1,256 | 3,299 | +163% | 0 | 0 | — |
case-12 | fail→pass | 10,117 | 20,606 | +104% | 1 | 1 | 0% | 931 | 3,543 | +281% | 0 | 0 | — |
case-13 | fail→fail | 25,729 | 35,676 | +39% | 1 | 1 | 0% | 1,323 | 4,564 | +245% | 0 | 0 | — |
case-14 | fail→pass | 30,942 | 26,855 | -13% | 1 | 1 | 0% | 1,209 | 4,181 | +246% | 0 | 0 | — |
case-15 | pass→pass | 14,098 | 11,282 | -20% | 1 | 1 | 0% | 1,677 | 3,930 | +134% | 0 | 0 | — |
case-16 | fail→pass | 11,681 | 10,020 | -14% | 1 | 1 | 0% | 1,060 | 3,875 | +266% | 0 | 0 | — |
case-17 | pass→pass | 25,267 | 11,929 | -53% | 1 | 1 | 0% | 810 | 3,780 | +367% | 0 | 0 | — |
case-18 | pass→pass | 10,942 | 8,822 | -19% | 1 | 1 | 0% | 1,010 | 3,294 | +226% | 0 | 0 | — |
case-20 | pass→pass | 33,082 | 13,101 | -60% | 1 | 1 | 0% | 1,567 | 3,526 | +125% | 0 | 0 | — |
case-21 | pass→pass | 23,523 | 11,496 | -51% | 1 | 1 | 0% | 1,634 | 3,960 | +142% | 0 | 0 | — |
case-22 | pass→pass | 28,711 | 18,878 | -34% | 1 | 1 | 0% | 1,578 | 4,282 | +171% | 0 | 0 | — |
case-23 | pass→pass | 11,458 | 34,209 | +199% | 1 | 1 | 0% | 1,118 | 3,723 | +233% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted, and 16 counted toward the lift figure. The other 7 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +30 percentage points is the difference between those two pass rates over the 16 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.