Why is 'Updating the Git index failed' dis

2019-03-08 13:07发布

问题:

I am using Windows. When staging files I get this error.

Updating the Git index failed. A rescan will be automatically started to resynchronize git-gui.

followed by a list of files which have been converted from LF to CRLF

After a lot of reading up on the CRLF / LF issue with Git usage cross platform, I more or less understand what is going on, and I am trying to determine which autocrlf setting is best for me, but I cant understand why Git says that Updating the index failed. My understanding is that it has converted the EOF's so what is the problem with that and why is it telling me that updating the index has failed. Do I need to fix something ( other than picking an appropriate autocrlf setting) or can I just proceed

I then have two options Continue and Unlock Index, what do these mean and what is the best course of action.

回答1:

git config --global core.autocrlf false

Has always been my recommendation (see "Git 1.6.4 beta on Windows (msysgit) - Unix or DOS line termination").

However, in your case, you can "Continue", but this warning is there to mention the conversion of certain files might not be reversible:

core.safecrlf

If true, makes git check if converting CRLF is reversible when end-of-line conversion is active. Git will verify if a command modifies a file in the work tree either directly or indirectly. For example, committing a file followed by checking out the same file should yield the original file in the work tree. If this is not the case for the current setting of core.autocrlf, git will reject the file.
The variable can be set to "warn", in which case git will only warn about an irreversible conversion but continue the operation.

If you don't want to see this warning, as explained in this thread, you can set core.safecrlf to false.

You could also stash your files through the tools menu of git gui, and add some options to those tools with, for instance, this git config file.
The interest is that, for each tool, you can add:

guitool.<name>.norescan

Don’t rescan the working directory for changes after the tool finishes execution.


Could you please elaborate a bit on Unlock Index

you can see that message in the index.tcl git-gui script: it removes the index.lock file the git-gui creates when manipulating the index.
You can see more at the "lockfile API" documentation page:

Mutual exclusion.
When we write out a new index file, first we create a new file $GIT_DIR/index.lock, write the new contents into it, and rename it to the final destination $GIT_DIR/index.
We try to create the $GIT_DIR/index.lock file with O_EXCL so that we can notice and fail when somebody else is already trying to update the index file.



回答2:

I also ran into this even tho my core.autocrlf setting is already false and core.safecrlf is unset. I suspect the culprit is the config setting diff.astextplain.textconv.

When I ran git config --list, the following line was shown in the output:

diff.astextplain.textconv=astextplain

I don't think this setting is actually related to the warning/error but it inspired me to look into text conversion that might be being done. After a little spelunking online and in my repo, I discovered the following line in my repo's .gitattributes file:

* text=auto

[I probably got the .gitattributes file from GitHub.]

Given that only the above line was un-commented in it, and further that dealing with 'automagic' line-ending conversions has always been a headache, I opted to remove that file from my repo. After doing so, staging the same files no longer prompted me with the "Updating the Git index failed" warning/error.



回答3:

TL;DR: This warning means that git might return you a text file in Windows-style despite you having checked in a text file in UNIX-style.

UNIX and Windows differ in how they save line breaks in text files. Wikipedia has a list of line breaks on different OSes

The warning you get is reproducible if you do the following on Windows:

  • Create a git repository in an empty directory
  • Create a commit representing the initial, empty state of the repo:

    git commit --allow-empty -m "initial commit"
    
  • use git config core.autocrlf and git config core.safecrlf to verify that autocrlf is set to true and safecrlf is unset (no output). If this is not the case, use the following commands to set them

    git config core.autocrlf true
    git config --unset core.safecrlf
    
  • Use Notepad++ to write a text file called text.txt in UNIX format. Write a file which has at least one line break. This is how you select UNIX line endings:

  • git add text.txt. You get the warning message

    warning: LF will be replaced by CRLF in text.txt.
    The file will have its original line endings in your working directory.

  • Commit the text file: `git commit -m "add file with UNIX endings"

  • Now see how the file looks like if you check it out from the tree. First, check out the version before you created the file (go 1 commit back). The file text.txt vanishes from the working directory:

    git checkout ~1
    
  • Now, restore the version after you created the file

    git checkout master
    

The file text.txt is restored. But open it in Notepad++ and check the line ending format in the bottom status line of Notepad++:

The file you checked out has Windows-style line endings, yet the file you commited had UNIX-style file endings! This is what the warning message is about: The settings core.autocrlf=true together with core.safecrlf=<unset> mean that the files you get restored from the tree might be different from the files you checked in, because they might have different file endings.