Version numbers your git history already knows.

GitCalVer reads commit history to produce a unique, strictly increasing version. Nothing to bump, no state to keep.

20260608
.
1
UTC date 20260608 The UTC day the commit landed.
Commit count 1 Consecutive first-parent commits up to this one that share its UTC day.

The first commit pushed on 20260608 (UTC) is 20260608.1.

GitCalVer is a deterministic function of history. Give it a commit, get its version. Give it a clean version, get the commit back.

1

Take the commit's UTC date

Committer date, normalized to UTC, formatted as YYYYMMDD. Time zones never leak in.

2

Count commits on that date

Walk the default branch's first-parent history and count the consecutive commits that share this UTC date, up to and including this one. Merge commits are one commit.

3

Join them with a dot

The result is YYYYMMDD.N — e.g. the third commit on April 11 is 20260411.3.


Boring on purpose

Strictly increasing

Later commits always sort after earlier ones. 20260607.1 < 20260607.2 < 20260608.1 — by plain numeric order, as long as committer dates never go backwards.

Unique per commit

Each first-parent commit on the default branch maps to one date-plus-count pair. No two ever resolve to the same clean string.

Reversible

Pass a clean version back to GitCalVer and it returns the exact commit hash. Versions are an index into history.

Zero config

No version file to bump, no tags to maintain by hand. The only dependency is git itself.


Everything that defines a version

format
YYYYMMDD.N
YYYYMMDD
The commit's committer date in UTC, zero-padded. Local time is never used.
N
1-based count of consecutive first-parent commits sharing that UTC date, up to and including this commit.
ordering
Compare as date, then as integer N. Strictly monotonic so long as committer dates never decrease.
prefix
An optional literal string, e.g. v0.v0.20260607.1 for SemVer tooling.
dirty
With optional --dirty, an uncommitted tree emits a marked, non-reversible version like 20260607.1-dirty.abc1234. The safe default behavior rejects this.
Read the full specification →

One file, one command

The reference implementation is a portable POSIX shell script. Its only dependency is git 2.15+.

install.sh
# grab the script, make it executable
curl -fsSLO https://github.com/gitcalver/sh/\
releases/latest/download/gitcalver.sh
chmod +x gitcalver.sh
run it
# version for HEAD
$ ./gitcalver.sh
20260607.1

# reverse: clean version → commit
$ ./gitcalver.sh 20260607.1
a1b2c3d4e5f6…
.github/workflows/release.yml
# mint a version on every push
# pin to a release tag — or a full commit SHA for the strongest supply-chain guarantee
- uses: gitcalver/sh@v20260530.6
  id: version
  with:
    prefix: 'v'
    tag: 'true'