What is the difference between git diff HEAD vs. git diff --staged?
Git diff is a very useful command to show the difference between different states of the repository. In this article, we will explore the different options of the git diff command.
The git diff
command has a lot of options and can be used to compare the working directory with the staging area (index),
or the staging area with a commit, or a commit with the working directory.
That diagram is a TLDR for this article:
Setup
To explore these different options, let’s create a repository with 4 commits.
The commit graph looks like this:
diff between commits
You can use git diff commit1 commit2
to compare two commits.
alina
alina git:( main ) git diff 30fc93 86c453
diff --git a/README.md b/README.md
index b126713..a17ddff 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
commit #1
commit #2
commit #3
+commit #4
alina git:( main ) █
You can also use the HEAD~n
notation to refer to the n-th parent of the current commit.
alina
alina git:( main ) git diff HEAD^1 HEAD
diff --git a/README.md b/README.md
index b126713..a17ddff 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
commit #1
commit #2
commit #3
+commit #4
alina git:( main ) █
file modified in working directory, not staged
Things get more interesting when you modify a file in the working directory.
We added a line to the README.md
file, and now git status
reports that the file is modified.
alina
alina git:( main ) git status
On branch main
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: README.md
no changes added to commit (use "git add" and/or "git commit -a")
alina git:( main ) █
Technically, there are now 3 versions of the README.md
file:
- the one in the last commit
- the one in the working directory
- the one in the staging area
The git diff
command can compare any two of these versions.
Here is a diagram showing the options for git diff
and what they compare:
git diff HEAD
Using git diff HEAD
, we can see the changes made between your file in the working directory and the last commit.
alina
alina git:( main ) git diff HEAD
diff --git a/README.md b/README.md
index a17ddff..be9b03f 100644
--- a/README.md
+++ b/README.md
@@ -2,3 +2,4 @@ commit #1
commit #2
commit #3
commit #4
+commit #5
alina git:( main ) █
git diff
The git diff
command compares the working directory with the staging area.
alina
alina git:( main ) git diff
diff --git a/README.md b/README.md
index a17ddff..be9b03f 100644
--- a/README.md
+++ b/README.md
@@ -2,3 +2,4 @@ commit #1
commit #2
commit #3
commit #4
+commit #5
alina git:( main ) █
git diff —staged
The git diff --staged
command compares the staging area with the last commit.
alina
alina git:( main ) git diff --staged
alina git:( main ) █
No difference here because we haven’t added anything to the staging area yet.
git diff commit
Using git diff <commit>
, you can also compare your working directory with any commit.
alina
alina git:( main ) git diff HEAD~1
diff --git a/README.md b/README.md
index b126713..be9b03f 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
commit #1
commit #2
commit #3
+commit #4
+commit #5
alina git:( main ) █
file modified in working directory, and staged
Let’s stage the file:
alina
alina git:( main ) git add README.md
alina git:( main ) █
git diff
This time, the git diff
command shows no difference between the working directory and the staging area.
alina
alina git:( main ) git diff
alina git:( main ) █
git diff —staged
The git diff --staged
command shows the difference between the staging area and the last commit.
alina
alina git:( main ) git diff --staged
diff --git a/README.md b/README.md
index a17ddff..be9b03f 100644
--- a/README.md
+++ b/README.md
@@ -2,3 +2,4 @@ commit #1
commit #2
commit #3
commit #4
+commit #5
alina git:( main ) █
git diff HEAD
The git diff HEAD
command shows the difference between the working directory and the last commit.
alina
alina git:( main ) git diff HEAD
diff --git a/README.md b/README.md
index a17ddff..be9b03f 100644
--- a/README.md
+++ b/README.md
@@ -2,3 +2,4 @@ commit #1
commit #2
commit #3
commit #4
+commit #5
alina git:( main ) █
commit the staging area
Let’s create a commit with the staging area:
alina
alina git:( main ) git commit -m 'commit #5'
[main 29455b1] commit #5
1 file changed, 1 insertion(+)
alina git:( main ) █
The commit graph now looks like this:
git diff
The git diff
command shows the differences between the working directory and the index.
There are no differences between the working directory and the index.
alina
alina git:( main ) git diff
alina git:( main ) █
git diff —staged
The git diff --staged
command shows the differences between the index and the HEAD.
It is empty because we just committed the index.
alina
alina git:( main ) git diff --staged
alina git:( main ) █
git diff HEAD
The git diff HEAD
command shows the differences between the working directory and the HEAD.
It is also empty because we just committed the index.
alina
alina git:( main ) git diff HEAD
alina git:( main ) █