Commit 7e51a8858075
Changed files (1)
dots
.config
claude
skills
UsingGitWorktrees
dots/.config/claude/skills/UsingGitWorktrees/SKILL.md
@@ -1,11 +1,11 @@
---
name: UsingGitWorktrees
-description: Creates isolated git worktrees using sibling layout for parallel development. USE WHEN starting feature work that needs isolation from current workspace OR before executing implementation plans OR working on multiple branches simultaneously OR need clean test environment. Creates isolated workspaces as siblings to main worktree.
+description: Creates isolated git worktrees in XDG data directory for parallel development. USE WHEN starting feature work that needs isolation from current workspace OR before executing implementation plans OR working on multiple branches simultaneously OR need clean test environment. Creates worktrees in ~/.local/share/worktrees/<org>/<repo>/<branch>.
---
# UsingGitWorktrees
-Create isolated git workspaces for parallel development using sibling layout.
+Create isolated git workspaces for parallel development using XDG data directory layout.
## Overview
@@ -15,204 +15,100 @@ Git worktrees create isolated working directories that share the same repository
- Clean baseline for new features
- No stashing or switching required
-**Core principle:** Sibling layout keeps worktrees organized as peers, not nested inside each other.
+**Core principle:** All worktrees live in `~/.local/share/worktrees/` following XDG conventions, consistent with lazyworktree.
**Announce at start:** "I'm using the UsingGitWorktrees skill to set up an isolated workspace."
-## Sibling Layout
+## XDG Data Layout
-All worktrees live as siblings under a parent folder:
+All worktrees are organized under `~/.local/share/worktrees/`:
```
-~/projects/my-project/ # parent folder
-├── main/ # main git working tree (main branch)
-├── feature-auth/ # worktree for feature/auth branch
-├── bugfix-123/ # worktree for bugfix/123 branch
-└── experiment-new-api/ # worktree for experiment/new-api
+~/.local/share/worktrees/
+├── vdemeester/
+│ ├── home/
+│ │ ├── main/
+│ │ └── feature-new-host/
+│ └── tektoncd-plumbing/
+│ ├── main/
+│ └── feature-terraform-branch-protection/
+└── tektoncd/
+ └── pipeline/
+ ├── main/
+ └── feature-new-resolver/
```
-### Benefits of Sibling Layout
+Structure: `~/.local/share/worktrees/<org>/<repo>/<branch>/`
+### Benefits
+
+- **XDG compliant:** Follows standard data directory conventions
+- **Centralized:** All worktrees in one global location
- **No .gitignore needed:** Worktrees aren't inside any repo
-- **Clear organization:** All related work in one parent folder
-- **Easy navigation:** `cd ../feature-auth` to switch contexts
-- **No nesting confusion:** Each worktree is independent
-- **Clean main worktree:** No `.worktrees/` folder cluttering the repo
+- **Consistent with lazyworktree:** Same layout as lazyworktree's default
+- **Organization aware:** Grouped by org/owner and repo
+- **Clean source directories:** Your `~/src/` stays clean
-### vs. Nested Layout (NOT used)
+### vs. Other Layouts (NOT used)
-| Aspect | Sibling Layout | Nested Layout |
-|--------|----------------|---------------|
-| Worktree location | Siblings under parent | Inside repo (`.worktrees/`) |
-| Requires .gitignore | No | Yes (easy to forget) |
-| Navigation | `cd ../other-branch` | `cd .worktrees/other-branch` |
-| Visual clutter | None in repo | Extra folder in repo |
-| Risk of tracking | None | High if .gitignore missing |
+| Aspect | XDG Data Layout | Nested Layout | Sibling Layout |
+|--------|-----------------|---------------|----------------|
+| Location | `~/.local/share/worktrees/` | Inside repo (`.worktrees/`) | Project parent folder |
+| Requires .gitignore | No | Yes | No |
+| Centralized | Yes | No | No |
+| lazyworktree compatible | Yes (default) | No | Partial |
-## Detection: Is Repo in Sibling Layout?
+## Determining Org and Repo
-Check if the current repo is set up correctly:
+Extract organization and repository name from git remote:
```bash
-# Get git directory info
-GIT_DIR=$(git rev-parse --git-dir)
+# Get remote URL
+REMOTE_URL=$(git remote get-url origin)
-# Check if .git is a file (worktree) or directory (main repo)
-if [ -f .git ]; then
- # This is a worktree - .git is a file pointing to main repo
- IS_WORKTREE=true
-else
- # This is a main repo - .git is a directory
- IS_WORKTREE=false
+# Parse org/repo from various URL formats
+# SSH: git@github.com:tektoncd/pipeline.git
+# HTTPS: https://github.com/tektoncd/pipeline.git
+# HTTPS with auth: https://user@github.com/tektoncd/pipeline.git
+
+if [[ "$REMOTE_URL" =~ git@[^:]+:([^/]+)/([^/.]+) ]]; then
+ ORG="${BASH_REMATCH[1]}"
+ REPO="${BASH_REMATCH[2]}"
+elif [[ "$REMOTE_URL" =~ https://[^/]+/([^/]+)/([^/.]+) ]]; then
+ ORG="${BASH_REMATCH[1]}"
+ REPO="${BASH_REMATCH[2]}"
fi
-# Get the toplevel of current worktree
-TOPLEVEL=$(git rev-parse --show-toplevel)
-PARENT_DIR=$(dirname "$TOPLEVEL")
-CURRENT_FOLDER=$(basename "$TOPLEVEL")
-
-# Check if parent has sibling worktrees
-# A sibling layout means: parent folder contains the main worktree
-# and worktrees are created as siblings
-git worktree list | while read -r path branch rest; do
- WORKTREE_PARENT=$(dirname "$path")
- if [ "$WORKTREE_PARENT" = "$PARENT_DIR" ]; then
- echo "Sibling layout detected: parent is $PARENT_DIR"
- fi
-done
+# Remove .git suffix if present
+REPO="${REPO%.git}"
```
-### Detection Logic
+## Worktree Creation
-1. **Get worktree list:** `git worktree list` shows all worktrees
-2. **Check parent directories:** All worktrees should share the same parent
-3. **Verify main worktree:** One worktree should be the default branch (main/master)
+### Step 1: Determine Paths
```bash
-# Full detection function
-detect_sibling_layout() {
- local worktree_list
- worktree_list=$(git worktree list --porcelain)
+# Base directory for all worktrees
+WORKTREE_BASE="$HOME/.local/share/worktrees"
- local parents=()
- local main_found=false
-
- while IFS= read -r line; do
- if [[ $line == worktree\ * ]]; then
- path="${line#worktree }"
- parent=$(dirname "$path")
- parents+=("$parent")
- fi
- if [[ $line == branch\ refs/heads/main ]] || [[ $line == branch\ refs/heads/master ]]; then
- main_found=true
- fi
- done <<< "$worktree_list"
-
- # All worktrees should have same parent
- local unique_parents
- unique_parents=$(printf '%s\n' "${parents[@]}" | sort -u | wc -l)
-
- if [ "$unique_parents" -eq 1 ] && [ "$main_found" = true ]; then
- echo "${parents[0]}" # Return parent directory
- return 0
- fi
- return 1
-}
-```
-
-## Migration to Sibling Layout
-
-If a repo is not in sibling layout, offer to migrate:
-
-### Step 1: Explain the Situation
-
-```
-This repository is not set up for sibling worktree layout.
-
-Current location: /home/user/repos/my-project
-Git directory: /home/user/repos/my-project/.git (standard repo)
-
-Sibling layout organizes worktrees as peers:
- ~/projects/my-project/
- ├── main/ ← your repo moves here
- ├── feature-branch/ ← worktrees as siblings
- └── another-branch/
-
-Would you like me to migrate to sibling layout?
-```
-
-### Step 2: Get Migration Target
-
-Ask user where to create the parent folder:
-
-```
-Where should the project parent folder be?
-
-1. ~/projects/my-project/ (Recommended)
-2. ~/src/my-project/
-3. Custom location
-
-Current repo will become: <parent>/main/
-Worktrees will be: <parent>/<branch-name>/
-```
-
-### Step 3: Perform Migration
-
-```bash
-# Variables
-PROJECT_NAME="my-project"
-CURRENT_REPO="/home/user/repos/my-project"
-PARENT_DIR="$HOME/projects/$PROJECT_NAME"
-NEW_MAIN="$PARENT_DIR/main"
-
-# Create parent directory
-mkdir -p "$PARENT_DIR"
-
-# Move current repo to become 'main' worktree
-mv "$CURRENT_REPO" "$NEW_MAIN"
-
-# Navigate to new location
-cd "$NEW_MAIN"
-
-# Verify git still works
-git status
-git worktree list
-```
-
-### Step 4: Verify Migration
-
-```bash
-# Should show:
-# /home/user/projects/my-project/main abc1234 [main]
-
-git worktree list
-
-# Confirm structure
-ls -la "$PARENT_DIR"
-# Should show: main/
-```
-
-## Worktree Creation (Post-Migration)
-
-Once in sibling layout, creating worktrees is simple:
-
-### Step 1: Determine Worktree Path
-
-```bash
-# Get project parent directory
-PARENT_DIR=$(dirname "$(git rev-parse --show-toplevel)")
+# Get org and repo from remote
+REMOTE_URL=$(git remote get-url origin)
+# ... parse ORG and REPO as above ...
# Sanitize branch name for filesystem
BRANCH_NAME="feature/user-authentication"
BRANCH_PATH=$(echo "$BRANCH_NAME" | tr '/' '-') # feature-user-authentication
-# Worktree path is sibling to main
-WORKTREE_PATH="$PARENT_DIR/$BRANCH_PATH"
+# Full worktree path
+WORKTREE_PATH="$WORKTREE_BASE/$ORG/$REPO/$BRANCH_PATH"
```
### Step 2: Create Worktree
```bash
+# Create directory structure
+mkdir -p "$WORKTREE_BASE/$ORG/$REPO"
+
# Create worktree and branch in one command
git worktree add "$WORKTREE_PATH" -b "$BRANCH_NAME"
@@ -297,7 +193,7 @@ make build
```
Worktree created successfully
-Location: ~/projects/my-project/feature-user-authentication
+Location: ~/.local/share/worktrees/myorg/myrepo/feature-user-authentication
Branch: feature/user-authentication
Tests: ✓ 47 passing (2.3s)
@@ -312,34 +208,31 @@ Ready to implement user authentication feature
git worktree list
```
-**Output (sibling layout):**
+**Output:**
```
-/home/user/projects/my-project/main abc1234 [main]
-/home/user/projects/my-project/feature-auth def5678 [feature/auth]
-/home/user/projects/my-project/bugfix-db ghi9012 [bugfix/database]
+/home/user/src/myorg/myrepo abc1234 [main]
+/home/user/.local/share/worktrees/myorg/myrepo/feature-auth def5678 [feature/auth]
+/home/user/.local/share/worktrees/myorg/myrepo/bugfix-db ghi9012 [bugfix/database]
```
-### Navigate Between Worktrees
+### Navigate to Worktree
```bash
-# From main, go to feature-auth
-cd ../feature-auth
+# Direct path
+cd ~/.local/share/worktrees/myorg/myrepo/feature-auth
-# From any worktree, go to main
-cd ../main
-
-# List siblings
-ls ..
+# Or use lazyworktree for interactive selection
+lazyworktree
```
### Remove Worktree
```bash
# Remove worktree (keeps branch)
-git worktree remove ../feature-auth
+git worktree remove ~/.local/share/worktrees/myorg/myrepo/feature-auth
# Force remove (even with uncommitted changes)
-git worktree remove --force ../feature-auth
+git worktree remove --force ~/.local/share/worktrees/myorg/myrepo/feature-auth
```
### Prune Deleted Worktrees
@@ -353,11 +246,10 @@ git worktree prune
| Situation | Action |
|-----------|--------|
-| First time with repo | Check if sibling layout → migrate if not |
-| Create new worktree | `git worktree add ../<branch-path> -b <branch>` |
-| Switch worktrees | `cd ../<other-worktree>` |
+| Create new worktree | `git worktree add ~/.local/share/worktrees/<org>/<repo>/<branch> -b <branch>` |
+| Navigate to worktree | `cd ~/.local/share/worktrees/<org>/<repo>/<branch>` or use `lazyworktree` |
| List worktrees | `git worktree list` |
-| Remove worktree | `git worktree remove ../<worktree>` |
+| Remove worktree | `git worktree remove <path>` |
| Cleanup references | `git worktree prune` |
| Check current branch | `git branch --show-current` |
@@ -368,12 +260,12 @@ Based on your NixOS home repository structure:
### Building a NixOS Configuration
```bash
-# Create worktree for system change (from main/)
-git worktree add ../sakhalin-upgrade -b feature/sakhalin-upgrade
+# From your main home repo at ~/src/home
+git worktree add ~/.local/share/worktrees/vdemeester/home/sakhalin-upgrade -b feature/sakhalin-upgrade
-cd ../sakhalin-upgrade
+cd ~/.local/share/worktrees/vdemeester/home/sakhalin-upgrade
-# Build without switching main worktree
+# Build without affecting main worktree
make host/sakhalin/build
# If successful, deploy
@@ -384,48 +276,58 @@ make host/sakhalin/switch
```bash
# Multiple worktrees for different hosts
-git worktree add ../rhea-jellyfin -b feature/rhea-jellyfin
-git worktree add ../aion-audio -b feature/aion-audio
+git worktree add ~/.local/share/worktrees/vdemeester/home/rhea-jellyfin -b feature/rhea-jellyfin
+git worktree add ~/.local/share/worktrees/vdemeester/home/aion-audio -b feature/aion-audio
# Work on both simultaneously
-cd ../rhea-jellyfin
+cd ~/.local/share/worktrees/vdemeester/home/rhea-jellyfin
make host/rhea/build
-cd ../aion-audio
+cd ~/.local/share/worktrees/vdemeester/home/aion-audio
make host/aion/build
```
-### Testing Flake Changes
+### Working on Tekton Pipeline
```bash
-# Isolated worktree for flake updates
-git worktree add ../flake-update -b chore/flake-update
+# Create worktree for pipeline feature
+cd ~/src/tektoncd/pipeline/main
+git worktree add ~/.local/share/worktrees/tektoncd/pipeline/feature-new-resolver -b feature/new-resolver
-cd ../flake-update
-
-# Update and test
-nix flake update
-make dry-build
-
-# If successful, merge to main
+cd ~/.local/share/worktrees/tektoncd/pipeline/feature-new-resolver
+go test ./...
```
+## Integration with lazyworktree
+
+The XDG data layout is consistent with lazyworktree's default behavior:
+
+```bash
+# Use lazyworktree to navigate between worktrees
+lazyworktree
+
+# Use aliases defined in your config
+wh # Jump to home worktrees
+wtp # Jump to tekton pipeline worktrees
+```
+
+lazyworktree provides:
+- Interactive worktree selection
+- PR/issue integration
+- Quick branch creation
+- Worktree management UI
+
## Common Mistakes
-### ❌ Creating Worktrees Without Sibling Layout
+### ❌ Creating Worktrees in Random Locations
-**Problem:** Worktrees end up in random locations, hard to find
-**Fix:** Always migrate to sibling layout first
+**Problem:** Worktrees scattered across filesystem
+**Fix:** Always use `~/.local/share/worktrees/<org>/<repo>/`
-### ❌ Forgetting to Migrate
+### ❌ Forgetting Org/Repo Structure
-**Problem:** Old repos still use nested `.worktrees/` pattern
-**Fix:** Run migration when skill detects non-sibling layout
-
-### ❌ Using Absolute Paths Instead of Relative
-
-**Problem:** Commands are longer and harder to type
-**Fix:** Use `../branch-name` for sibling navigation
+**Problem:** Flat structure makes it hard to find worktrees
+**Fix:** Always include org and repo in path
### ❌ Proceeding with Failing Tests
@@ -455,12 +357,11 @@ make dry-build
**Cleanup after work:**
```bash
-# Merge work back to main
-cd ../main
+# From main repo, merge work back
git merge feature/user-authentication
# Remove worktree
-git worktree remove ../feature-user-authentication
+git worktree remove ~/.local/share/worktrees/myorg/myrepo/feature-user-authentication
# Delete branch if done
git branch -d feature/user-authentication
@@ -468,35 +369,29 @@ git branch -d feature/user-authentication
## Examples
-**Example 1: First-time setup (migration)**
+**Example 1: Creating a worktree for a new feature**
```
-User: "Set up worktree for new feature"
+User: "Set up worktree for new authentication feature"
→ Invoke UsingGitWorktrees skill
→ Announce: "I'm using the UsingGitWorktrees skill to set up an isolated workspace"
-→ Check: Is repo in sibling layout?
-→ Detect: No - .git is a directory, no sibling worktrees
-→ Explain: "This repo needs migration to sibling layout"
-→ Ask: "Where should the parent folder be? ~/projects/my-project/ recommended"
-→ User confirms
-→ Migrate: mv current-repo ~/projects/my-project/main
-→ Verify: git worktree list shows main
-→ Create: git worktree add ../feature-auth -b feature/auth
-→ Setup and verify
-→ Ready for work
-```
-
-**Example 2: Repo already in sibling layout**
-```
-User: "Create worktree for database migration"
-
-→ Invoke UsingGitWorktrees skill
-→ Check: Is repo in sibling layout?
-→ Detect: Yes - all worktrees share parent ~/projects/my-project/
-→ Create: git worktree add ../db-migration -b feature/db-migration
+→ Parse remote: git@github.com:myorg/myrepo.git → org=myorg, repo=myrepo
+→ Create: git worktree add ~/.local/share/worktrees/myorg/myrepo/feature-auth -b feature/auth
→ Setup: npm install
→ Test: npm test → 47 passing
-→ Report: "Worktree ready at ~/projects/my-project/db-migration"
+→ Report: "Worktree ready at ~/.local/share/worktrees/myorg/myrepo/feature-auth"
+```
+
+**Example 2: Working on home repository**
+```
+User: "Create worktree for sakhalin upgrade"
+
+→ Invoke UsingGitWorktrees skill
+→ Parse remote: git@github.com:vdemeester/home.git → org=vdemeester, repo=home
+→ Create: git worktree add ~/.local/share/worktrees/vdemeester/home/sakhalin-upgrade -b feature/sakhalin-upgrade
+→ Setup: nix develop
+→ Build: make dry-build → success
+→ Report: "Worktree ready at ~/.local/share/worktrees/vdemeester/home/sakhalin-upgrade"
```
**Example 3: Parallel host configurations**
@@ -504,39 +399,37 @@ User: "Create worktree for database migration"
User: "I need to work on both rhea and aion configurations simultaneously"
→ Invoke UsingGitWorktrees skill
-→ Verify sibling layout
-→ Create worktree: git worktree add ../rhea-jellyfin -b feature/rhea-jellyfin
-→ Create worktree: git worktree add ../aion-audio -b feature/aion-audio
+→ Create: ~/.local/share/worktrees/vdemeester/home/rhea-jellyfin
+→ Create: ~/.local/share/worktrees/vdemeester/home/aion-audio
→ Both worktrees have clean baselines
→ Can build and test both in parallel
-→ Switch between with cd ../rhea-jellyfin
+→ Use lazyworktree to switch between them
```
**Example 4: Cleanup after merge**
```
User: "Clean up the authentication worktree now that it's merged"
-→ Navigate to main worktree: cd ../main
→ Verify feature branch merged: git branch --merged
-→ Remove worktree: git worktree remove ../feature-auth
+→ Remove: git worktree remove ~/.local/share/worktrees/myorg/myrepo/feature-auth
→ Delete branch: git branch -d feature/auth
→ Confirm: git worktree list shows worktree removed
-→ ls .. shows only remaining worktrees
```
## Red Flags
**Never:**
-- Create worktrees in non-sibling layout
-- Skip migration when detected
+- Create worktrees outside `~/.local/share/worktrees/`
+- Skip org/repo structure in path
- Proceed with failing tests without explicit permission
- Leave old worktrees around indefinitely
- Commit to wrong branch (verify with `git branch --show-current`)
**Always:**
-- Detect and migrate to sibling layout
-- Use relative paths (`../branch`) for navigation
+- Use XDG data directory: `~/.local/share/worktrees/<org>/<repo>/<branch>`
+- Parse org/repo from git remote
- Auto-detect and run project setup
- Verify clean test baseline
- Report clear status when worktree is ready
- Clean up worktrees when work is merged
+- Use lazyworktree for navigation when available