We are thrilled to announce 📢 Kosli is now SOC 2 Type 2 compliant - Read more
✨ New Feature: Kosli Trails is live ✨ Create comprehensive audit trails for any DevOps activity - Read more
git diff tags

Using git diff to Compare Tags: A Guide With Examples

Bruce Johnston
Published October 13, 2022 in technology
clock icon 9 min read

In Git, you can use the git diff command for comparisons. This command is very powerful and flexible, and it covers a lot of ground, but today we’ll be narrowing the scope down to the “git diff tags” use case. 

In this post you’ll learn how to compare two tags in Git. We’ll cover some fundamentals about both the git diff command and tags, so don’t worry if you’re not familiar with these terms. 

By the end of the post, you’ll understand what tags are, how to diff them, and how to interpret the output of the diff itself. 

Does your team struggle with software audits? Is it a mess of screenshots and spreadsheets?

Learn how to automate it

Requirements

There are just a few requirements to follow along with this post: 

  • You should be comfortable working with the command line.
  • You should have Git installed on your system.
  • You should be familiar with some basic Git commands.

We don’t make any assumptions regarding your choice of operating systems. I’ll be testing the commands I write on both Windows and Linux (Ubuntu), but I expect them to work on macOS as well. 

git diff Tags 101

Let’s start by answering some fundamental questions so we’re all on the same page. 

What Are Git Tags?

Git tags are labels or marks you can add to a commit. Think of them as a friendlier name for a commit. If you mark a commit with the tag “good-spot,” then you can use “good-spot” to refer to that commit instead of, say, a854d19. 

People often use tags for marking software versions. So, at the exact spot where a new release is cut, you bump—that is, increase—the version number and then add a tag to that point. 

Here’s a quick example of tags in use:

$ mkdir demo

$ cd demo

$ echo hello > file

$ git init

$ git add .

$ git commit -m "create file"

$ git tag first-commit

In the example above we created a new repository, added a commit, and then added a tag to it. Now, running the git tag command will list “first-commit” as an output:

$ git tag
first-commit

What are git diffs?

To understand git diff, let’s first make sure we know what diff is. 

According to Wikipedia: 

In computing, the utility diff is a data comparison tool that computes and displays the differences between the contents of files.

So, we can say that git diff is just Git’s implementation of the diff utility. With this command you can compare two commits, branches, and, of course, tags. 

Let’s see a quick example of git diff in practice, using the same repo from the previous example: 

$ echo more text >> file
$ git diff

We simply append more text to the existing file and then run the diff command. If you’re following along you should see something like this:

diff --git a/file b/file
index 907cd4b..29cf517 100644
--- a/file
+++ b/file
@@ -1 +1,2 @@
 hello
+more text

If that output looks confusing, don’t worry - we’ll explain it in more detail later in this post. For now, understand that it just says the line “more text” was added as the second line of the text file.

Git Diff Tags: How To Use It In Practice

You now understand what tags are and what diff is. It’s time to put the two together! 

First, let’s commit the change made during the previous example:

$ git commit -am "append to the file"

Run git log --oneline, and you’ll see an output like the following:

$ git log --oneline
0f07e99 (HEAD -> main) append to the file
8ce58eb (tag: first-commit) create file

The only difference is that the commit hashes (the alphanumeric commit identifier you see at the start of the line) will be different from mine. 

Now let’s do three things: 

  • append yet another line to the file
  • commit that change
  • mark the commit with a new tag

The following commands accomplish the above:

$ echo another line >> file
$ git commit -am "edit the file"
$ git tag new-version

Running git tag now shows the two tags:

$ git tag
first-commit
new-version

Now that we have two tags, let’s compare them. Run the following command:

$git diff first-commit new-version

The output should look like this:

diff --git a/file b/file
index 907cd4b..b8fe3f1 100644
--- a/file
+++ b/file
@@ -1 +1,3 @@
 hello
+more text
+another line

Basically, here it says that the two tags differ regarding the file called file. The file has two more lines in the version pointed at by the most recent tag. 

Keep in mind that the order is relevant regarding git diff. Let’s run the command again, this time swapping the order of the tags:

$git diff new-version first-commit

Here’s the result:

$ git diff first-commit new-version
diff --git a/file b/file
index 907cd4b..b8fe3f1 100644
--- a/file
+++ b/file
@@ -1 +1,3 @@
 hello 
+more text
+another line

As you see, now it shows that the two last lines have been removed! You might have some reason to look at the changes this way, but if you want the comparison to take chronological order into account, you must also provide the tag names in the correct order. 

Understanding the Output of git diff

The output of git diff can look confusing at first. However, it’s not hard to understand once you know what each bit of information means. So, let’s cover that. We’ll examine the output of running git diff first-commit new-version, line by line. 

For reference, this is what the output looks like:

$ git diff first-commit new-version
diff --git a/file b/file
index 907cd4b..b8fe3f1 100644
--- a/file
+++ b/file
@@ -1 +1, 3 @@
 hello
+ more text
+ another line

What Is “A” and “B” in git diff?

The first line of the output is this:

diff --git a/file b/file

The line above indicates the file that we’re comparing. The name of the file is simply file. A and B are prefixes, indicating the comparison’s source and destination. It’s possible not to show prefixes:

$ git diff first-commit new-version --no-prefix
diff --git file file
index 907cd4b..b8fe3f1 100644
--- file
+++ file
@@ -1 +1,3 @@
 hello
+more text
+another line

You can also choose different prefixes for the source, destination, or both:

$ git diff first-commit new-version --src-prefix=start --dst-prefix=end
diff --git startfile endfile
index 907cd4b..b8fe3f1 100644
--- startfile
+++ endfile
@@ -1 +1,3 @@
 hello
+more text
+another line

What About Those Numbers?

The second line of the output is this:

index 907cd4b..b8fe3f1 100644

Here, 907cd4b is a sha1 hash identifying the first version of the file. b8fe3f1 identifies the latter version of the file. Finally, 100644 represents the file’s mode, indicating it’s a normal, non-executable file.

Plus and Minus Signs

Next, we have those two lines:

--- a/file
+++ b/file

Those are markers. They indicate that when you look at the next section, the minus sign will correspond to the first file while the plus sign will point to the latter version. 

Chunks

The next section of the diff output is called chunks. They indicate the exact lines of the file that were changed between the versions:

@@ -1 +1,3 @@

The -1 refers to the first file—which is marked by the minus sign, remember? This indicates that the first line of what we’ll see next is present in the first version of the file. 

The +1,3 part refers to the second version of the file, which is represented by the plus sign. This indicates that the first line of the following output is present in the second version of the file, and then it has a total of three lines that are present in the file as well. That makes sense since the most recent version has two more lines than the first one. 

Now we have the actual differences:

 hello 
+more text
+another line

The first line is present in both files. The second and third lines are present only in the second file, which is represented by +1,3. The plus signs at the start of the line indicate that those lines were added. 

Git Diff Tags: Useful Options

Let’s now explore some more ways to use this command. 

Showing Information About Files Changed

In our examples so far we changed only one file. A commit is likely to touch many different files in a real-world scenario. A comparison between two tags that are far apart is bound to result in a lot of output. You’ll often want Git to list all the changed files instead of showing the actual differences. For this, you can use the --stat option.

A commit is likely to touch many different files in a real-world scenario kosli quote

For this example let’s add two more commits. First, we’ll append again to the existing file:

$echo even more text >> file && git commit -am "another line"

Then, let’s create a new file and commit that as well:

$ echo new file > file2
$ git add .
$ git commit -m "create new file"

Finally, let’s create a tag:

$git tag number3

Then, let’s run the command:

$git diff first-commit number3 --stat

This results in the following output:

file  | 3 +++
 file2 | 1 +
 2 files changed, 4 insertions(+)

Git says that two files changed, with four insertions. We added three lines to the first file between the first tag and the latest one. The inclusion of the new file counts as one line. 

Without the --stat option we get the full diff, which is quite busier than what we’ve seen before:

$ git diff first-commit number3
diff --git a/file b/file
index 907cd4b..43044eb 100644
--- a/file
+++ b/file
@@ -1 +1,4 @@
 hello 
+more text
+another line
+even more text
diff --git a/file2 b/file2
new file mode 100644
index 0000000..fa49b07
--- /dev/null
+++ b/file2
@@ -0,0 +1 @@
+new file

As you can see, the result now contains two entries, one for each file. Regarding file2, it’s represented by /dev/null in the first tag. That happens because the file didn’t exist back then. 

Diffing Only One File

What if you want to compare two tags but are only interested in a single file? It’s possible to filter for a single file or folder. Just add two dashes and then the path to a file or folder. In our case, let’s say we only wanted the diff for file. Here’s what we’d do: 

$ git diff first-commit number3 -- file

The line above results in the output below:

diff --git a/file b/file
index 907cd4b..43044eb 100644
--- a/file
+++ b/file
@@ -1 +1,4 @@
 hello
+more text
+another line
+even more text

Conclusion - diff tags are useful and fun :)

Comparing versions of files is a core feature of a version control system. Git is no exception to that. This post shows us how to use the git diff command to perform a diff between tags. You’ve learned about tags themselves, what they’re used for, and how to interpret the output of the diff command. 

Where should you go now? I have two suggestions. First, continue exploring the diff command. Try to make different changes—for instance, remove lines—and see how the output of the command behaves. You can also explore some tools to make your diff viewing experience better. On Windows, WinMerge is a nice option. Meld is also interesting and available both for Windows and many Linux distributions.


ABOUT THIS ARTICLE

Published October 13, 2022, in technology

AUTHOR

Stay in the loop with the Kosli newsletter

Get the latest updates, tutorials, news and more, delivered right to your inbox
Kosli is committed to protecting and respecting your privacy. By submitting this newsletter request, I consent to Kosli sending me marketing communications via email. I may opt out at any time. For information about our privacy practices, please visit Kosli's privacy policy.
Kosli team reading the newsletter

Got a question about Kosli?

We’re here to help, our customers range from larges fintechs, medtechs and regulated business all looking to streamline their DevOps audit trails

Contact us
Developers using Kosli