Local files
Untracked files you want in every worktree — a .env with credentials,
editor settings, a personal Makefile.local, an .npmrc with a token — live
in one directory beside the workspace, local/ by default
(integrations.local.dir, resolved like bare_dir). The integration is on
whenever that directory exists.
With a single repository everything in local/ is placed into the worktree.
With several, local/ holds one subdirectory per repository, named after it:
local/api/.env goes to <branch>/api/.env.
Each entry’s path relative to that directory is matched against the paths
rules in order — the whole path, as a regular expression, with / between the
components — and the first rule that matches decides how it is placed:
| mode | |
|---|---|
link |
a symlink to the file in local/: one copy, shared by every worktree (the default) |
copy |
an independent copy per worktree |
hardlink |
shared like link, but a real file to tools that will not follow a symlink |
integrations: local: dir: local paths: - { pattern: '\.env.*', mode: copy } # each branch edits its own - { pattern: '.*', mode: link } # everything else is sharedAn entry no rule matches is left out. A directory is placed whole when the
worktree has nothing at that path; when the repository tracks that directory,
the walk goes inside it instead, so local/config/dev.yaml lands next to the
repository’s own config/base.yaml. What the worktree already has is never
replaced — a tracked file wins, with a warning on the switch that creates the
worktree — and the placing runs on every switch, so a file added to local/
later reaches the existing worktrees too.
Local files are placed before the package managers install (an .npmrc may be
what lets them reach a registry) and before setup; --no-setup skips them.
They are not added to any ignore file: keep them in the repository’s
.gitignore, or your global one. A branch whose directory would be local/
itself is refused.