30

When I want to get git diff files, I found someone use

git diff-index --cached --diff-filter=AM --name-only HEAD 

and if I use

git diff --cached --diff-filter=AM --name-only HEAD 

can get the same result. So what's the difference between git diff and git diff-index? When you must use git diff-index but not git diff?

3 Answers 3

21

git diff-index is a diff against the index or working tree:

Compares the content and mode of the blobs found in a tree object with the corresponding tracked files in the working tree, or with the corresponding paths in the index

git diff is more versatile and can compare two files, or two commits, or (like diff-index) a tree and the index.

In your case, a diff HEAD would indeed diff HEAD against the index, which diff-index does too.


Warning: "git diff --cached"(man) codepath did not fill the necessary stat information for a file when fsmonitor knows it is clean, and ended up behaving as if it is not clean, which has been corrected with Git 2.43 (Q4 2023).

See commit 6a044a2 (11 Sep 2023) by Josip Sokcevic (sokac).
(Merged by Junio C Hamano -- gitster -- in commit 671eaaa, 20 Sep 2023)

diff-lib: fix check_removed when fsmonitor is on

Signed-off-by: Josip Sokcevic

git diff-index(man) may return incorrect deleted entries when fsmonitor is used in a repository with git submodules.
This can be observed on Mac machines, but it can affect all other supported platforms too.

If fsmonitor is used, stat *st is not initialized if cache_entry has CE_FSMONITOR_VALID set.
But, there are three call sites that rely on stat afterwards, which can result in incorrect results.

This change partially reverts commit 4f3d6d0 ("fsmonitor: skip lstat deletion check during git diff-index", 2021-03-17, Git v2.32.0-rc0 -- merge listed in batch #4).

Sign up to request clarification or add additional context in comments.

4 Comments

what is the index?
@Will the index is where you prepare your next commit. Linux Torvalds, when making Git back in 2005, needed a tool where he could add multiple changes while ignoring others, in order to prepare the next Linux code commit. For more: stackoverflow.com/a/4086986/6309
git diff-index is not always against the index. As the documentation says: "Compare a tree to the working tree or index"
@Droopycom Agreed. I have edited the answer accordingly.
5

After investigating the difference between these two commands, I have found starange behavior:

Looks like git diff-index is sensitive if the file has changed but the content is not. while git diff is not sensitive in this case.

In other words if you want to know if a file is NOT changed but you don't care the timestamp of the last-change was changed, use git diff.

  • Note: I'm not sure I'm correct here.

2 Comments

git.vger.kernel.narkive.com/3Xf875jB/… talks about this peculiarity of git diff-index
This is correct. Can be verified using touch foo && git diff-index HEAD -- foo. This will be reset by something like git status, see touch foo && git status > /dev/null && git diff-index HEAD -- foo
4

diff-index is a lower level operation that does less but is much faster because it doesn't look at the content, it only checks metadata like timestamps. Only Linux you can verify this with something like:

 strace -f -e file -o diff-index.log git diff-index HEAD wc diff-index.log less diff-index.log 

Forget about diff-index unless you have some git performance problem to solve.

https://git-scm.com/docs/git-update-index#_using_assume_unchanged_bit

https://public-inbox.org/git/[email protected]/

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.