[git] Unstaged changes left after git reset --hard

I hit a similar issue also involving .gitattributes, but for my case involved GitHub's LFS. While this isn't exactly the OP's scenario, I think it provides an opportunity to illustrate what the .gitattributes file does and why it can lead to unstaged changes in the form of "phantom" differences.

In my case, a file already was in my repository, like since the beginning of time. In a recent commit, I added a new git-lfs track rule using a pattern that was in hindsight a bit too broad, and ending up matching this ancient file. I know I didn't want to change this file; I know I didn't change the file, but now it was in my unstaged changes and no amount of checkouts or hard resets on that file was going to fix it. Why?

GitHub LFS extension works primarily through leveraging the hooks that git provides access through via the .gitattributes file. Generally, entries in .gitattributes specify how matching files should be processed. In the OP's case, it was concerned with normalizing line endings; in mine, it was whether to let LFS handle the file storage. In either case, the actually file that git sees when computing a git diff does not match the file that you see when you inspect the file. Hence, if you change how a file is processed via the .gitattributes pattern that matches it, it will show up as unstaged changes in the status report, even if there really is no change in the file.

All that said, my "answer" to the question is that if the change in .gitattributes file is something you wanted to do, you should should really just add the changes and move on. If not, then amend the .gitattributes to better represent what you want to be doing.

References

  1. GitHub LFS Specification - Great description of how they hook into the clean and smudge function calls to replace your file in the git objects with a simple text file with a hash.

  2. gitattributes Documentation - All the details on what is available to customize how git processes your documents.