Keep local project files without adding them to your main Git history.
Some files belong inside a project but not in its main Git history:
PLAN.md- working notes
- research
- local documentation
- AI context files
- machine-specific configuration
frigo keeps those files in their normal project paths and gives them a separate, local Git-backed history.
frigo add PLAN.md
frigo commit -m "Add implementation plan" PLAN.mdYour file stays where it is. Main Git leaves it alone. frigo tracks its changes.
frigo is French for "fridge".
Think of it as a local compartment inside your project: the files stay where you use them, while their history stays separate from the main repository.
The go ending is also a small nod to Go, the language frigo is built with.
Install from npm:
npm install -g frigoOr run without a global install:
npx frigo --helpRequirements:
- An existing Git repository
- Git 2.23 or newer on
PATH - Node.js 18 or newer for the npm package and launcher
Supported platforms:
- Linux, macOS, and Windows
- amd64 and arm64
Add a file to frigo:
frigo add PLAN.mdThis assigns PLAN.md to frigo. The file remains in the project, but ordinary operations in the main Git repository will leave it out.
Review its current state:
frigo status
frigo diffCommit it to frigo history:
frigo commit -m "Add implementation plan" PLAN.mdContinue editing the file normally:
$EDITOR PLAN.mdReview and commit another revision:
frigo diff PLAN.md
frigo commit -m "Update implementation plan" PLAN.mdNo separate initialization or staging step is required.
Given this project:
my-project/
├── .git/
├── src/
├── README.md
├── PLAN.md
└── docs/
└── research.md
Assign local planning files to frigo:
frigo add PLAN.md docs/research.mdThe project now has two separate histories over the same directory:
Main Git history
├── src/
└── README.md
frigo history
├── PLAN.md
└── docs/research.md
There is still only one physical copy of each file.
git statusshows changes for the main repository.
frigo statusshows changes for frigo-managed files.
frigo
frigo add [--] <path>...
frigo release [--force] [--] <path>...
frigo release [--force] --all
frigo status
frigo list
frigo ls
frigo diff [--] [<path>...]
frigo commit -m <message> [--] <path>...
frigo commit -a -m <message>
frigo commit -am <message>
frigo log
frigo show [<revision>] [-- <path>...]
frigo restore [--] <path>...
frigo doctor
frigo doctor --repair
frigo help
frigo --help
frigo --version
Running frigo without arguments prints concise usage. Use frigo help or frigo --help for detailed help.
frigo add PLAN.md
frigo add PLAN.md NOTES.md
frigo add docs/local/add assigns existing files or directories to frigo.
It:
- keeps the paths in their current location;
- registers them as frigo-managed paths;
- locally excludes them from the main Git repository;
- includes them in frigo's separate history.
It does not modify the repository's shared .gitignore.
It also does not create a commit. Use frigo commit when you are ready to record the files.
When you add a directory, frigo manages it as a container. Files created inside that directory later automatically belong to frigo too.
frigo statusfrigo reports changes to its managed files, including:
- files that have never been committed;
- modified files;
- deleted files;
- changes inside managed directories;
- problems with the main Git ignore boundary.
frigo listThe shorter alias is:
frigo lsThis lists the exact files and directories currently assigned to frigo.
Show all uncommitted frigo changes:
frigo diffLimit the diff to selected paths:
frigo diff PLAN.md
frigo diff docs/local/The comparison is against the latest frigo commit.
frigo does not expose a persistent staging area, so there is no staged diff.
Commit selected managed paths:
frigo commit -m "Update implementation plan" PLAN.mdCommit several selected paths:
frigo commit -m "Update local documentation" PLAN.md docs/local/Commit every changed path currently managed by frigo:
frigo commit -a -m "Checkpoint local project files"frigo commits only the paths you select, or all managed changes when -a is used. Unrelated files from the main repository are not included.
A commit requires either one or more paths or -a. Running frigo commit -m "message" without either is rejected.
List commits from frigo's separate history:
frigo logShow the latest commit metadata and complete patch:
frigo showSelect another commit using Git revision syntax, optionally filtering the historical patch to exact paths:
frigo show HEAD~1
frigo show HEAD~1 -- PLAN.mdHistorical path filters also work for files that were later released from frigo ownership.
Run a read-only repository-wide diagnosis:
frigo doctorfrigo doctor reports deterministic issue lines and does not change Frigo
metadata. It checks the current store, agreed active linked-worktree
administration, stable stores, pointers, lifecycle locks, exclusions,
attributes, and history.
To request bounded repairs:
frigo doctor --repairfrigo doctor --repair prints the complete plan before the first change,
applies only unambiguous safe repairs, and diagnoses the repository again
afterward. It does not delete history, adopt unsupported pre-v0.2 state,
rewrite suspect paths, remove orphan stores, or clear foreign locks.
Exit status:
0: diagnosis is healthy, or repair completed with no remaining issues;1: one or more issues remain, or diagnosis/repair failed;2: command-line usage is invalid.
An orphan-store issue means a stable linked-worktree store has no unique,
exact live checkout/admin/pointer/manifest association. Doctor reports the
exact store path and leaves it unchanged.
If the original checkout still exists, first use Git to restore its reciprocal
worktree administration, then run frigo doctor from that checkout. Review
frigo doctor --repair only if it offers an unambiguous pointer repair. If the
checkout or administration is gone, preserve the reported store, inspect its
manifest.json and history.git, and recover any needed history to a safe
location before considering manual cleanup. Doctor never adopts or deletes an
orphan store.
An operation-lock-unavailable issue reports the exact lock path, normally
$GIT_COMMON_DIR/frigo.lock, and its recorded owner details: operation, PID,
host, and start time.
Verify that no Frigo process is still running for this repository, using the
recorded owner details and the exact repository named by the issue. Only after
that verification, manually delete the exact lock path shown in the issue.
frigo doctor, including frigo doctor --repair, never removes the common
operation lock.
Discard uncommitted changes to a managed file:
frigo restore PLAN.mdRestore several paths:
frigo restore PLAN.md docs/local/The files are restored from the latest frigo commit. frigo restore writes back the exact bytes from the latest frigo commit. Files that were never saved to frigo stay in place, including inside managed directories.
Be careful: current uncommitted changes to those paths will be lost.
Stop managing a path with frigo:
frigo release PLAN.mdReleasing a path:
- keeps the physical file in place;
- removes only Frigo ownership and Frigo-managed exclusion for it;
- other Git ignore rules may still hide it from the main Git repository;
- preserves its existing frigo history.
frigo release --all releases every path owned by the current worktree.
frigo refuses to release a path with uncommitted frigo changes.
Re-adding a previously released path resumes its existing frigo history; earlier commits are not removed.
To release a path despite uncommitted frigo changes:
frigo release --force PLAN.mdrelease does not delete the file.
To delete a file, delete it normally and commit that deletion to frigo:
rm PLAN.md
frigo commit -m "Remove implementation plan" PLAN.mdfrigo uses Git internally, but it is not a replacement Git interface.
It manages two concepts:
- which project paths belong to frigo rather than the main repository;
- a separate Git history for those paths.
Under the hood, frigo maintains another Git repository connected to the same project directory.
project directory
│
┌─────────────┴─────────────┐
│ │
main Git frigo
main history local history
frigo also manages repository-local ignore rules so ordinary commands such as:
git add -A
git commitleave frigo-managed files out of the main repository.
Specifically, frigo writes managed paths to .git/info/exclude, or to the equivalent $GIT_COMMON_DIR/info/exclude when Git uses shared metadata, such as with linked worktrees. Git provides this for repository-specific files that should remain local instead of being shared through .gitignore.
Linked worktrees keep their frigo history under $GIT_COMMON_DIR/frigo/worktrees/<frigo-id>/, so the history stays with the shared Git metadata even if the linked worktree directory is removed. The main worktree keeps its existing .git/frigo history. If frigo finds pre-v0.2 linked metadata, it reports it as unsupported and leaves it untouched.
No Git hooks are installed. No daemon runs in the background. No shared configuration file is added to the project.
A shared .gitignore is appropriate when a file should be ignored by everyone using the repository.
frigo is for files that belong only to the current clone or developer workflow.
For example, your personal PLAN.md may belong inside the project without becoming a repository-wide convention.
frigo manages that locally, without creating a .gitignore change for the rest of the project.
Unlike an ordinary ignored file, a frigo-managed file can still have:
- status;
- diffs;
- commits;
- history;
- restoration.
frigo-managed files remain ordinary files in the project directory.
Coding agents can read and edit them directly when given their paths:
Read PLAN.md and continue from the current plan.
frigo also helps prevent normal agent-driven Git operations from committing those files to the main repository.
Automatic file discovery varies by editor and agent. Some tools omit Git-ignored files from search results, repository maps, or file pickers even though the files remain accessible by path.
frigo does not install agent-specific instructions or modify files such as AGENTS.md, CLAUDE.md, or editor settings.
Add this to AGENTS.md, CLAUDE.md, or your agent's equivalent instruction file:
Use `frigo` for local project files that should stay out of the main Git
history. Before committing, check `frigo status` and commit plans, notes,
research, or AI working files with `frigo`, not `git`.
frigo is convenience tooling, not a security boundary. Deliberate force-adds, direct index changes, or modified ignore rules can bypass it.
Frigo-owned lifecycle locks are a practical boundary, not a security boundary.
- ordinary
git worktree removeis blocked when Git considers the worktree unsafe to remove; git worktree remove --forcestill respects Frigo's owned lifecycle lock;git worktree remove --force --forcecan remove a locked worktree, so the shared history remains the recovery point.
frigo history belongs to the current repository clone.
It is not pushed with the main repository and is not automatically available from another clone or computer.
frigo stores its history alongside the current clone's Git metadata.
Removing or rebuilding .git also removes the frigo history for that clone.
frigo is not a backup service.
frigo protects files from ordinary main-repository staging and commit workflows.
Repository ignore rules can conflict with frigo's local rules. frigo validates managed paths during its commands and reports detected conflicts, but later changes outside frigo can still alter the effective Git behavior. frigo only manages its own exclusion boundary.
Review the main repository's staged diff before committing sensitive files.
frigo rejects invalid UTF-8 path bytes before metadata changes. It also rejects raw registry bytes that are not valid UTF-8 before decoding JSON.
If a path appears as U+FFFD, frigo reports that it may be a real filename or a historical replacement artifact and does not guess the original bytes or rewrite it automatically.
frigo-managed files remain normal readable files on disk.
frigo does not encrypt them, restrict filesystem access, or make them safe for credentials and secrets.
Use an appropriate secret manager for passwords, tokens, private keys, and other sensitive values.
frigo-managed files remain visible and editable in the filesystem, but their frigo history does not automatically appear as a second source-control provider in editors such as VS Code.
Use the frigo CLI to inspect status, diffs, and history.
Source builds require Go 1.26 or newer:
go install github.com/roie/frigo/cmd/frigo@latestFor local development:
go build -trimpath -o frigo ./cmd/frigonpm uninstall -g frigoThis removes only the command. Existing frigo history and local ignore entries remain unchanged, so it is a safe uninstall.
Do not delete frigo's project metadata directly. Managed paths may remain excluded from the main repository.
Apache-2.0