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:
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 anothergit config
(or equivalent) command is already running and we must wait for it to finish before we do our owngit config
.Read the existing configuration file, one
key = value
entry at a time. If the key is the one that we care about, write the newkey = value
value, otherwise copy the existingkey = 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 togit config
for details. Note thatgit 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 thecore.*
values, whichgit 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 matchingkey = value
pair. Unsetting is implemented by simply not writing the given key, instead of writing a replacementkey = value
. Sincegit config
is simply working through the file line-by-line, that's easy to do. Also, if yourkey = value
is totally new, Git handles this by reading through all the lines, noticing that it did not replace any existingkey
, and hence adding a newkey = 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.)Finally, having read through the entire existing configuration and completely written out the new one (using
fflush
andfsync
andfclose
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.