Jak pracować nad kilkoma funkcjami jednocześnie bez ciągłego przełączania branchów i stashowania zmian.
Problem
Standardowy workflow: jeden katalog, jeden branch. Chcesz skoczyć na mastera żeby zrobić hotfix - musisz stashować albo commitować niedokończoną pracę. Wracasz - odtwarzasz stan. Jak masz 3 branche w locie, to robi się bałagan.
Git worktree
Git worktree pozwala mieć kilka katalogów roboczych podpiętych do tego samego repozytorium, każdy na innym branchu.
# Twórz worktree na istniejącym branchu
git worktree add ../intum-hotfix master
# Albo na nowym branchu
git worktree add ../intum-feature -b nowy_feature
# Lista worktree
git worktree list
# Usunięcie (po zakończeniu pracy)
git worktree remove ../intum-hotfix
Po tym masz dwa katalogi - każdy z pełnym kodem na swoim branchu. Możesz mieć odpalony serwer w jednym i pisać kod w drugim.
Wszystkie worktree dzielą ten sam .git (historię, remote’y, hooki). Commit w jednym worktree jest od razu widoczny z drugiego.
Worktree w Claude Code
Claude Code obsługuje worktree na dwa sposoby:
Agent w worktree - zlecasz zadanie subagentowi który pracuje w izolowanej kopii repo:
Agent({
description: "Fix na masterze",
prompt: "Napraw bug XYZ",
isolation: "worktree"
})
Agent dostaje własną kopię i nie rusza Twoich plików. Jak skończy - dostajesz branch i ścieżkę do review.
Sesja w worktree - mówisz “wejdź w worktree” i cała sesja przełącza się na izolowany katalog. “ExitWorktree” żeby wrócić.
Baza danych per worktree
Worktree dzieli ten sam kod, ale każdy worktree może używać własnej bazy danych. Są trzy podejścia:
1. Wspólna baza (domyślnie)
Nic nie robisz - wszystkie worktree używają tej samej bazy deweloperskiej. Proste, ale migracje z jednego brancha mogą kolidować z drugim.
2. Osobna baza per worktree przez DATABASE_URL
Najczystsze podejście. Tworzysz drugą bazę i ustawiasz zmienną środowiskową w worktree:
# Utwórz bazę
createdb intum_dev_feature1
# Skopiuj schemat z głównej bazy
pg_dump -s intum_dev \| psql intum_dev_feature1
# W worktree ustaw DATABASE_URL
export DATABASE_URL="postgresql://localhost/intum_dev_feature1"
# Lub dodaj do .env w worktree (jeśli używasz dotenv)
echo 'DATABASE_URL=postgresql://localhost/intum_dev_feature1' > .env.local
3. Przełączanie bazy w database.yml
Możesz też zrobić warunek w config/database.yml:
development:
database: <%= ENV.fetch('INTUM_DB', 'intum_dev') %>
I uruchamiać serwer w worktree z INTUM_DB=intum_dev_feature1 bin/dev.
Kiedy warto mieć osobną bazę
- Pracujesz nad migracjami które zmieniają schemat (dodawanie/usuwanie kolumn)
- Dwa branche mają sprzeczne migracje
- Chcesz mieć różne dane testowe per feature
Kiedy wystarczy wspólna baza:
- Zmiany są tylko w kodzie Ruby/JS, bez migracji
- Branche są krótkożyciowe i szybko mergowane
Przykładowy workflow
# Główny katalog - feature A
cd ~/projects/intum
git checkout feature_a
# Worktree na hotfix
git worktree add ~/projects/intum-hotfix master
cd ~/projects/intum-hotfix
# ... naprawiasz, commitujesz, pushujesz
cd ~/projects/intum
git worktree remove ~/projects/intum-hotfix
# Worktree na feature B (równoległe)
git worktree add ~/projects/intum-feature-b feature_b
# Teraz masz dwa katalogi otwarte w IDE
Ważne: nie możesz mieć dwóch worktree na tym samym branchu. Każdy worktree musi być na innym branchu.