> internals & scripting
How worktrees actually work: a .git pointer file, a private metadata directory per worktree, and precise sharing rules — objects, refs, config, hooks, and the stash are repository-wide, while HEAD, the index, and a few ref namespaces are per-worktree. Knowing the model explains every sharp edge, and the porcelain output plus per-worktree ref paths make worktrees fully scriptable — the foundation agent orchestrators are built on.
// internals & scripting
6 commands$ cat ../myapp-hotfix/.git$ git config extensions.worktreeConfig true$ git worktree add --no-checkout -b agent-web ../myapp-web main$ git rev-parse worktrees/auth/HEAD$ git worktree list --porcelain$ git worktree add --orphan -b gh-pages ../myapp-pages// faq
What's shared between worktrees and what's private?
Shared: the object database, all refs under refs/ (branches, tags, remotes — even the stash), configuration, and hooks. Private per worktree: HEAD, the index/staging area, the working files, and the refs/bisect, refs/worktree, and refs/rewritten namespaces. In short: history is one, checkout state is many.
Are git hooks shared across worktrees?
Yes — one .git/hooks directory (or core.hooksPath) applies to every worktree, so your Husky or pre-commit setup runs in agents' worktrees too. For per-worktree hooks, enable extensions.worktreeConfig and set core.hooksPath with git config --worktree.
Can I use worktrees with a bare repository?
Yes, and it's a popular layout: git clone --bare into ~/repos/myapp.git, then one worktree per branch — no privileged "main checkout" at all, which suits agent fleets nicely. One caveat: a bare clone's default fetch refspec doesn't create remote-tracking branches; set remote.origin.fetch to "+refs/heads/*:refs/remotes/origin/*" and fetch once, or remote branches won't resolve.
How old is git worktree — can I rely on it being available?
git worktree shipped in Git 2.5 (2015), so add, list, and prune are everywhere. Newer subcommands have version floors: move and remove came in 2.17, repair in 2.30, add --orphan in 2.42. Any Git from the last few years has all of them.