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.
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
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
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.
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
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.
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:
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