0

Consider the following sequence of commands, which does the following: 1.Creates two branches (master and test_branch), where master has two commits, and test_branch has one commit. 2. The final state is that test_branch is checked out, but the working directory should match the tree at the tip of master exactly.

git init .
git commit --allow-empty -m 'Initial commit'
echo FOO > FOO.txt
git add FOO.txt
git commit -m 'Added foo'
git checkout -b test_branch HEAD^
git status
git checkout master -- .
git reset
git diff master

The output of this sequence of commands is the following:

diff --git a/FOO.txt b/FOO.txt
deleted file mode 100644
index b7d6715..0000000
--- a/FOO.txt
+++ /dev/null
@@ -1 +0,0 @@
-FOO

However, my working directory has FOO.txt with exactly the contents that git claims are missing:

cat FOO.txt
FOO

Is there some alternate invocation of git diff or lower level command that will force it to take the literal working tree and compare it with a commit, instead of pretending the untracked files in the working tree do not exist for the purposes of comparison?

merlin2011
  • 71,677
  • 44
  • 195
  • 329
  • You can use `git add -N .`. Then your untracked files will be present in the diff. See https://stackoverflow.com/q/855767/14967413 – user14967413 Jan 24 '23 at 09:54
  • It looks like this approach changes the index, so perhaps it's not possible to do it without changing the index. I'll post my silly workaround in that case. – merlin2011 Jan 24 '23 at 17:02
  • I believe `-N` option only modifies the index in the way that affects `git diff` and `git commit -a` commands as described in https://stackoverflow.com/a/24347875/14967413. Normal `git commit` should not be affected. – user14967413 Jan 24 '23 at 18:37
  • 1
    @user14967413, After running `git add -N .`, I can no longer run `git stash`: ```git stash error: Entry 'FOO.txt' not uptodate. Cannot merge. Cannot save the current worktree state``` – merlin2011 Jan 24 '23 at 23:07
  • The fact that it records a zero-length blob in the main index is still different from the desired entirely zero-index-modification state, and it can cause weird side effects like this, which we can try to workaround, but I think ultimately causes enough unexpected problems that it's not worth it. – merlin2011 Jan 24 '23 at 23:09

1 Answers1

0

Based on my current read of the docs, it seems like there's no way to perform this diff without adding the working directory to some index.

Therefore, I will continue to use the following hack, which adds the working tree to a secondary index file without touching the default index file. Note that the script deliberately excludes files that are ignored by .gitignore, since I do not care about diffing files I've explicitly ignored.

#!/bin/bash

TARGET_COMMIT="HEAD"
if [[ $# -gt 0 ]]; then
  TARGET_COMMIT="$1"
fi

GIT_ROOT="$(git rev-parse --show-toplevel)"
GIT_DIR="${GIT_DIR:-$GIT_ROOT/.git}"
export GIT_INDEX_FILE=$GIT_DIR/.xyz
rm -f $GIT_INDEX_FILE

git read-tree "$TARGET_COMMIT"
git add "$GIT_ROOT"
git diff --cached "$TARGET_COMMIT"
merlin2011
  • 71,677
  • 44
  • 195
  • 329