An underlying problem is git is a file system on top of a file system.
If every time the journal / write-ahead log was flushed, the files were rehashed, we wouldn't need index vs non-index so much.
We would use normal commands to sync two work trees one being what we have, and one being what we want to commit.
Instead of .gitignore we simply should have temp files elsewhere.
Basically the file system is a bad abstraction and all VCS is ad-hoc work around it.