Git init: fatal: could not set 'core.filemode' to 'false'

I hate to be that guy, but I solved this by restarting Windows.


Traderhunt Games traced this to some antivirus software, which makes sense. The reason has to do with the process Git uses to update a configuration entry.

When git config runs and is told to change one or more configuration key = value field(s), such as changing core.filemode to false, the way it implements this is to use a three-step process:

  1. Create a new, empty file (.git/config.lock), using the OS service call that creates a file, or fails if the file already exists. If this step fails, that indicates that another git config (or equivalent) command is already running and we must wait for it to finish before we do our own git config.

  2. Read the existing configuration file, one key = value entry at a time. If the key is the one that we care about, write the new key = value value, otherwise copy the existing key = value.

    There's some fanciness here with keys that are allowed to repeat, vs keys that should only occur once; see the --replace-all and --unset-all options to git config for details. Note that git config itself knows little to nothing about most key and value pairs, and you can invent your own key/value pairs as long as you pick keys that Git is not using today and won't be using in the future. (How you figure out what Git will and won't use in, say, the year 2043, I have no idea. :-) ) The main exceptions are some of the core.* values, which git config does understand, and several other Git commands may set on their own.

    (Note that --unset is handled much the same as replacing. Like a non-all replace, it only unsets the first matching key = value pair. Unsetting is implemented by simply not writing the given key, instead of writing a replacement key = value. Since git config is simply working through the file line-by-line, that's easy to do. Also, if your key = value is totally new, Git handles this by reading through all the lines, noticing that it did not replace any existing key, and hence adding a new key = value line. This is complicated a bit by the fact that the keys are listed section-by-section, but the logic itself is simple enough.)

  3. Finally, having read through the entire existing configuration and completely written out the new one (using fflush and fsync and fclose and so on as needed), git config invokes the OS service to rename a file, in order to rename .git/config.lock to .git/config. This is where the process is failing in this particular case.

The rename, if it succeeds, has the effect of putting the new configuration into effect and removing the lock file, all as one atomic operation: any other Git command sees either the complete old configuration, from the original .git/config file, or the complete new configuration, from the new .git/config file that was known during construction as .git/config.lock.

Another StackOverflow question asks: Will we ever be able to delete an open file in Windows? The accepted answer includes this statement: An anti virus product that does not open files with full sharing (including deletion) enabled is buggy. If that's the case—that is, if this particular AV software fails to open with the "allow delete" flag, and if such software is buggy, then this particular AV software is the problem and is buggy.


In my case using "sudo" worked for me. For example:

asif@asif-vm:/mnt/prog/protobuf_tut$ git clone https://github.com/protocolbuffers/protobuf.git
Cloning into 'protobuf'...
error: chmod on /mnt/prog/protobuf_tut/protobuf/.git/config.lock failed: Operation not permitted
fatal: could not set 'core.filemode' to 'false'

After doing a "sudo" I could get it working:

asif@asif-vm:/mnt/prog/protobuf_tut$ sudo git clone https://github.com/protocolbuffers/protobuf.git
Cloning into 'protobuf'...
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 66782 (delta 0), reused 0 (delta 0), pack-reused 66777
Receiving objects: 100% (66782/66782), 55.83 MiB | 2.04 MiB/s, done.
Resolving deltas: 100% (45472/45472), done.
Checking out files: 100% (2221/2221), done.