Git Changelog & Sprint Visualization: Track What Ships
A good changelog tells the story of your software. A sprint visualization shows what actually shipped. This guide covers generating changelogs from Git history, using tags for releases, and visualizing commit activity across a sprint, all without leaving your Git workflow.
Intermediate13 min readUpdated
What is a Git changelog?
A Git changelog is a structured record of changes between versions, generated from commit history and release tags. Sprint visualization maps commit activity, feature merges, and tag-marked releases onto a timeline so teams can see what shipped, and when.
The short version
- 1Adopt Conventional Commits:
feat:,fix:,docs:,chore: - 2Tag every release:
git tag -a v1.x.0 -m 'release message' - 3Generate changelog:
conventional-changelog -p angular -i CHANGELOG.md -s - 4Visualize sprint:
git log --oneline --after='sprint-start' --before='sprint-end' - 5Compare releases:
git log v1.2.0..v1.3.0 --oneline
Why it matters
The sprint is over. Your PM asks: 'What did we actually ship?' You open the repo, scroll through 80 commits with messages like 'fix stuff', 'wip', 'typo', and 'testing again'. There is no changelog. Nobody knows what version is deployed. The release notes are empty.
A good changelog is evidence of professional engineering. It keeps stakeholders informed, accelerates incident response ('which version introduced this?'), and helps new team members understand the project's trajectory. Git already contains all this information: you just need to know how to extract it.
Where it usually goes wrong
- Writing no changelog at all and relying on 'git log' dumps
- Using commit messages like 'fix' or 'update' that carry zero information
- Not tagging releases, making it impossible to compare versions
- Mixing features, fixes, and chores in a single unstructured history
- Generating changelogs manually instead of from Git data
Git changelogs, step by step
Step 1: Establish a commit message convention
Useful changelogs start with useful commit messages. The Conventional Commits specification is the industry standard. Every commit message follows a predictable format that tools can parse automatically.
Terminal# Conventional Commits format:# <type>[optional scope]: <description># Types:# feat - new feature (bumps MINOR version)# fix - bug fix (bumps PATCH version)# docs - documentation only# style - formatting, no logic change# refactor - neither fix nor feature# test - adding/updating tests# chore - build process, deps, tooling# perf - performance improvement# ci - CI configuration# Examples:git commit -m "feat(auth): add OAuth2 login with GitHub"git commit -m "fix(api): handle null response in user endpoint"git commit -m "docs: update README with setup instructions"git commit -m "feat!: redesign settings page (BREAKING CHANGE)"Tip: Add a git commit-msg hook or use a tool like
commitlintto enforce Conventional Commits on your team. Consistent messages = automatic changelogs.Step 2: Tag your releases
Tags are the anchors of your changelog. Every release, even a small one, should be tagged. Use semantic versioning: MAJOR.MINOR.PATCH.
Terminal# Create an annotated tag (recommended - stores metadata)git tag -a v1.3.0 -m "Release v1.3.0: OAuth login and perf improvements"# Create a lightweight tag (for internal markers)git tag v1.3.0-rc1# Push a tag to remotegit push origin v1.3.0# Push all tags at oncegit push origin --tags# List all tagsgit tag -l# List tags with a patterngit tag -l "v1.*"Tip: Always use annotated tags (
-a) for releases. They store the tagger, date, and message. Lightweight tags are just pointers with no metadata.Step 3: Generate a changelog from git log
Use
git logwith formatting flags to extract commit data between two tags. This is the foundation of any changelog.Terminal# All commits between two tags, one per line:git log v1.2.0..v1.3.0 --oneline# Pretty format with author and date:git log v1.2.0..v1.3.0 --pretty=format:"- %s (%an, %ad)" --date=short# Filter only features and fixes (Conventional Commits):git log v1.2.0..v1.3.0 --oneline --grep="^feat" --grep="^fix"# Example output:# - feat(auth): add OAuth2 login with GitHub (jane, 2025-04-10)# - fix(api): handle null response in user endpoint (tom, 2025-04-09)# - feat(ui): redesign settings page (jane, 2025-04-08)Step 4: Automate changelog generation
Once your commits follow Conventional Commits, a tool can generate a full, categorized changelog automatically. The most popular option is
conventional-changelog-cli.Terminal# Install conventional-changelog-cli globallynpm install -g conventional-changelog-cli# Generate changelog for the latest release, prepend to CHANGELOG.mdconventional-changelog -p angular -i CHANGELOG.md -s# Generate from the beginning of the projectconventional-changelog -p angular -i CHANGELOG.md -s -r 0# Alternative: use standard-version for bump + changelog + tag in one stepnpm install -g standard-versionstandard-version# This will:# 1. Bump version in package.json (based on commit types)# 2. Update CHANGELOG.md# 3. Commit the changes# 4. Create a new version tagTip:
standard-versionor its successorrelease-itautomates the entire release workflow: version bump, changelog update, commit, and tag in a single command.In Gitoryx: Select any date range on the commit graph to instantly see every commit shipped during a sprint.How it works Step 5: Visualize your sprint in git log
To see what shipped in a sprint, scope your git log to the sprint's date range or tag range. Use
--graphfor a visual branch view.Terminal# Commits during a sprint (date range):git log --oneline --after="2025-04-01" --before="2025-04-15"# Commits on main during the sprint, with branch graph:git log --oneline --graph --after="2025-04-01" --before="2025-04-15" main# Group by author - useful for sprint retrospective:git shortlog -sn --after="2025-04-01" --before="2025-04-15"# Output:# 14 Jane Smith# 9 Tom Williams# 6 Ana Rodrigues# Count commits by type during sprint:git log --oneline --after="2025-04-01" --before="2025-04-15" | grep "^feat" | wc -lStep 6: Compare two sprints or releases
Use tag-based ranges to produce a diff summary between any two versions, ideal for release notes or sprint comparisons.
Terminal# Files changed between two releases:git diff v1.2.0 v1.3.0 --stat# Commits by type between two releases:git log v1.2.0..v1.3.0 --oneline | grep "^feat" git log v1.2.0..v1.3.0 --oneline | grep "^fix"# Full diff of a specific file between releases:git diff v1.2.0..v1.3.0 -- src/auth/login.ts# Which branches were merged in this range:git log v1.2.0..v1.3.0 --merges --onelineStep 7: Build a CHANGELOG.md with the Keep a Changelog format
If you prefer a manually curated changelog, Keep a Changelog (keepachangelog.com) is the most widely adopted format. Structure it as Markdown with sections per release.
markdown# CHANGELOG.md - Keep a Changelog format## [Unreleased]## [1.3.0] - 2025-04-15### Added- OAuth2 login with GitHub- Dark mode toggle in settings### Fixed- Null response crash in user API endpoint- Race condition in session refresh### Changed- Settings page redesigned for clarity## [1.2.0] - 2025-03-20### Added- User avatar upload### Fixed- Login timeout not applying correctlyTip: Keep an
[Unreleased]section at the top. Move entries from Unreleased to a versioned section when you cut a release.
Mistakes to avoid with Git changelogs
- No commit message convention
- Without a convention like Conventional Commits, every changelog must be written manually. Messages like 'fix stuff' or 'minor updates' are useless for automated or manual changelog generation.
- Fix: Adopt Conventional Commits from day one. Enforce it with
commitlintin a pre-commit hook or CI pipeline. The payoff is automatic changelogs and semantic versioning forever. - Not tagging releases
- Without version tags, there are no anchors in history. You cannot generate a changelog between 'this release' and 'the previous one' because Git doesn't know where releases are.
- Fix: Tag every release immediately after merging to main:
git tag -a v1.x.x -m 'Release message'. Automate this withstandard-versionorrelease-it. - Mixing fixes and features in the same commit
- A commit that fixes a bug AND adds a feature is impossible to categorize correctly. It will appear in the wrong section of the changelog, or be skipped entirely.
- Fix: Keep commits atomic: one logical change per commit. If you did two things, use
git add -pto stage them separately and create two commits. - Generating changelogs only at release time
- Waiting until release to write changelog entries is painful: you have to trace through every commit and reconstruct context that's long gone.
- Fix: Update the
[Unreleased]section of CHANGELOG.md with each PR merge. Make it part of the PR template checklist.
Git changelogs in Gitoryx
Gitoryx lets you generate a changelog from any sprint or tag: select a date range on the commit graph to see what shipped during a sprint, or pick two tags to instantly list all commits between releases, no git log commands needed.
- Select any date range on the commit graph to instantly see every commit shipped during a sprint.
- Pick two tags and Gitoryx lists all commits between them: your release changelog in one click.
- Tag a release directly from the commit graph: right-click any commit and choose 'Create tag'.
- The author lane view shows commit activity per developer, giving sprint-level contribution visibility.
- The visual branch history makes it obvious when features were merged relative to release points.
Free plan · no account required · macOS, Windows and Linux
Git changelogs: frequently asked questions
- What is a Git changelog?
- A Git changelog is a structured document that records what changed between versions of a project. It is typically generated from commit history and release tags, organized by version and change type (features, fixes, breaking changes).
- What is Conventional Commits?
- Conventional Commits is a specification for writing structured commit messages. Each message starts with a type (
feat,fix,docs, etc.), an optional scope, and a description. This structure enables automated changelog generation and semantic versioning. - How do I generate a changelog from git log?
- Use
git log v1.0.0..v1.1.0 --pretty=format:'- %s (%an)' --grep='^feat' --grep='^fix'to extract commits between two tags filtered by type. For full automation, useconventional-changelog-cliorstandard-version. - What is semantic versioning?
- Semantic versioning (semver) is a versioning system: MAJOR.MINOR.PATCH. Breaking changes increment MAJOR. New features increment MINOR. Bug fixes increment PATCH. With Conventional Commits, the version bump can be automated based on commit types.
- How do I see what was committed during a sprint in Git?
- Use
git log --oneline --after='YYYY-MM-DD' --before='YYYY-MM-DD'scoped to your sprint dates. Usegit shortlog -snwith the same flags to group by author. - What is the difference between an annotated tag and a lightweight tag?
- An annotated tag (
git tag -a) stores a tagger name, date, and message alongside the tag. A lightweight tag is just a pointer to a commit with no metadata. Always use annotated tags for releases. - What tools automate changelog generation?
- Popular tools include
conventional-changelog-cli(generates from Conventional Commits),standard-version(bump + changelog + tag in one command),release-it(flexible release workflow), andgit-cliff(Rust-based, highly configurable). - How do I compare two Git releases?
- Use
git log v1.0.0..v1.1.0 --onelineto list commits between tags. Usegit diff v1.0.0 v1.1.0 --statfor a file-level summary. Usegit diff v1.0.0..v1.1.0 -- path/to/filefor a specific file.
Related reading
- GitFlow Explained: The Classic Branching ModelTutorial · 11 min
- Git Branching Strategy: A Complete GuideTutorial · 14 min
- Git Bisect: Find the Commit That Broke Your CodeTutorial · 11 min