Lesson 7 of 7 in Branching & Merging

Tags

Story: Some moments in a timeline matter more than others. Juno pins a marker on them so nobody loses them.

A tag is a name for one commit, like a branch. The difference is that a tag never moves. When you commit, the branch you're on moves to the new commit, and every tag stays where you put it. That makes tags the way to mark releases: v1.0 should always mean the same commit.

Annotated tags

$ git tag -a v1.0 -m "First release"

git tag -a makes an annotated tag on the commit you're on. An annotated tag is an object of its own in the repository. It records who made it, when, and a message, and it points at the commit. Use annotated tags for releases. Without -m, git opens your editor for the message, as git commit does.

git show shows an annotated tag first, then the commit it points at:

$ git show v1.0
tag v1.0
Tagger: You <you@example.com>
Date:   Mon Jan 1 09:11:00 2024 +0000

First release

commit a4b8d971a4104bc200dc7415344326f408c54d03 (HEAD -> main, tag: v1.0)
Author: You <you@example.com>
Date:   Mon Jan 1 09:10:00 2024 +0000

    Style the heading

diff --git a/style.css b/style.css
new file mode 100644
index 0000000..e6608d8
--- /dev/null
+++ b/style.css
@@ -0,0 +1 @@
+h1 { color: teal; }

Lightweight tags

Without -a, git tag v0.9 makes a lightweight tag: only a name for the commit, with no message of its own. Both kinds of tag take a commit after the name, to tag that commit instead of the one you're on: git tag v0.9 HEAD~1.

git tag on its own lists the tags, in name order. git log shows each one next to its commit:

$ git log --oneline
a4b8d97 (HEAD -> main, tag: v1.0) Style the heading
ab89288 (tag: v0.9) Add the home page
37d7cf7 Add a README

Using a tag

A tag works wherever git takes a commit: git log v1.0, git show v0.9, or git switch -c hotfix v1.0 to start a branch there. But a tag isn't a branch, so you can't switch to one:

$ git switch v1.0
fatal: a branch is expected, got tag 'v1.0'
hint: If you want to detach HEAD at the commit, try again with the --detach option.

git switch --detach v1.0 looks around at a tag's commit on a detached HEAD.

Moving and deleting tags

Each tag name can be used once. When v1.0 exists, git tag v1.0 stops with fatal: tag 'v1.0' already exists, and nothing changes. To put a tag somewhere else, delete it with git tag -d, then tag the right commit:

$ git tag -d v1.0
Deleted tag 'v1.0' (was e626b07)

For an annotated tag, the id after was is the tag object's, not the commit's. Deleting a tag never deletes a commit.

Command What it does
git tag -a <name> -m "<message>" Makes an annotated tag, with a message, on the commit you're on.
git tag <name> Makes a lightweight tag: just a name for the commit you're on.
git tag <name> <commit> Tags that commit instead. Works with -a too.
git tag Lists the tags.
git tag -d <name> Deletes a tag. The commit stays.

New commands

  • git tag
  • git tag -a
  • git tag -m
  • git tag -d

Explainer: Tags mark commits for good

project: your repo, you are here37d7cf7 Add a README37d7cf7ab89288 Add the home pageab89288a4b8d97 Style the headinga4b8d9715514ac Tighten the paragraphs15514actag: v1.0HEAD → main
The repository at the end of the Explainer.
Graph as text

project: your repo, you are here

  • HEAD → main at 15514ac "Tighten the paragraphs"

Branches and tags

  • main at 15514ac "Tighten the paragraphs"
  • v1.0 at a4b8d97 "Style the heading"

Commits, newest first

  1. 15514ac "Tighten the paragraphs"; parent a4b8d97; refs: HEAD → main
  2. a4b8d97 "Style the heading"; parent ab89288; refs: tag v1.0
  3. ab89288 "Add the home page"; parent 37d7cf7
  4. 37d7cf7 "Add a README"; no parent

Challenge 1 of 3

Story: This moment is the first release, Agent. Mark it so the whole agency can find it again.

main's newest commit is the project's first release. Tag it v1.0, with an annotated tag and a message such as First release. You're on main.

Unlocks after Basics.

Terminal

Unlocks after Basics.

This Lesson can be played once Basics is complete. Its text and Explainer are open to everyone.