Skip to main content
Gat separates a large file’s version from its bytes. Git commits a small gat.lock file that maps paths to content IDs. Gat stores the bytes in a local and, when configured, remote storage. A is the link between them: the lock says which content belongs at a path, and the cache holds that content. This lets a Git commit select an exact large-file version without putting the large file itself in Git history.

Git selects the version

Commits record the lock. Switching revisions changes which content IDs belong at your file paths.

Gat restores the bytes

Sync creates working files from cached content. Pull downloads missing content before syncing.

Follow one file through a change

Suppose data/model.bin contains version A, and you want to share it.
1

Record the bytes with Gat

gat add data/model.bin hashes the file, caches its content, and records its path and content ID in gat.lock. Gat also excludes the working file from Git locally.This updates Gat’s metadata; it does not create a Git commit or upload bytes.
2

Commit the version with Git

Stage gat.lock with git add, then commit it. Include gat.yaml when shared configuration changes. The commit now identifies version A.
3

Publish the content, then the commit

gat push uploads the selected content to your configured remote. Run git push afterward so readers of the commit can fetch its bytes.Git and Gat remotes are separate: one stores Git history, the other stores large-file content. See Set up a remote.
4

Restore the file in another clone

git clone brings the lock and shared settings, but not the large-file bytes. Run gat init, then gat pull: Gat downloads missing content to the cache and creates data/model.bin with the version selected by the lock.
When you replace the file with version B, run gat add again. Its new bytes get a new content ID; your next Git commit records that ID. The earlier commit still points to A. Checking out that commit and syncing restores A from the cache, or requires a download if A is no longer cached.
Try the commands in the Quickstart, or follow the branching and publishing workflow.

Fetch, sync, and pull

Path selection limits which files an operation uses. History selection can include content referenced by older commits, for example to prefetch it before going offline. Fetching history does not check out those versions: Git chooses the revision to restore.

What lives where

my-repo
gat.yaml
gat.lock
data
model.bin
.gat
.gitignore
objects
state
.git
info
exclude
Commit gat.lock and project gat.yaml. The cache, managed working files, and local bookkeeping stay out of Git.
Gat maintains .gat/.gitignore before writing local storage, recreating it if missing. Opening an existing state database also ensures this protection: database reads can create coordination files. Reading an absent database leaves local storage absent.Managed working files use separate Git exclusions. See ignore rules to understand which files Git and Gat each ignore.
Each entry holds a repository-relative path and a BLAKE3 content ID. Checking out another Git revision selects that revision’s file versions.Large repositories can shard the lock into a gat.lock/ directory. The logical format stays the same.
Project configuration contains general settings and named resources. Use gat config for settings such as automatic fetching, and gat remote, gat route, gat mount, or gat selection to manage named definitions. Personal overrides belong in global or local configuration. See General settings and managed resources for the command distinction and scope rules.
An object is one file’s bytes, stored by content ID. Identical bytes share one object across paths and revisions. The cache location is configurable. See shared-cache setup before reusing one across clones.
Gat records what it last put in the working tree. Sync compares this record with the current lock and files on disk to plan changes.For maintenance and recovery, see the experimental gat system commands.
Gat maintains local exclusions so git add -A skips managed working files. Your project’s .gitignore remains separate.Git cannot express exact ignore rules for filenames containing newlines. Those files need a broader ignore pattern or a different name.

How sync decides what to change

Sync reconciles three things: Gat uses recorded state and filesystem checks to determine whether working files still match the expected content. It hashes bytes when metadata alone cannot establish a match. The local state is bookkeeping, not another version history. If the lock now selects B where Gat previously placed A, sync replaces a clean A with B from the cache. It can also restore a missing file or remove a previously managed path that is no longer desired. A file already at the desired version needs no replacement. If replacement or removal would discard local changes, sync reports a conflict. It also protects existing files that obstruct a desired path. Review the dry run and conflict options before forcing a change.
gat status compares lock metadata, not the bytes of working files. After editing an asset, use gat add to record its new content. See what status reports.

When the Git version changes

gat init installs Git hooks that run sync after supported operations such as switching branches and merging. Git selects the lock; Gat then restores the corresponding working files. Cached versions can be restored offline. Missing content needs gat pull or fetching enabled during sync. Run gat init in each clone. After operations without a suitable hook, such as git reset --hard or git restore, run gat sync yourself. See Automatic sync for triggers, fetching, and recovery.

Content identity is independent of path

The content ID is a BLAKE3 hash of the bytes, not the filename. Renaming a tracked file with gat mv reuses its cached content. Editing a file requires gat add again to record the new bytes and content ID.
Creating a working file from cached content is called . The default strategy creates an independent copy. Gat can also use reflinks, hardlinks, or symlinks, depending on the filesystem and configuration.Hardlinks and symlinks share bytes with the cache; editing them can change cached content. Prefer independent copies or reflinks for editable files.Changing the strategy affects future materializations. Use gat sync --rematerialize --dry-run to preview recreating existing clean files with the new strategy. See Materialization strategies.

Remotes, routes, and mounts

Remote: store the bytes

Connect object storage or a local directory.

Route: choose storage by path

Send different paths to different remotes. Experimental.

Mount: import a snapshot

Consume tracked files owned by another repository. Experimental.

Selection: choose a working set

Limit an operation to the files you need.

Interrupting commands

Press Ctrl+C once to request cancellation. Gat stops admitting new transfer work, interrupts Git fetch/checkout at its checkpoints, and waits for owned work and cleanup to finish. A filesystem publication or journaled mount update that has already started finishes its consistency-critical sequence before returning. Cancellation is cooperative: work without an interruption checkpoint may need to finish or reach its I/O timeout. A cancelled CLI invocation exits with status 130, without a success summary. On Unix, SIGTERM requests the same cleanup and exits with 143. On Windows, Ctrl+C uses the same cooperative behavior. Hooks suppress the interruption notice and keep reporting other errors. A second interrupt terminates the process immediately and skips remaining cleanup. Use it only when you intend to force termination; the next invocation may need to recover an interrupted transaction.