Git Diff Git

Dec 4th, 2020 - written by Kimserey with .

Git Diff is a command used to look at changes between two revisions. The revision can be directly looked by branch tip, tag or commit hash. In this post we will look at the different usages of git diff and how to read the output.

Diff relative to index

The most common scenario for checking the diff between our feature-branch and current master.

1
A---B (master, feature-branch)

Here we have a feature-branch on the same commit as master, for example if we just created the branch. And we have added changes that we haven’t added to the index (staging area).

1
2
3
4
5
6
7
8
❯ git status
On branch feature-branch
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   b.md

no changes added to commit (use "git add" and/or "git commit -a")

We can see that we’ve modified b.md but haven’t gone yet into the index.

If we want to see the changes we are about to stage, we can use:

1
2
3
4
5
6
7
8
9
❯ git diff
diff --git a/b.md b/b.md
index 649e2f1..449c283 100644
--- a/b.md
+++ b/b.md
@@ -1,2 +1,3 @@
 Change in b
 Change in b
+Change in b

A simple git diff will show the diff between the current repository and the index. When looking at the diff output, we see the reference to a and b. a represents the index and b represents the unstaged changes (comming changes). We can see from this diff log that a line was added +Change in b, which means that b brought an extra line compared to a.

Diff between Index and HEAD

Now once we add the stage changes with git add, lets say we’ve staged multiple changes and are at a point where we want to commit in the current branch, we can check the diff between the index and HEAD (current branch tip):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
❯ git diff --cached   
diff --git a/a.md b/a.md
index f762684..be37bff 100644
--- a/a.md
+++ b/a.md
@@ -3,3 +3,4 @@ test
 test
 test
 test
+Change in a

diff --git a/b.md b/b.md
index 649e2f1..449c283 100644
--- a/b.md
+++ b/b.md
@@ -1,2 +1,3 @@
 Change in b
 Change in b
+Change in b

git diff --cached will show the diff between the current HEAD and the index. We can see that we have staged changes in two different files a.md and b.md. To view a single file, we can specify the name of the file at the end of the command:

1
2
3
4
5
6
7
8
9
10
❯ git diff --cached a.md
diff --git a/a.md b/a.md
index f762684..be37bff 100644
--- a/a.md
+++ b/a.md
@@ -3,3 +3,4 @@ test
 test
 test
 test
+Change in a

Diff between Branches

Once we have committed the change, we end up with the following graph:

1
2
3
      C feature-branch
     /
A---B master

Before we merge our changes to master if we want to check the diff between feature-branch and master we can do as such:

1
2
❯ git checkout feature-branch
❯ git diff master

which is equivalent to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
❯ git diff master feature-branch
diff --git a/a.md b/a.md
index f762684..be37bff 100644
--- a/a.md
+++ b/a.md
@@ -3,3 +3,4 @@ test
 test
 test
 test
+Change in a
diff --git a/b.md b/b.md
new file mode 100644
index 0000000..449c283
--- /dev/null
+++ b/b.md
@@ -0,0 +1,3 @@
+Change in b
+Change in b
+Change in b

which is also equivalent to:

1
❯ git diff master..feature-branch

The diff executed is from the tip of both branches, here we see the changes that feature-branch would bring into master, and because B is the tip of master it’s not a problem. If a new change is added to master, for example:

1
2
3
      C feature-branch
     /
A---B---D master

The tip of master is now D, hence by executing a regular diff, we will get the difference between C and D.

For example if we added D:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
❯ git show
commit 6114f573323841874ae262ac6bfdd76adb79ef46 (HEAD -> master)
Author: Kimserey Lam
Date:   Sat Nov 28 13:44:32 2020 +0000

    Added something in master

diff --git a/a.md b/a.md
index f762684..9b48ec7 100644
--- a/a.md
+++ b/a.md
@@ -3,3 +3,4 @@ test
 test
 test
 test
+Added something in master

And we do diff between master and feature-branch:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
❯ git diff master feature-branch
diff --git a/a.md b/a.md
index 9b48ec7..be37bff 100644
--- a/a.md
+++ b/a.md
@@ -3,4 +3,4 @@ test
 test
 test
 test
-Added something in master
+Change in a

diff --git a/b.md b/b.md
new file mode 100644
index 0000000..449c283
--- /dev/null
+++ b/b.md
@@ -0,0 +1,3 @@
+Change in b
+Change in b
+Change in b

Here we see that the change in D is also included in the diff -Added something in master. In some cases, for example in Pull-Request scenarios, we want to see only the changes brought by the branch rather than also the changes added to the upstream branch. To check that, we can use ... (triple dot diff):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
❯ git diff master...feature-branch
diff --git a/a.md b/a.md
index f762684..be37bff 100644
--- a/a.md
+++ b/a.md
@@ -3,3 +3,4 @@ test
 test
 test
 test
+Change in a

diff --git a/b.md b/b.md
new file mode 100644
index 0000000..449c283
--- /dev/null
+++ b/b.md
@@ -0,0 +1,3 @@
+Change in b
+Change in b
+Change in b

Triple dot is equivalent do doing a regular diff between the merge-base and feature-branch, merge-base being the base where master and feature-branch started to differ, meaning git diff master...feature-branch is equivalent to:

1
2
3
4
❯ git merge-base master feature-branch
e582ba2fb268908a6999c02a338235bf273fecda

❯ git diff e582ba2fb268908a6999c02a338235bf273fecda feature-branch

Diff between Commit Hashes

Lastly as we saw in the previous example with merge-base, git diff can also be used with specific commit hash:

1
2
3
4
❯ git log -3 --oneline
69a5fff (HEAD -> feature-branch) Commit changes
876bf66 Added b.md
e582ba2 Added test

We can check the changes brought into feature-branch by checking the diff between e582ba2 and 69a5fff which will essentially be 876bf66 and 69a5fff:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
❯ git diff e582ba2 69a5fff
diff --git a/a.md b/a.md
index f762684..be37bff 100644
--- a/a.md
+++ b/a.md
@@ -3,3 +3,4 @@ test
 test
 test
 test
+Change in a

diff --git a/b.md b/b.md
new file mode 100644
index 0000000..449c283
--- /dev/null
+++ b/b.md
@@ -0,0 +1,3 @@
+Change in b
+Change in b
+Change in b

which we can verify:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
❯ git show 876bf66
commit 876bf667c0968b0939c5cebff71ba4046e18f3f1
Author: Kimserey Lam
Date:   Sat Nov 28 13:09:45 2020 +0000

    Added b.md

diff --git a/b.md b/b.md
new file mode 100644
index 0000000..649e2f1
--- /dev/null
+++ b/b.md
@@ -0,0 +1,2 @@
+Change in b
+Change in b

❯ git show 69a5fff
commit 69a5fff5016458bb15ada89a2591137604e8691f (HEAD -> feature-branch)
Author: Kimserey Lam
Date:   Sat Nov 28 13:38:56 2020 +0000

    Commit changes

diff --git a/a.md b/a.md
index f762684..be37bff 100644
--- a/a.md
+++ b/a.md
@@ -3,3 +3,4 @@ test
 test
 test
 test
+Change in a
diff --git a/b.md b/b.md
index 649e2f1..449c283 100644
--- a/b.md
+++ b/b.md
@@ -1,2 +1,3 @@
 Change in b
 Change in b
+Change in b

Other than the commit hash itself, we can also look at the diff between the current unstaged changes and a specific commit within the checkout branch with HEAD~n:

1
❯ git diff HEAD~3

which will display the diff between the third commit from HEAD and the current unstaged changes.

And that concludes today’s post! I hope you liked this post and I see you on the next one!

External Sources

Designed, built and maintained by Kimserey Lam.