Free Ebook cover Git for Programmers: Version Control for Small Projects

Git for Programmers: Version Control for Small Projects

New course

7 pages

Releases and Snapshots: Tagging Versions and Creating Recoverable Milestones in Git

Capítulo 7

Estimated reading time: 5 minutes

+ Exercise

What “Releases” and “Snapshots” Mean in Git

A Git tag is a human-friendly name attached to a specific commit. Unlike a branch, a tag does not move when you add new commits. That makes tags ideal for marking stable milestones such as “v1.0.0” or “2026-01-15-demo”.

In small projects, tags act like recoverable checkpoints: you can quickly compare versions, share an exact state with someone else, or roll back to a known-good point when something breaks.

Lightweight vs Annotated Tags

Lightweight tags (quick pointers)

A lightweight tag is just a name pointing at a commit. It’s fast to create and useful for personal or temporary markers.

git tag v1.0.0

Annotated tags (recommended for releases)

An annotated tag is a full Git object that includes a message, author, and date (and can be signed). For anything you consider a “release” or share with others, annotated tags are a better habit because they capture context.

git tag -a v1.0.0 -m "Release v1.0.0: first stable CLI"

Practical rule of thumb: use annotated tags for releases; use lightweight tags only for quick local markers you don’t care to document.

Continue in our app.

You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.

Or continue reading below...
Download App

Download the app

Naming Conventions: v1.0.0 and Friends

Consistent naming makes tags easy to scan, sort, and compare. A common convention is semantic versioning: vMAJOR.MINOR.PATCH.

  • MAJOR: breaking changes (users must adapt)
  • MINOR: new features, backward compatible
  • PATCH: bug fixes only

Examples:

  • v1.0.0 initial stable release
  • v1.0.1 bug fix release
  • v1.1.0 adds features without breaking existing usage

Keep tag names simple: avoid spaces; prefer dots and hyphens. If you need pre-releases, you can add suffixes like v1.2.0-rc.1.

Tagging a Specific Commit

By default, git tag tags the current commit (the one HEAD points to). You can also tag an older commit by providing its hash.

Tag the current commit

git tag -a v1.0.0 -m "Release v1.0.0: stable after tests"

Tag an earlier commit

git log --oneline --decorate

Copy the commit hash you want, then:

git tag -a v0.9.0 1a2b3c4 -m "v0.9.0: last beta"

If you accidentally tagged the wrong commit, you can delete and recreate the tag (locally) by removing it and tagging again.

git tag -d v1.0.0
git tag -a v1.0.0 <correct-commit> -m "Release v1.0.0: stable"

Listing and Inspecting Tags

List tags

git tag

To filter by pattern:

git tag -l "v1.*"

Show what a tag points to

To see the tagged commit and (for annotated tags) the tag message:

git show v1.0.0

To see the commit hash a tag resolves to:

git rev-parse v1.0.0

Pushing Tags to a Remote

Tags are not automatically pushed when you push commits. You must push them explicitly, which is a helpful safety feature: you can create tags locally, verify them, then publish.

Push one tag

git push origin v1.0.0

Push all tags

git push origin --tags

In small projects, prefer pushing individual release tags so you don’t accidentally publish experimental tags.

Practical Release Habits for Small Projects

1) Tag only after a passing build/test

Make “green build first” your default. The tag should represent a state you can confidently return to.

  • Run your test command (whatever your project uses).
  • Ensure the working tree is clean.
  • Create an annotated tag with a meaningful message.
git status
# run your tests here
git tag -a v1.0.0 -m "Release v1.0.0: tests passing; adds config loader"

2) Write tag messages that capture notable changes

A good tag message is short but specific. Include what changed and why it matters.

  • Good: “v1.1.0: adds JSON export; fixes crash on empty input”
  • Too vague: “release”

3) Use tags to compare versions

Tags are excellent anchors for diffs.

git diff v1.0.0 v1.1.0

You can also focus on file-level changes:

git diff v1.0.0 v1.1.0 -- path/to/file.py

4) Return to a known-good state (detached HEAD)

Checking out a tag puts you in a detached HEAD state: you’re viewing the project exactly as it was at that tag, but you’re not on a branch that will advance.

git checkout v1.0.0

In detached HEAD, you can build, run, or inspect safely. If you need to make a fix starting from that release, create a branch immediately so your work is anchored.

Create a hotfix branch from a tag

git checkout -b hotfix/v1.0.1 v1.0.0

Now you can commit your fix on hotfix/v1.0.1, test, and then tag a patch release when ready.

# edit files, run tests
git commit -am "Fix: handle empty config file"
git tag -a v1.0.1 -m "Release v1.0.1: fix empty config handling"

Mini-Release Exercise: Two Tags and a Changelog

This exercise simulates a small project release cycle: tag a stable version, make a change, tag again, then generate a concise changelog between the two tags.

Step 1: Ensure you are at a stable point

git status

Make sure your working tree is clean and tests/build pass.

Step 2: Create the first release tag (annotated)

git tag -a v1.0.0 -m "Release v1.0.0: stable baseline"

Step 3: Make a small change and commit it

# edit one file (e.g., add a small feature or fix)
git commit -am "Add: show version in --help output"

Step 4: Tag the next release

Again, do this after verifying the project still works.

git tag -a v1.1.0 -m "Release v1.1.0: adds version in help"

Step 5: Compare versions with a diff

git diff v1.0.0 v1.1.0

Step 6: Produce a concise changelog from git log

Generate a one-line-per-commit changelog between the tags:

git log --oneline v1.0.0..v1.1.0

If you want a slightly richer changelog including dates and authors:

git log --pretty=format:"- %s (%an, %ad)" --date=short v1.0.0..v1.1.0

Optional: Push the release tags

git push origin v1.0.0
git push origin v1.1.0

Now answer the exercise about the content:

In a small Git project, which approach best matches recommended release tagging and publishing habits?

You are right! Congratulations, now go to the next page

You missed! Try again.

Annotated tags store context (message/author/date) and are recommended for releases. Tags are not pushed automatically, so pushing specific release tags helps avoid accidentally publishing temporary or experimental tags.

Download the app to earn free Certification and listen to the courses in the background, even with the screen off.