git-cow
git worktree add that clones files instead of copying them. Every new worktree is a copy-on-write clone of a template checkout, so target/, node_modules and other build output are shared on disk until a build rewrites them. A worktree that would cost gigabytes starts at a few megabytes and builds incrementally.
A binary named git-cow on your PATH is a git subcommand, so git cow works once it is installed.
How it works
- Keep one template checkout per repository at
<worktree's parent>/.git-cow/<repo>, moved toorigin/HEADbefore each clone. - Clone the gitignored directories of your checkout into the template: build output and dependencies, never loose ignored files like
.envand never paths with a hidden component. git worktree add --no-checkout, then clone every template entry except.gitinto it. macOS usescp -c(clonefile), Linuxcp --reflink=always(FICLONE).- Copy the template's index, refresh it, and
git reset --hard, which rewrites only the files where your branch differs from the template.
If the volume cannot clone, or anything fails, it removes what it made and runs plain git worktree add with the same arguments.
Configuration
| Default | ||
|---|---|---|
git config cow.root |
~/.worktrees |
Where a worktree goes when the path is left out: <root>/<repo>/<last part of the branch> |
git config cow.template |
<worktree's parent>/.git-cow/<repo> |
The template checkout |
GIT_COW=0 |
Plain git worktree add |
The checkout, the template and the worktrees must be on one volume that clones: APFS on macOS, XFS formatted with reflink=1 or btrfs on Linux. ext4 and HFS+ always fall back.
Library
add?;
warm?;
Synchronous and without dependencies. A lock file next to the template keeps concurrent clones, from threads or processes, from seeing it half updated.
Costs
- A cloned file's blocks are copied the first time either side writes it.
git update-index --refreshre-hashes every tracked file, since clones have new inodes. That grows with the number of tracked files.- Output that embeds absolute paths, such as virtualenvs, points at the template. Whether the tool recovers is up to the tool.
- A directory where everything is ignored is shared whole, hidden subdirectories included, because git reports it as one entry.
- The template is one more checkout on disk and shows in
git worktree list. - Repositories with submodules always fall back.
Origin
Extracted from orch, where every agent task gets a worktree. Measured there on APFS: a warmed clone built in 55 to 72 s against 73 s for a plain worktree, and wrote about 1 GB less per task.
MIT licensed.