Git diff

  1. Diff outputs
  2. Highlighting changes
  3. Diffing binary files
  4. Comparison of files: git diff file
  5. Comparison of all changes
  6. Changes since the recent commit
  7. Comparison of files between two commits
  8. Comparison of branches
  9. Comparison of the files from two branches


The git diff is a multi-function Git command, which is used to compare changes committed in Git. Particularly, with the help of this command, you can take two input data sets and output the modifications between them. While executing, this command runs a diff function on Git data source. Commonly, it is used in combination with git status and git log commands for analyzing the state of a git repository.

Diff outputs

Diffing can have multiple outputs that will be discussed below.

Raw output format

Take a look at the commands below to create a simple repository:

mkdir test_repo
cd test_repo
touch test.txt
echo "this is a git diff test example" > test.txt
git init .
#Initialized empty Git repository in /Users/kev/code/test/.git/
git add test.txt
git commit -am "add diff test file"
#[master (root-commit) 9e2dcac] add diff test file
#1 file changed, 1 insertion(+)
#create mode 100644 test.txt

If you want the git diff to have an output, you have to change the content of the test.txt file after adding it to the created repository. You can do it by executing the following command:

echo "this is a diff example" > test.txt

Only now we can view a diff and discuss output. Executing git diff will produce the following:

diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

Diff input sources

Below you can find the comparison input of diff. As a result, a/test.txt and b/test.txt will be passed to the diff.

diff --git a/test.txt b/test.txt

Meta data

This line shows some internal Git meta data .The numbers in this output match to Git object version hash identifiers.

index 6b0c6cf..b37e70a 100644

Symbols for changes

These lines show the symbols assigned to each diff input source. Changes from a/test.txt are marked with a --- and the changes from b/test.txt are marked with the +++ symbol.

--- a/test.txt
+++ b/test.txt

Diff chunks

A diff doesn’t show the whole file. It shows only modified lines. That modified portion is called a "chunk". The advantage of the chunks is that they show lines before and after the changes, so you can have a better understanding of the modifications.

@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

The first line is the chunk header. Each chunk is placed by a header within @@ symbols. The changes made to the file are summarized in the header.

Highlighting changes

You can use the following 2 tools for highlighting changes so that they will be more visible.

git diff --color-words

The first way of highlighting changes is the special mode that git diffproposes: ‐‐color-words. It tokenizes added and removed lines by whitespace and then diffs those.

git diff --color-words
diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
this is agit difftest example

git diff-highlight

In the case of cloning the git source, a sub-directory call contrib will be found. This sub-directory contains tools that are related to Git. One of these tools is called diff-highlight. It highlights changed sub-word pieces.

git diff | /your/local/path/to/git-core/contrib/diff-highlight/diff-highlight
diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

Diffing binary files

Git diff can be run not only on text files, but also on binary ones. The default option can sometimes be not very useful.

git diff
Binary files a/script.pdf and b/script.pdf differ

Git has a feature allowing you to specify a shell command to convert the binary files content into text prior to performing the diff. However, a little set up may be required. First of all, you should define a textconv filter with the description of the conversion way of a certain type of binary to a text. For example, you can use a simple utility called pdftohtml (available through homebrew) to convert PDF into HTML. There are two ways of setting it up: by editing the .git/config file, or globally, by editing .gitconfig.

[diff "pdfconv"]
textconv=pdftohtml -stdout

Then you need to connect one or more file patterns with the pdfconv filter, which can be done by creating a .gitattributes file in the root of the repository.

*.pdf diff=pdfconv

After the configuration, git diff will firstly run the binary file via the configured converter script and diff the output of the converter. Using the same technique, you can also have helpful diffs from all types of a binary file (zips, jars, and other archives).

Comparison of files: git diff file

The git diff command has also an explicit file path option. The Git diff operation will go through the specific file once the file path passed to git diff. In the example below, the ./path/to/file argument will compare the modifications in the working directory against the index and display the changes that haven’t been staged yet. It will perform the comparison against HEAD.

git diff HEAD ./path/to/file

Comparison of all changes

In order to compare changes throughout the whole repo, you should run git diff without a file path. So, you can invoke the examples above without the ./path/to/file argument and have the same results across all files in the local repository.

Changes since the recent commit

Initially, git diff shows all of the uncommitted changes since the most recent commit:

git diff

Comparison of files between two commits

Thegit diff command can be passed to Git refs, such as names of head, tags, and branches. Every commit in Git has its commit ID which can get when executing git log. The commit ID can also be passed to git diff.

Comparison of branches

The comparison of branches is executed similarly to other ref inputs to git diff. Let’s see dot operator examples:

git diff branch1..branch2

The two dots in the example above show that the diff input is the tips of both branches. You will have the same result if the dots are left out and space is used between the branches. Besides, there is a three-dot operator:

git diff branch1...branch2

The three-dot operator changes the first input parameter branch1 initiating the diff. It transforms branch1 into a ref of the shared common ancestor commit between the two diff inputs. The last input parameter stays the same as the tip of branch2.

Comparison of the files from two branches

In order to compare a specific file in branches, you should pass in the path of the file as the third argument to git diff:

git diff master new_branch ./test.txt

Do you find this helpful?

Related articles