Skip to content

Latest commit

 

History

58 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

frigo

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.md

Your file stays where it is. Main Git leaves it alone. frigo tracks its changes.

Why frigo?

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

Install from npm:

npm install -g frigo

Or run without a global install:

npx frigo --help

Requirements:

  • 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

Quick start

Add a file to frigo:

frigo add PLAN.md

This 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 diff

Commit it to frigo history:

frigo commit -m "Add implementation plan" PLAN.md

Continue editing the file normally:

$EDITOR PLAN.md

Review and commit another revision:

frigo diff PLAN.md
frigo commit -m "Update implementation plan" PLAN.md

No separate initialization or staging step is required.

Example

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.md

The 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 status

shows changes for the main repository.

frigo status

shows changes for frigo-managed files.

Commands

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.

Add files

frigo add PLAN.md
frigo add PLAN.md NOTES.md
frigo add docs/local/

add assigns existing files or directories to frigo.

It:

  1. keeps the paths in their current location;
  2. registers them as frigo-managed paths;
  3. locally excludes them from the main Git repository;
  4. 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.

Check status

frigo status

frigo 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.

List managed paths

frigo list

The shorter alias is:

frigo ls

This lists the exact files and directories currently assigned to frigo.

Review changes

Show all uncommitted frigo changes:

frigo diff

Limit 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 changes

Commit selected managed paths:

frigo commit -m "Update implementation plan" PLAN.md

Commit 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.

View history

List commits from frigo's separate history:

frigo log

Show the latest commit metadata and complete patch:

frigo show

Select another commit using Git revision syntax, optionally filtering the historical patch to exact paths:

frigo show HEAD~1
frigo show HEAD~1 -- PLAN.md

Historical path filters also work for files that were later released from frigo ownership.

Doctor and repair

Run a read-only repository-wide diagnosis:

frigo doctor

frigo 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 --repair

frigo 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.

Recover an orphan store

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.

Recover a stale common operation lock

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.

Restore files

Discard uncommitted changes to a managed file:

frigo restore PLAN.md

Restore 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.

Release files

Stop managing a path with frigo:

frigo release PLAN.md

Releasing 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.md

release 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.md

How it works

frigo uses Git internally, but it is not a replacement Git interface.

It manages two concepts:

  1. which project paths belong to frigo rather than the main repository;
  2. 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 commit

leave 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.

Why not .gitignore?

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 and coding agents

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.

Suggested agent instruction

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`.

Limitations

frigo is convenience tooling, not a security boundary. Deliberate force-adds, direct index changes, or modified ignore rules can bypass it.

Linked worktree removal can bypass frigo

Frigo-owned lifecycle locks are a practical boundary, not a security boundary.

  • ordinary git worktree remove is blocked when Git considers the worktree unsafe to remove;
  • git worktree remove --force still respects Frigo's owned lifecycle lock;
  • git worktree remove --force --force can remove a locked worktree, so the shared history remains the recovery point.

frigo history is local

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.

Git metadata contains the history

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.

Main Git protection is practical, not absolute

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.

UTF-8 and U+FFFD

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 is not secret storage

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.

Editor integration is separate

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.

Building from source

Source builds require Go 1.26 or newer:

go install github.com/roie/frigo/cmd/frigo@latest

For local development:

go build -trimpath -o frigo ./cmd/frigo

Uninstall

npm uninstall -g frigo

This 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.

License

Apache-2.0

About

Keep local project files without adding them to your main Git history.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages