Skip to content

Releases: gmr/drift

Release list

v1.1.0

Choose a tag to compare

@gmr gmr released this 20 Aug 15:40
4cbd246

Added

  • Commits whose message carries a Drift: ignore trailer are no longer reported as drift, letting an author explicitly vouch for a change instead of having it show up as unexplained (#4)
  • New ignored_commits_skipped field in the JSON report, counted separately from commits_scanned and merge_commits_skipped
  • In --tree mode, a path changed only by ignored commits is now reported as unattributed

The trailer's token and value are matched ASCII case-insensitively.

v1.0.0

Choose a tag to compare

@gmr gmr released this 11 Aug 22:06
3dd503e

First release of drift.

.driftignore lists the paths whose changes do not matter. Everything else does.
drift compares two git refs, drops the noise, and reports what is left: the
changes worth acting on, who made them, and how long they have been waiting.

$ drift --tree 1.1.0 main --pretty
{
  "drift_detected": true,
  "mode": "tree",
  "drift_commits": ["0f1e2d3..."],
  "drift_authors": ["Ann Author <ann@example.com>"],
  "drift_paths": ["src/app.py", "uv.lock"],
  "oldest_drift": { "sha": "9a8b7c6...", "age_seconds": 1209600 },
  "newest_drift": { "sha": "0f1e2d3...", "age_seconds": 91800 }
}

Features

  • Accepts any two committish refs: a full or short sha, a tag, a branch,
    origin/main, HEAD~3.
  • .driftignore, in gitignore pattern syntax, read from the tree of the newer
    ref
    rather than from disk, so a run never depends on the worktree and always
    repeats the same answer.
  • Two modes. --log, the default, counts every path the range touched, so work
    that was later reverted still reports. --tree counts only the paths whose
    content actually differs between the two refs, then attributes each back to the
    commits that touched it, which is the honest answer to "is a release worth
    cutting".
  • JSON on stdout: the drift flag, the mode, commit shas, authors, paths, and the
    ages of the oldest and newest drift commit.
  • Flags diverged refs, and lists separately any drifting path that no commit in
    the range explains.
  • --fail-on-drift for CI gates. Exit 0 when the analysis ran, 1 for drift with
    that flag, 2 on failure.
  • Runs entirely in-process through gix.
    No git binary is invoked and none needs to be installed.

Defined behavior

Documented in the README and covered by 30 tests:

  • The range is from..to, exactly what git log from..to lists.
  • Merge commits are traversed but never classified; the walk already reaches the
    commits on their sides.
  • Renames are two literal paths, since rename detection is off. Moving a file into
    an ignored directory still reports drift at the source path.
  • Ages come from the committer timestamp against a single clock reading, so the two
    ends of the window are always consistent.
  • Output is newest-first with sorted path lists, byte for byte stable across runs.

Install

Homebrew:

brew install gmr/utils/drift

Install script:

curl -fsSL https://raw.githubusercontent.com/gmr/drift/main/install.sh | sh

Docker, multi-arch (linux/amd64, linux/arm64):

docker pull ghcr.io/gmr/drift:1.0.0
docker run --rm -v "$PWD:/repo:ro" -w /repo ghcr.io/gmr/drift:1.0.0 --tree 1.1.0 main

The binary is statically linked against musl, so it can be lifted into any base
image, glibc or musl:

COPY --from=ghcr.io/gmr/drift:1.0.0 /usr/local/bin/drift /usr/local/bin/drift

From source:

cargo install --git https://github.com/gmr/drift

Pre-built binaries for x86_64/aarch64 on Linux and macOS are attached below.

Notes

Not published to crates.io: the name drift there belongs to an unrelated
project. Use the Homebrew tap, the install script, the container image, or
cargo install --git.