What is the difference between git diff HEAD vs. git diff --staged?

Git

Git Problem Overview


What is the difference between git diff HEAD and git diff --staged? I tried both but both give the same output.

Git Solutions


Solution 1 - Git

Suppose this output for git status:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   y
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   x
#

As you see, there is one file modified but not staged for commit, and a new file added that is ready to be committed.

git diff --staged will only show changes to files in the "staged" area.

git diff HEAD will show all changes to tracked files. If you have all changes staged for commit, then both commands will output the same.

Solution 2 - Git

  • git diff View difference between Stage and Working Directory
  • git diff --staged View difference between HEAD and Stage
  • git diff HEAD View difference between HEAD and Working Directory

enter image description here
img src

  • HEAD is a reference to the last commit in the currently checked-out branch.
  • Staging area, stage and index all mean the same thing
  • Unstaged changes exist in our Working Directory, but Git hasn’t recorded them into its version history yet.
  • Staged changes are a lot like unstaged changes, except that they’ve been marked to be committed the next time you run git commit

Solution 3 - Git

You will be able to see more easily the difference between the two diff with the upcomming (Git 2.3.4+, Q2 2015) git status -v -v

See commit 4055500 from Michael J Gruber mjg, it does a good job explaining the difference between git diff HEAD and git diff --staged:

> ### commit/status: show the index-worktree diff with -v -v

> git commit and git status in long format show the diff between HEAD and the index when given -v. This allows previewing a commit to be made.

> They also list tracked files with unstaged changes, but without a diff.

> Introduce '-v -v' which shows the diff between the index and the worktree in addition to the HEAD index diff. This allows a review of unstaged changes which might be missing from the commit.

> In the case of '-v -v', additional header lines

Changes to be committed:
# and
Changes not staged for commit:

> are inserted before the diffs, which are equal to those in the status part; the latter preceded by 50*"-" to make it stick out more.

Solution 4 - Git

Another edge case difference: In a newly created git repo, where only git init has been run so far, git diff HEAD will result in a fatal error (ambiguous argument 'HEAD') while git diff --staged will produce no output.

Solution 5 - Git

You can also get different output from the two diff commands if you are running them on an unsuccessful merge, i.e. unmerged paths.

I have not been able to find out why it behaves like this, but you could read more about it here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionvhdView Question on Stackoverflow
Solution 1 - GitCarlos CampderrósView Answer on Stackoverflow
Solution 2 - GitPremrajView Answer on Stackoverflow
Solution 3 - GitVonCView Answer on Stackoverflow
Solution 4 - Gitdave_k_smithView Answer on Stackoverflow
Solution 5 - GitBimmeView Answer on Stackoverflow