How It Works
This page explains the mechanics behind how repoverlay manages overlay files.
Symlinks vs copies
Section titled “Symlinks vs copies”By default, repoverlay creates symlinks from the target repo to the overlay source. This means changes to the source are immediately reflected in the target.
Use the --copy flag to copy files instead, which is useful when:
- Symlinks aren't supported (e.g., some Docker setups or Windows without developer mode)
- You want independent copies that won't change when the source is modified
- Your CI environment doesn't handle symlinks well
Git exclusion
Section titled “Git exclusion”When files are applied, repoverlay adds them to .git/info/exclude — a per-repo gitignore file that isn't tracked by git itself. This means:
- Overlay files don't show up in
git status - No changes to the tracked
.gitignorefile - Each overlay gets its own named section for clean removal
The exclude entries look like this:
# repoverlay:my-overlay start.envrc.claude/# repoverlay:my-overlay endThis approach keeps overlay files completely invisible to git without modifying any tracked files.
State tracking
Section titled “State tracking”repoverlay tracks applied overlays in two locations:
- In-repo state (
.repoverlay/overlays/<name>.ccl) — the primary record of what's applied, stored inside the target repository - External backup (
~/.local/share/repoverlay/applied/) — a recovery copy stored outside the repository
The external backup exists so that overlays can be restored after git clean or other operations that remove untracked files. See Restoring After Git Clean for details.
State files are written in CCL format and track the overlay name, source, applied timestamp, and list of files with their link types.
Caching
Section titled “Caching”GitHub repositories are cached locally to avoid re-downloading on every apply. Caches are stored at ~/.cache/repoverlay/github/<owner>/<repo>/.
- Repos are shallow cloned to minimize disk usage
- Caches are updated automatically during
repoverlay update - Cache metadata tracks the commit hash and last update time
- Changing
--reffetches the new ref into the existing cache
Manage the cache with:
repoverlay cache list # List cached repositoriesrepoverlay cache path # Show cache locationrepoverlay cache remove owner/repo # Remove a specific cached reporepoverlay cache remove --all # Remove all cached reposFork inheritance
Section titled “Fork inheritance”When you work on a fork of a repository, repoverlay can automatically inherit overlays from the upstream (parent) repository.
Resolution order
Section titled “Resolution order”When you apply an overlay from a shared overlay repository, repoverlay checks:
- Direct match — an overlay matching your fork's
org/repo - Upstream fallback — if no direct match exists and an
upstreamremote is configured, an overlay matching the upstream'sorg/repo
Example
Section titled “Example”# Your fork's remotesgit remote -v# origin git@github.com:tylerbutler/FluidFramework.git# upstream git@github.com:microsoft/FluidFramework.git
# This checks for tylerbutler/FluidFramework/claude-config first,# then falls back to microsoft/FluidFramework/claude-configrepoverlay apply microsoft/FluidFramework/claude-configStatus display
Section titled “Status display”When an overlay is resolved via upstream fallback, repoverlay status shows how it was resolved:
Overlay: claude-config Source: microsoft/FluidFramework/claude-config (via upstream) (overlay repo) Commit: abc123def456Upstream detection
Section titled “Upstream detection”repoverlay detects the upstream repository by scanning git remotes for one named upstream — the standard convention for forks. Both HTTPS and SSH remote URLs are supported.