What wrote this code, and how?
Stamp the model, prompt hash, and transcript ref onto the commits an agent produces. Audit later without parsing messages.
$ git meta set commit:HEAD agent:model claude-4.6
$ git meta list:push branch:feat-checkout agent:chat \
'new comment'
git-meta
is an open specification and reference CLI tool for attaching arbitrary, fine-grained metadata to Git objects — provenance, ownership, reviews, attestations — stored locally for fast queries and exchanged using normal Git transfer protocols and servers.
You can think of git meta
as a more performant,
scalable, flexible and collaborative git notes
.
Attach key/values to commits, branches, paths, change-ids, or the project itself — not just whole commits.
Attach values of several types (strings, lists, sets) to
namespaced keys such as agents:model
.
Metadata is exchanged as commits on refs/meta/*
. If
you can git push
, you can share it.
git-meta is designed around Git's promisor remotes, meaning it can easily handle millions of metadata entries and get values on demand.
Metadata wants its own lane — structured, queryable, independently mutable — without polluting your working tree.
Stamp the model, prompt hash, and transcript ref onto the commits an agent produces. Audit later without parsing messages.
␃WPNCODE0␃
Keep owners, reviewers, and policy hints against paths — as sets that merge across branches instead of a single file people fight over.
$ git meta set:add path:src/billing owners '["ali", "jin"]'
$ git meta set:add path:src/billing reviewers mira
Attach review threads and approvals directly to commits or ranges. Independent of any single forge.
$ git meta set commit:314e7f0 review:status approved
$ git meta list:push commit:314e7f0 review:notes \
"lgtm; verify the retry backoff"
Record test runs, SBOMs, or signatures as first-class keys — many independent fields on the same commit, each mutable on its own schedule.
$ git meta set commit:HEAD ci:status passed
$ git meta set commit:HEAD ci:run gha-4912
$ git meta set commit:HEAD sbom:sha sha256:ab…
Every change lands in a fast local index first. To share, git-meta
serializes that index into commits on a
refs/meta/*
ref and ships them with the same
git push
and git fetch
you already use — no new daemons, protocols, or new wire formats.
git fetch
The reference implementation is a single Rust binary. Install with
cargo
, wire up a remote, set a value and push it — then watch a teammate pull it down with the same tool.
Builds with stable Rust. The crate is
git-meta-cli
; the installed command is
git meta
.
$ cargo install git-meta-cli
$ git meta --version
Metadata lives under its own ref namespace. Pin the
recommended remote in a .git-meta
file at the
repo root — the same repo as your code is fine —
then run git meta setup
to wire it up and seed
refs/meta/main
.
$ cd your-project
$ printf 'url: git@github.com:you/proj.git\n' > .git-meta
$ git meta setup
Set a key on any target — commit
,
branch
, path
, or
project
— then push the metadata refs to the remote.
$ git meta set commit:HEAD review:status approved
$ git meta push
On a different machine, a collaborator clones the repo and
runs git meta setup
. The committed
.git-meta
file from step 02 picks the remote for them, fetches the metadata refs, and gets them ready to inspect the values you wrote.
$ git clone git@github.com:you/proj.git && cd proj
$ git meta setup
$ git meta show HEAD
The git-meta specification was developed and proposed by GitButler with inspiration and feedback from several leading version control teams, to solve the growing Git metadata problem. Contact us if you would like to join this list of cool kids using it.
Both. The important part is the exchange format — the agreement needed for different implementations to interoperate. A reference implementation lives alongside the spec so you can try the ideas end-to-end.
No. git-meta uses ordinary Git objects — trees, commits,
and refs under refs/meta/*
. Any Git server that accepts arbitrary refs can transport it.
git notes
?
git notes
attaches a single blob per commit. git-meta models many small, independently mutable fields against many kinds of targets (paths, branches, change-ids), with typed values and deterministic merges.
Three to start: string
, list
, and
set
. Each has a documented merge behavior so concurrent edits resolve without custom code.
Metadata lives on its own refs/meta/*
refs, so cloning code doesn't pull metadata unless you ask for it. Initialization uses partial fetches to only get a working set of data, not every historical value, but older values can be fetched on demand with any modern Git server, including GitHub.
If that's not enough, history can even be split and unioned in special cases, or even partially made private.
Yes — that's one of the motivating use cases. Stamp model, prompt data, and transcript references onto commits or branches, and query them later without parsing commit messages.
git-meta is small and sharp. The fastest way to make it better is to use it for something real.