You’ll often need to compare different tagged versions of your codebase to track modifications between releases.
Git’s diff command lets you easily visualize these changes between any two tags in your repository.

In this guide, you’ll learn how to effectively use git diff with tags to analyze your project’s evolution and better understand code changes across releases.

What are Git Tags

Assuming you’re working with Git, tags serve as reference points marking specific commits in your repository’s history.
They typically represent release versions, milestones, or important checkpoints in your project.
You can think of tags as sticky notes attached to specific commits, making them easily identifiable and accessible later.

Tag Naming Conventions

Any consistent tag naming pattern will help you maintain order in your repository.

You’ll commonly see semantic versioning (v1.0.0, v2.1.0) or date-based tags (release-2024-10).
Choose a convention that fits your project’s release strategy and stick to it.

Git Diff Command

Assuming you have multiple tags in your repository, you can compare differences between any two tags using Git’s diff command.
The basic syntax follows the pattern git diff tag1 tag2, which shows all changes made between these two tagged versions.
This command shows you the differences between two tagged versions of your repository in all the files, helping you track changes between releases.

An alternate syntax for comparing two tags is

git diff tag1..tag2

Understanding the diff output becomes easier with practice.
The '-' symbol indicates removed lines, '+' shows added lines, and unchanged lines provide context.

Structure of the diff command can be enhanced with additional options, which are covered in this article.

Viewing Changes in Specific Files

With Git diff, you can narrow down your comparison to specific files between tags. Use the command

git diff v1.0 v2.0 -- path/to/file

to see changes in particular files only.

It’s helpful to know that you can specify multiple files by listing them after the tags: git diff v1.0 v2.0 -- file1.txt file2.txt.
This approach lets you focus on relevant changes while ignoring modifications in other files.

Filtering Diff Output

Some situations require filtering the diff output to focus on specific types of changes.
You can use options like --diff-filter to show only added, modified, or deleted files between tags.

# show only modified files
git diff v1.0 v2.0 --diff-filter=M

# show only deleted files
git diff v1.0 v2.0 --diff-filter=D

# show only new added files
git diff v1.0 v2.0 --diff-filter=A

Output filtering helps you manage large diffs effectively and makes reviewing changes more manageable when dealing with numerous files.

Showing Changes Stats

The git diff --stat option provides a summary of changes between commits, branches, or the working directory by showing the number of lines added and deleted per file.
It displays a concise overview of the files that have been modified, along with the number of insertions(+) and deletions(-) in each file.
This is particularly useful for quickly assessing the scope of changes without viewing the full diff.

For example, running git diff --stat v1.0 v2.0 compares both tags and outputs a summary as below

 src/main.java |  5 ++++-
 README.md     |  2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)

This helps developers understand the impact of changes at a glance.

Showing Summary

The git diff --summary option provides a high-level overview of changes, focusing on file-level modifications such as creations, deletions, renames, and mode changes.

In Git, mode changes refer to changes in a file’s permissions (such as read, write, and execute permissions) or file type (e.g., from a regular file to an executable).
These are tracked in Git as mode bits, similar to UNIX file permissions.

Instead of showing the full diff output, it lists files that have been modified, added, or deleted, along with a brief description of the changes.

This is particularly useful for quickly reviewing the scope of changes without delving into detailed line-by-line differences.

For example, running git diff --summary v1.0 v2.0 will display a summary of changes as shown below

 rename old_file.txt => new_file.txt (100%)
 create mode 100644 new_script.sh
 delete mode 100644 removed_file.txt

This indicates that old_file.txt was renamed, new_script.sh was created, and removed_file.txt was deleted.
This option is particularly useful in code reviews to track structural modifications efficiently.

Displaying Detailed Changes

The git diff --patch (or -p) option in Git is used to display changes between commits, branches, or the working directory and the index in a patch format.

This format provides a detailed, line-by-line comparison of the differences, including added, removed, and modified lines, along with context lines for better understanding.

The patch format is particularly useful for reviewing changes before committing them or for generating patches that can be applied to other repositories.

For example, running git diff --patch v1.0 v2.0 shows the differences between the last commit and the one before it in patch format, making it easier to inspect changes or share them with others. Example output,

diff --git a/main.java b/main.java
index 3b18e5d..e8a4f92 100644
--- a/main.java
+++ b/main.java
@@ -5,7 +5,7 @@ public class Main {
     public static void main(String[] args) {
         System.out.println("Hello, World!");
     }
-    int x = 10;
+    int x = 20;
 }

Exporting patch file

Let’s say you want to provide differences between two tags to your client.

git diff can do this with its --patch option and redirecting the output to a file with below command.

git diff v1.0 v2.0 --patch > changes.patch

The patch file will contain the delta of the changes between two tags and the changes in this file can then be applied on the target repository with git apply.

Getting File Names

To get only the names of files having changes between two tags, use –name-only with git diff

git diff v1.0 v2.0 --name-only

Excluding Files from Diff

Tags comparison can be refined by excluding certain files or directories.
Use — followed by ‘!path of file to exclude’ as shown below

git diff tag1 tag2 -- ':!path/to/exclude'

git diff tag1 tag2 -- ':!src/main/java/com/codippa/FileToExclude.java'

Comparing tags while excluding specific files helps you focus on relevant changes.

You can also use wild-cards to exclude all files with certain extensions or even exclude a directory from comparing diffs such as

# exclude log files
git diff tag1 tag2 -- . ':!*.log' 

# exclude vendor directory
git diff tag1 tag2 -- ':!vendor/'

Order of Tags

Order of tags provided to git diff has an effect on the output produced.

git diff v1 v2 shows changes needed to go from v1 to v2 while
git diff v2 v1 shows changes needed to go from v2 back to v1.

Additions (+) in the first case indicate lines that were added in v2 (i.e., they are present in v2 but not in v1) while in the second case additions in v1 (relative to v2) appear as + changes.

Similarly, Deletions (-) indicate lines removed in v2 (i.e., they were in v1 but not in v2) while removals from v1 (relative to v2) appear as - changes.

So, you need to be very careful with the order of tags provided.

Summing up

On the whole, when you need to compare changes between two tagged versions of your repository, git diff provides you with powerful comparison capabilities.

You can use commands like git diff tag1 tag2 to see all differences, or git diff v1.0 v2.0 path/to/file.txt for specific file changes.

For a more detailed view, you can add the --stat option: git diff v1.0 v2.0 --stat

These comparisons help you track the evolution of your codebase and understand what changes were implemented between releases.

Categorized in:

Git,