Categories
diff dvcs git git-diff git-stage

How do I show the changes which have been staged?

2445

I staged a few changes to be committed. How do I see the diffs of all files which are staged for the next commit? Is there a handy one-liner for this?

git status only shows names of files which are staged, but I want to see the actual diffs.

The git-diff(1) man page says:

git diff [–options] [–] […]

This form is to view the changes you made relative to the index (staging area for the next commit). In other words, the differences are what you could tell git to further add to the index but you still haven’t. You can stage these changes by using git-add(1).

2

  • 111

    git status -v works too. See my answer below

    – VonC

    Mar 18, 2015 at 7:22

  • 4

    @VonC I always use this, but piped to less, as in: git status -v | less – manageable chunks 🙂

    – Mr Office

    Jul 25, 2016 at 17:17

2960

It should just be:

git diff --cached

--cached means show the changes in the cache/index (i.e. staged changes) against the current HEAD. --staged is a synonym for --cached.

--staged and --cached does not point to HEAD, just difference with respect to HEAD. If you cherry pick what to commit using git add --patch (or git add -p), --staged will return what is staged.

6

  • 46

    If you want the file names only, do the following git diff --name-only --cached per post at stackoverflow.com/a/4525025/255187

    Jul 26, 2012 at 18:47


  • 6

    Use this with git difftool --staged rather than git diff --staged to launch the default visual diff tool on each file. difftool can be substituted for diff with any other arguments as well.

    – LightCC

    Aug 14, 2017 at 23:03

  • And you can use git difftool --staged -d to diff the two directories in a visual tool rather than one file at a time.

    Aug 13, 2018 at 16:19

  • since this one is marked as answer and showing first it should include git diff at the top, then git [[others]], just my 2 cents

    Aug 2, 2019 at 13:09

  • And to view the changes in a single staged file, following will work: git diff --cached -- <stagedfile>

    Mar 5, 2020 at 19:21


1707

A simple graphic makes this clearer:

Simple Git diffs

git diff

Shows the changes between the working directory and the index. This shows what has been changed, but is not staged for a commit.

git diff –cached

Shows the changes between the index and the HEAD (which is the last commit on this branch). This shows what has been added to the index and staged for a commit.

git diff HEAD

Shows all the changes between the working directory and HEAD (which includes changes in the index). This shows all the changes since the last commit, whether or not they have been staged for commit or not.

Also:

There is a bit more detail on 365Git.

9

  • 8

    This is naive, I’m afraid (as is usually the case with any git explanation). If you have local modifications to foo.c and do not perform git add foo.c, then foo.c is not in the index; it is not staged for commit. If git diff foo.c naively compared to the working foo.c to the index, then it would have to show a giant diff between an empty/nonexistent file and the entire contents of foo.c. So in fact, when a file does not exist in the index, git diff falls back, for that file, on using the HEAD copy.

    – Kaz

    Nov 4, 2014 at 20:37

  • 10

    @Kaz strictly speaking, the index is not a blank slate. It’s a virtual copy of the HEAD on which the staged changes are applied. Remember that Git works by saving changes, not by saving entire files. When you stage a file, it’s only storing the changes made. If the index is blank like you imply, it wouldn’t know how to save the changes in the index, and would have to save the entire file as “newly added” – which is wrong.

    – ADTC

    Feb 4, 2015 at 3:32


  • 10

    @Kaz Both the index and the HEAD will have the unchanged version of the foo.c file (they are not physical copies, but just logical copies to you and me. To Git they are just the same data stream that every commit that ever involved that file refers to). So when you do git diff on the fully unstaged foo.c it’s not really falling back to HEAD it’s actually doing the diff with the Index (which happens to contain the exact same version of the file as HEAD does). So the graphic is correct.

    – ADTC

    Feb 4, 2015 at 3:36

  • 2

    Hello, I would like to know what it means “index” in this context? Thanks!

    Apr 18, 2016 at 13:23


  • 3

    @TomRussell git status -v is equivalent to git diff --cached (plus git status of course)

    – wisbucky

    Nov 29, 2017 at 0:38

62

Note that git status -v also shows the staged changes!
(meaning you need to have staged — git add — some changes. No staged changes, no diff with git status -v.
It does that since Git 1.2.0, February 2006)

In its long form (default), git status has an undocumented “verbose” option which actually display the diff between HEAD and index.

And it is about to become even more complete: see “Show both staged & working tree in git diff?” (git 2.3.4+, Q2 2015):

git status -v -v

6

  • The last line should be git diff HEAD

    – artur

    May 31, 2015 at 15:12

  • 4

    @artur why? The point of the answer is to mention that git status -vv also includes what git diff HEAD does.

    – VonC

    May 31, 2015 at 15:27

  • Does not work on git version 1.8.3.1. I know it’s old, but if possible, note when this flag was introduced.

    – onebree

    Jun 1, 2015 at 13:41

  • 2

    @onebree 1.8.3.1 is June 2013, old indeed. But git status -v is older (github.com/git/git/commit/…, git 1.2.0, February 2006!). Note that it displays the diff between the index and HEAD: if you have added anything to the index (no git add), then git status -v would not display any diff. git status -v -v is more recent (Git 2.3.4, March 2015)

    – VonC

    Jun 2, 2015 at 6:38

  • @VonC that was my mistake… I did git diff -v.

    – onebree

    Jun 2, 2015 at 12:51