Installation
Three supported channels. The Go install is the simplest; the Nix derivation is what your coworkers will thank you for picking.
Go, system-wide
$ go install github.com/flaticols/gitmd/cmd/gitmd@latest
Go tool, project-pinned
# Go 1.24+, version recorded in go.mod $ go get -tool github.com/flaticols/gitmd/cmd/gitmd@latest $ go tool gitmd show
Nix, macOS
$ nix-env -if https://github.com/flaticols/gitmd/raw/latest/nix/gitmd.nix
Platforms
The release pipeline currently ships aarch64-darwin and x86_64-darwin. Linux users build from source.
Quickstart
Every gitmd verb takes an optional <ref> —
anything git rev-parse accepts. Omit it and you operate
on HEAD, which is what you want most of the time.
# attach reasoning + ticket to the commit you just made $ gitmd add --reason "required for audit" --ticket JIRA-1234 # replace, don't append $ gitmd set --ticket JIRA-2 # pretty-print, or hand to jq $ gitmd show $ gitmd show HEAD~3 --json # reach back two commits, attach an arbitrary trailer $ gitmd add HEAD~2 --trailer "Reviewed-by=Alice <a@x>"
Real show output
From the very commit that introduced this page. Pretty form for
humans, --json for jq and friends.
$ gitmd show commit 33d2dff8 — docs: add retro-styled single-page HTML reference manual author Denis Panfilov <gh@flaticols.dev> 2026-04-28T20:21:52+02:00 Reason single-page reference manual for the project; satisfies the docs/ workflow added on origin Assisted Claude Code (Opus 4.7)
$ gitmd show --json { "commit": "33d2dff8be6ea9b3a534d64cc3e13773cf1cc439", "subject": "docs: add retro-styled single-page HTML reference manual", "author": { "name": "Denis Panfilov", "email": "gh@flaticols.dev", "date": "2026-04-28T20:21:52+02:00" }, "trailers": [ { "key": "Reason", "value": "single-page reference manual for the project; satisfies the docs/ workflow added on origin" }, { "key": "Assisted", "value": "Claude Code (Opus 4.7)" } ] }
The why belongs on the commit, not in a wiki that will rot.
Commands
Five verbs. Three of them rewrite history and refuse to run on a dirty tree; the other two are pure reads.
--json for machines.
Trailer keys
Three predefined shortcuts cover the cases worth standardising.
Anything else lives behind --trailer KEY=VALUE, which is
repeatable.
-
flag · --reason
Reason
The motivation. Why this diff exists — the constraint, the bug, the user request. One sentence is enough.
-
flag · --ticket
Ticket
An issue or PR identifier.
JIRA-1234,gh-42, anything machine-readable. -
flag · --assisted
Assisted
For AI-assisted commits. The model name and version:
Claude Code 4.7. -
flag · --trailer
Idea / arbitrary
Design notes, follow-ups, paths-not-taken. Or any custom key —
Reviewed-by,Tested-by, etc.
How it works
For HEAD, gitmd shells out to git commit --amend.
For any other reachable commit it runs an interactive rebase with
itself registered as GIT_SEQUENCE_EDITOR — the editor
inserts a surgical exec git commit --amend -F <newmsg>
after the target's pick line.
Trailer composition is delegated to git interpret-trailers,
so gitmd inherits git's exact semantics — folded values, the
--- divider, and the twenty-five percent
trailer-line tolerance.
Safety
History rewriting should never surprise you. gitmd is conservative on purpose.
Refuses dirty trees
If git status has anything pending, gitmd bails out before touching history. Stash or commit first.
Won't amend non-HEAD merges
Rewriting a merge commit's message via interactive rebase is a footgun. gitmd refuses; do it by hand if you must.
Never force-pushes
If the rewritten commit was already published, you run git push --force-with-lease yourself — gitmd does not.