A small, dependency-free Go CLI, named gitloglore, that generates a grouped CHANGELOG.md from a
git repository's Conventional Commits
history — a from-scratch reimplementation inspired by
release-lab/whatchanged (not a fork or wrapper of it).
Uses only the Go standard library plus the local git binary (via os/exec) —
no external Go modules, no network access required to build.
Using the included Makefile (recommended — outputs to build/):
make build # compiles build/gitloglore for your current OS/arch
make build-all # cross-compiles release binaries for macOS/Linux/Windows into build/
make test # go test ./...
make vet # go vet ./...
make clean # removes build/Or manually with go build, also targeting build/:
mkdir -p build
go build -o build/gitloglore ./cmd/gitlogloreCross-compile for other platforms:
mkdir -p build
GOOS=darwin GOARCH=arm64 go build -o build/gitloglore-darwin-arm64 ./cmd/gitloglore
GOOS=darwin GOARCH=amd64 go build -o build/gitloglore-darwin-amd64 ./cmd/gitloglore
GOOS=linux GOARCH=amd64 go build -o build/gitloglore-linux-amd64 ./cmd/gitloglore
GOOS=windows GOARCH=amd64 go build -o build/gitloglore-windows-amd64.exe ./cmd/gitlogloreExamples below assume you've run make build and are calling the binary at
./build/gitloglore (swap in whatever path/name fits your setup):
# Full history, written to an auto-named gitloglore-changelog-<datetime>.md
./build/gitloglore -repo /path/to/repo
# Range using tags
./build/gitloglore -repo /path/to/repo -range v1.0.0..HEAD -title v1.1.0 \
-output CHANGELOG.md -prepend
# Range using raw commit SHAs (short or full both work)
./build/gitloglore -repo /path/to/repo -range a1b2c3d..e4f5a6b
# Same thing, but with explicit -from/-to (mixes tags/branches/SHAs freely)
./build/gitloglore -repo /path/to/repo -from a1b2c3d -to e4f5a6b -title "hotfix batch"
# -from without -to defaults the end to HEAD
./build/gitloglore -repo /path/to/repo -from v1.0.0 -title v1.1.0
# Pull-request changelog: only commits on this branch, not yet in main/master
git checkout feature/login
./build/gitloglore -repo /path/to/repo -current-branch -output -
# Same, but against a specific base branch instead of auto-detected main/master
./build/gitloglore -repo /path/to/repo -current-branch -base develop -output -
# Print to stdout instead of writing a file
./build/gitloglore -repo /path/to/repo -output -
# List tags (newest first), useful for picking a range
./build/gitloglore -repo /path/to/repo -list-tags
# See all flags
./build/gitloglore -h| Flag | Default | Description |
|---|---|---|
-repo |
. |
Path to the git repository |
-range |
(full history) | Explicit commit range, e.g. v1.0.0..HEAD or a1b2c3d..e4f5a6b. Wins over -from/-to |
-from |
(none) | Starting point (older): tag, branch, or commit SHA |
-to |
HEAD (if -from set) |
Ending point (newer): tag, branch, or commit SHA |
-current-branch |
false |
Only include commits on the current branch not yet in the base branch — for pull-request changelogs |
-base |
auto-detect (origin/main, main, origin/master, master) |
Base branch to diff against when using -current-branch |
-output |
gitloglore-changelog-<datetime>.md |
Output file path. Use - to print to stdout instead |
-title |
Unreleased or the range |
Section heading |
-prepend |
false |
Prepend to an existing output file |
-no-authors |
false |
Omit author names |
-no-links |
false |
Omit commit links |
-group-order |
feat,fix,perf,refactor,docs,build,ci,test,chore,style,revert |
Section ordering |
-list-tags |
false |
List tags and exit |
-from/-to and -range accept tags, branches, or raw commit SHAs (short or
full) interchangeably — git resolves any of them the same way, so
-from a1b2c3d -to e4f5a6b works exactly like -from v1.0.0 -to v1.1.0.
-current-branch finds the merge-base (common ancestor) between your current
branch and the base branch, then lists only commits reachable from HEAD
that aren't reachable from that merge-base — i.e. exactly the commits your
PR would add, even if the base branch has moved on since you branched off.
The title defaults to the branch name, which is usually what you want to
paste into a PR description.
Each commit subject is parsed as type(scope)!: subject. Recognized types
(feat, fix, perf, refactor, docs, build, ci, test, chore,
style, revert) get a labeled section; anything else lands in "Other
Changes". A commit is treated as a breaking change if it has a ! before the
colon, or a BREAKING CHANGE: footer in the body — either way it's also
listed in its own "BREAKING CHANGES" section at the top.
Makefile build/test/vet/clean targets, outputs to build/
cmd/gitloglore/main.go CLI flag parsing & orchestration
internal/convcommit/ Conventional Commits header/footer parser
internal/gitlog/ git log/tag/remote extraction (shells out to git)
internal/changelog/ Markdown rendering, grouped by type
make test
# or: go test ./...This binary is designed to be driven from a VS Code extension via child_process/
os/exec-style calls (spawn gitloglore -repo <workspaceRoot> -range ... -output ...
and read stdout/stderr), the same way the original whatchanged project has an
official VS Code extension that
shells out to its own binary. Ask to have that wrapper generated once you're happy
with the CLI behavior.