Difference between git diff and git diff –staged
git diff shows all the staged and unstaged changes, wrt the last commit. git diff –staged would show only the staged changes. Both of these show differences only on tracked files. git diff would mark only unstaged changes as new, whereas git diff HEAD would mark both staged and unstaged changes as new.
In case of a new file that is still not added, all these commands would show empty output. In case of all the changes are staged, git diff would show the output as empty. git diff HEAD and git diff –staged would show all the changes.
Let us see all these scenarios through a hands-on example.
Consider the initial setup as shown.
git branch shows that there is a branch called main.
git status shows that a new file dirone/fileseven is added and not tracked. It has two lines. Note this file is still not added to git.
~/codeversion$ git branch
* main
~/codeversion$ git status
On branch main
Your branch is up to date with 'origin/main'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
dirone/fileseven
nothing added to commit but untracked files present (use "git add" to track)
~/codeversion$ cat dirone/fileseven
This is fileseven line 1
Now, if you issue git diff, git diff –staged, or git diff HEAD, all these commands would show empty output.
~/codeversion$ git diff
~/codeversion$ git diff --staged
~/codeversion$ git diff HEAD
~/codeversion$
Let us now add this file to git versioning.
Then make a change as shown and leave it unstaged, i.e., do not add the file after the new change.
Now git status would show that the file dirone/fileseven is in git versioning. However, there are also unstaged changes in the file.
~/codeversion$ git add dirone/fileseven
~/codeversion$ git status
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: dirone/fileseven
~/codeversion$ echo "This is second line" >> dirone/fileseven
~/codeversion$ git status
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: dirone/fileseven
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: dirone/fileseven
Now, we will see that git diff, git diff HEAD, and git diff –staged show different outputs.
git diff and git diff HEAD showed all changes along with unstaged changes. The unstaged change here is “This is second line”. But, git diff HEAD marked only the unstaged change as new. git diff marked both changes that are staged and not staged as new.
git diff –staged showed only till the line “This is fileseven line 1”. Note that we have earlier staged that change by doing git add.
~/codeversion$ git diff
diff --git a/dirone/fileseven b/dirone/fileseven
index d057506..5d8f326 100644
--- a/dirone/fileseven
+++ b/dirone/fileseven
@@ -1 +1,2 @@
This is fileseven line 1
+This is second line
~/codeversion$ git diff HEAD
diff --git a/dirone/fileseven b/dirone/fileseven
new file mode 100644
index 0000000..5d8f326
--- /dev/null
+++ b/dirone/fileseven
@@ -0,0 +1,2 @@
+This is fileseven line 1
+This is second line
~/codeversion$ git diff --staged
diff --git a/dirone/fileseven b/dirone/fileseven
new file mode 100644
index 0000000..d057506
--- /dev/null
+++ b/dirone/fileseven
@@ -0,0 +1 @@
+This is fileseven line 1
Now, if we do git add on the file, we will see that the output of the three commands varies.
~/codeversion$ git status
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: dirone/fileseven
git diff HEAD and git diff –staged would show all the changes. git diff, however, would show empty output.
~/codeversion$ git diff
~/codeversion$ git diff --staged
diff --git a/dirone/fileseven b/dirone/fileseven
new file mode 100644
index 0000000..5d8f326
--- /dev/null
+++ b/dirone/fileseven
@@ -0,0 +1,2 @@
+This is fileseven line 1
+This is second line
~/codeversion$ git diff HEAD
diff --git a/dirone/fileseven b/dirone/fileseven
new file mode 100644
index 0000000..5d8f326
--- /dev/null
+++ b/dirone/fileseven
@@ -0,0 +1,2 @@
+This is fileseven line 1
+This is second line