0

On an untouched file, git thinks the file is removed then added back. I can't figure out why.

The symptoms, in terms of git, can be shown as follows:

$ git diff-index --cached HEAD
:000000 100644 0000000000000000000000000000000000000000 8d1b41aeb85f3c2afc6e70e824902f3f365e416c A  myfile.h
:100644 000000 8d1b41aeb85f3c2afc6e70e824902f3f365e416c 0000000000000000000000000000000000000000 D  myfile.h

This looks alien to me. The checksum of the file is the same, the mode of the file is the same, but git still thinks there is a change removing the file and then a change adding the file and this is between the index and the working directory !

git status says

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  modified:   myfile.h

But using git reset HEAD myfile.h changes nothing, nor does git checkout myfile.h. Removing the file physically and creating it again does not fix the problem either.

git reset --hard gets rid of the problem, but is not an option in many cases when this is happening to me like in the middle of a rebase.

In this situation I can also do the following :

$ git rm --cached myfile.h
rm 'myfile.h'
$ git status
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    myfile.h

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        myfile.h

$ git add myfile.h
$ git status
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   myfile.h

$ git diff
$

I'd like to figure out why git thinks this file is removed and added, but I'm not sure any more in what direction to investigate. How can I ask git more info about what it thinks of my index so I can figure out why it wants so much to remove/add this unchanged file ?

UPDATE : I still haven't found the reason but I have more information to share. I've tried to compare the git tree objects referencing the case where git reports a difference and the case where it doesn't. It turns out that git ls-tree on the parent directory of the problematic file look different on one account: the order of the files.

100644 blob e79f590c93e9a971c9c443558f35067898d2587f myeee.h
100644 blob 8d1b41aeb85f3c2afc6e70e824902f3f365e416c myfile.h
040000 tree a9091c79f0d317f1d0ea596e538b50afde4b6251 myfile
100644 blob 47925e1b444f396a038052dc583310dc3a6b6021 myfile_again.h

versus

100644 blob e79f590c93e9a971c9c443558f35067898d2587f myeee.h
040000 tree a9091c79f0d317f1d0ea596e538b50afde4b6251 myfile
100644 blob 8d1b41aeb85f3c2afc6e70e824902f3f365e416c myfile.h
100644 blob 47925e1b444f396a038052dc583310dc3a6b6021 myfile_again.h

This seems to be the source of the difference git is seeing... but I still don't know why it sees something different.

Jean
  • 10,545
  • 2
  • 31
  • 31
  • 1
    Are you on windows or linux or anything strange like that? Are you file synching across platforms? The places I would look into is whitespace and file permission bits being set. Also, are you using some IDE? – PressingOnAlways May 18 '15 at 04:11
  • I answered a similiar question [here](http://stackoverflow.com/questions/22790758/on-git-line-endings-again/30110522#30110522) and [here](http://stackoverflow.com/questions/25871938/unstaged-changes-immediately-after-cloning-in-eclipse/30118841#30118841). I hope this is gonna help you. – ckruczek May 18 '15 at 04:18
  • This apparently has nothing to do with line endings. The checksums of the file is the same - that would not be the case if the files had different line endings. Also, git diff --word-diff-regex=. shows no differences, but it does when line endings are different. I am working on mac OS (oh, not by choice believe me - this is an iOS app), and the repo is managed on linux, and there seem to be a link - only devs in my team working on macs see this problem. But there is no whitespace differences, no line ending differences, and no file permissions differences apparently : I checked these already. – Jean May 18 '15 at 04:33
  • @Jean: Wow ok thats really strange though. So is it maybe a file that got renamed or any automatically build file which is removed and added after each build? – ckruczek May 18 '15 at 05:51
  • There's a nice doc on git plumbing, but I'm not sure it'll help here. http://ftp.newartisans.com/pub/git.from.bottom.up.pdf – Nick Volynkin May 18 '15 at 08:44
  • I could reproduce just the same `diff-index` output by renaming a file, or by removing and adding a new one with the same content and a different name. Is it possible that the `myfile.h` gets somewhat renamed or moved? – Nick Volynkin May 18 '15 at 08:48
  • Thanks for the doc Nick, it helps with basic concepts. As for reproducing with different file names, that's expected - the only case where it should not happen is when the file name is the same. – Jean May 18 '15 at 09:30
  • Added new info in an UPDATE section of the post. It seems the trees seen by git when git status reports a difference vs when it doesn't are different in file order. I still don't know what to make of it... – Jean May 18 '15 at 09:31

0 Answers0