Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does `.git/index` change when I haven't done anything to my repository?

Tags:

git

unison

With the latest Debian version of git (I'm using 1.7.2.5), I've noticed that a .git/index file may change mysteriously, without my having performed any operation that I feel should change the repository. (My shell occasionally runs git branch so it can display what branch is checked out, but that shouldn't change anything.) The change results in a .git/index file with the same length as the original, but containing different bits. What causes this change, and how can I stop it?

(The change is inconvenient because it messes things up for the Unison file synchronizer.)

like image 992
Norman Ramsey Avatar asked Aug 25 '12 22:08

Norman Ramsey


2 Answers

The index file shouldn't just randomly change. That is the staging tree, a buffer between the repository of commits and the working tree. For efficiency, it also stores some metadata about the working tree (the checked out files which you can modify), which would allow faster status or diff results. To see what kind of such information is stored, try to execute git ls-files --debug. This should print, for each file and directory, something like:

path/to/file
  ctime: 1332898839:873326227
  mtime: 1332898839:873326227
  dev: 2052     ino: 4356685
  uid: 1000     gid: 100
  size: 3065    flags: 6c

So, if a file changes in any way on the disk, not as its content, but internal stuff like which inode it's using, it will trigger an update to the index file next time the index is used.

git branch doesn't update the index, since it only checks the .git/HEAD file and the .git/refs/heads and .git/packed-refs files, it doesn't care about the index or the working tree. git diff and git status, on the other hand, do work with the index.

I did an experiment: I copied the current index file, I created a new version of a file making sure that a new inode will be assigned to it (copy, remove original, rename the copy back to the original name), executed git status, and then compared the new index file with the original copy. Two things changed: a line that contained the affected file in it, and the changes were in the bytes right before the filename, and a few bytes right at the end of the index file, probably a timestamp for the last index computation. The overall size of the file remained the same.

Back to your problem, if you're not executing any command that touches the index yourself, then maybe you have another tool that does that for you: an IDE plugin or a file browser extension that knows about git repositories, and which checks the status of git repositories. Or, there's another process that changes the way files are stored on disk, like a disk-defrag utility.

like image 68
Sergiu Dumitriu Avatar answered Oct 08 '22 13:10

Sergiu Dumitriu


I've come across this issue as well, and I believe it's the interaction between unison and git that is causing the problem. When unison synchronizes the two directories, it doesn't synchronize the ctimes. That means that in one copy of the git repository, say copy 2, the file ctimes don't match the times stored in .git/index. That means that .git/index in copy 2 will get updated the next time you run a git command that stats files. When unison runs, .git/index is copied to copy 1, but then its contents don't match the ctimes there. So the next time a git command is run there, the index is updated. Then unison copies it to copy 2, etc.

I haven't found a reasonable workaround for this. Setting core.trustctime=false doesn't help.

To the extent that .git/index is a cache, it should be omitted from synchronization by unison. But I believe that .git/index is also used to stage files, and one might start that process on one machine and finish it on another, which would require .git/index to be synchronized.

(I know some people think it's odd to synchronize git repos with unison, but the point of unison is that you can switch between working on two different machines and continue exactly where you left off. It's an amazing tool!)

like image 29
Dan Christensen Avatar answered Oct 08 '22 11:10

Dan Christensen