docs(edu): write git worktrees reference; update project status

Mark git worktrees and Markov Chains as complete in PROJECTS.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
quotesdb
Elijah Voigt 3 months ago
parent ce48ffac5a
commit d01b5db905

@ -1,7 +1,7 @@
# TODO
## Tools
- [ ] `nbd` agent tasks management cli
- [x] `nbd` agent tasks management cli
## Projects
- [ ] QuotesDB website
@ -14,9 +14,9 @@
- [ ] Local-first app development
## Interactive Learning and Education
- [ ] Git worktrees, how do use please
- [x] Git worktrees, how do use please
- [ ] How to structure a co-op profit sharing worker owned business
- [ ] Hands-on: Markov Chains
- [x] Hands-on: Markov Chains
- [ ] Hands-on: Vector Databases
- [ ] Hands-on: Creating and training a simple LLM
- [ ] Hands-on: Writing your own language (lisp, interpreted, compiled to C)

@ -0,0 +1,170 @@
# Git Worktrees
## What Are They?
A git worktree is a checked-out copy of a branch that lives in a separate directory on your filesystem, but shares the same underlying git repository (`.git` database) as your main clone.
Normally, a single git clone has one working directory — the files you see and edit. A worktree lets you have **multiple working directories at once**, each on a different branch, all tied to the same repository. You don't clone the repo a second time; you project a second (or third, or fourth) working directory from the one clone.
```
~/.git/ ← shared: all objects, refs, config
~/projects/myapp/ ← main worktree (branch: main)
~/projects/myapp-feature/ ← linked worktree (branch: feature/auth)
~/projects/myapp-hotfix/ ← linked worktree (branch: hotfix/crash)
```
All three directories above read and write to the same `.git` object store. Commits made in any worktree are immediately visible to all others.
---
## Core Commands
### Add a worktree
```sh
# Check out an existing branch into a new directory
git worktree add ../myapp-feature feature/auth
# Create a new branch and check it out in one step
git worktree add -b feature/new-thing ../myapp-new-thing main
```
The first argument is the path for the new directory. The second is the branch name (or starting commit).
### List worktrees
```sh
git worktree list
```
Example output:
```
/home/you/projects/myapp abc1234 [main]
/home/you/projects/myapp-feature def5678 [feature/auth]
```
### Remove a worktree
```sh
# Remove the directory and deregister the worktree
git worktree remove ../myapp-feature
# Force-remove even if there are untracked or modified files
git worktree remove --force ../myapp-feature
```
After deleting a linked worktree directory manually (e.g. with `rm -rf`), git still knows about it. Clean up the stale reference with:
```sh
git worktree prune
```
### Move a worktree
```sh
git worktree move ../myapp-feature ../myapp-auth-feature
```
---
## Typical Workflows
### Work on two branches simultaneously
You're deep in a feature branch when a urgent bug report comes in. Instead of stashing your work or committing a WIP, you add a worktree:
```sh
git worktree add ../myapp-hotfix main
cd ../myapp-hotfix
# fix the bug, commit, push — then come back to your feature
```
Your feature working directory is untouched.
### Run tests against a different branch without switching
```sh
git worktree add /tmp/myapp-test origin/release/2.0
cd /tmp/myapp-test
cargo test
```
You keep your editor open on `main` while tests run elsewhere.
### Review a colleague's PR locally
```sh
git fetch origin
git worktree add ../review-pr-123 origin/pr/123
cd ../review-pr-123
# read, run, evaluate — then remove when done
git worktree remove ../review-pr-123
```
---
## How It Works Internally
When you run `git worktree add`, git:
1. Creates a subdirectory inside `.git/worktrees/<name>/` to store the worktree's private state (its `HEAD`, index, and a back-reference to the working directory path).
2. Writes a `.git` *file* (not a directory) into the new working directory that points back to `.git/worktrees/<name>/`.
3. Checks out the requested branch into the new directory.
The object database (all commits, trees, blobs) is shared. Only the index and `HEAD` are per-worktree.
---
## Limitations and When to Avoid Them
### Each branch can only be checked out once
The most important constraint: **a single branch cannot be checked out in two worktrees at the same time.** Git enforces this to prevent the two trees from diverging their indexes silently. If you try, you'll get an error:
```
fatal: 'feature/auth' is already checked out at '/home/you/projects/myapp'
```
Workaround: check out the second worktree at a specific commit (detached HEAD), or create a local tracking branch.
### Tools that look for `.git` as a directory can break
Some tools assume `.git` is a directory, not a file. A linked worktree has a `.git` *file* instead, which confuses:
- Older git GUIs that scan for `.git/` directories
- Some shell prompts and plugins that detect git repos naively
- Scripts that do `test -d .git`
### Build systems that use the working directory path
If your build system or language tooling caches absolute paths (e.g. Cargo's `target/` directory is placed relative to the workspace root), separate worktrees work fine — each has its own `target/` directory. But if a tool bakes the source path into cached artifacts, switching between worktrees may cause spurious rebuilds or cache invalidation.
### Hooks run in the worktree context, not the main repo
Git hooks in `.git/hooks/` apply to all worktrees. But the working directory (`$GIT_WORK_TREE`) will be the linked worktree path, not the main repo path. Hook scripts that assume a fixed working directory can behave unexpectedly.
### Not a substitute for branches in CI
Worktrees are a local developer convenience. Don't model CI pipelines around them — use proper branch checkouts in ephemeral CI environments instead.
### Submodules require extra care
Submodules are not automatically initialized in a new worktree. You need to run `git submodule update --init` inside each linked worktree where you need them.
### Avoid for long-lived parallel development
If you find yourself maintaining two worktrees of the same repo for weeks at a time, that's a signal you might want two separate clones or a proper branch strategy — not worktrees. Worktrees shine for short-lived parallel work (hotfixes, reviews, quick tests), not as a permanent parallel development setup.
---
## Quick Reference
| Task | Command |
|---|---|
| Add a worktree for an existing branch | `git worktree add <path> <branch>` |
| Add a worktree and create a new branch | `git worktree add -b <branch> <path> <start-point>` |
| List all worktrees | `git worktree list` |
| Remove a worktree | `git worktree remove <path>` |
| Clean up stale worktree records | `git worktree prune` |
| Move a worktree | `git worktree move <old-path> <new-path>` |
Loading…
Cancel
Save