29

Using Team City to check out from a Git Repo. (Gitlabs if it matters)

Start with Empty build directory. Get this error:

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

(Running on a Windows machine, if that matters)

The user that Team City is running on was changed to an Admin just in case.

The .Git directory is not a valid Repo when this command exits.

Wiping the entire 'work' directory doesn't help.

It randomly comes and goes...

AND this: git config --global --replace-all core.fileMode false

Does nothing useful - with or without the --replace-all, and run as admin, or another user (if you change 'false' to 'true' you get the same error, if you change it to 'falseCD' it changes the error to that being an invalid value - so clearly, it is changing it.

Anyone got any ideas?

Traderhut Games
  • 1,222
  • 1
  • 15
  • 30
  • 4
    It's clear enough that Git is *trying* to change the configuratino setting, but failing. What's not clear is *why*. Git updates `.git/config` by creating `.git/config.lock`, writing the new configuration there, and then renaming the completed `.git/config.lock` to `.git/config`. If one of those steps fails (can't create .lock, can't write .lock file, can't rename .lock file into place) you get the above error. Figure out which of these three is the case and why. – torek Apr 30 '18 at 21:46
  • It just created the directory (no .git before), so if there is a config.lock file then THIS process just created it as part of the 'git init' command. It has created a lot of other files in the directory, including the 'config' file, it has full Administrator access to the machine for the process that is running git. Which, I believe, has ruled out all 3 of those... – Traderhut Games May 02 '18 at 20:03
  • So, one way to fix this would be to tell git to not update the config file once it has written it in the first place. I've seen the error both trying to set the value to false, and on another project to 'true' . I tried using --system instead of --global and it didn't help. (not even sure) - Oh, no config.lock file. If it couldn't rename the file, it should issue an error saying so (doubt it does), if it can't create it, it should issue an error saying so (doubt it does). I'm rather expecting that it is unrelated to anything that seems obvious :-( – Traderhut Games May 02 '18 at 20:07
  • 1
    I don't "do" Windows but it's my understanding that Windows has mandatory file locking, where if some process has a file open while another process tries to manipulate that file, the second process's attempts just fail. Perhaps some lingering background process (part of TeamCity?) is holding something open that prevents Git from getting anything done here, despite admin privileges. – torek May 02 '18 at 20:34
  • Another clue- it seems related to not being able to update the file 'config' for some reason (it just created it), because removed the core.filemode from the --system level and now it is failing on:fatal: could not set 'core.bare' to 'false' – Traderhut Games May 02 '18 at 21:10
  • Two things that 'fixed' it: 1. Changing it to pull the sources down on the build server (same actual machine as build agents) allowed it to pull the sources - failed on the generation of the build # step. #2, changing it to not start with a clean directory each time. (NOT sure if this really fixed it, but it went away again..) – Traderhut Games May 02 '18 at 21:18
  • After thinking through this, it is fairly clear it must be failing when it trys to delete the 'config' file and rename it. As it was able to create/write 'config' and other files, and it is running as admin so pretty much the only failure that is possible is the file is open.... I'm now 99% sure that the problem is a back-ground virus scanner opens the file and has it open during this time period (but sometimes not -thus the random factor..) . UNIX would just let you blow the file away. – Traderhut Games May 02 '18 at 21:29
  • That scenario seems to fit all the facts. So it wasn't Colonel Mustard in the C Library with the pipe() call, but rather Mr Green, with the virus-rope (lariat?) in the file-study. – torek May 02 '18 at 21:33
  • I have confirmed that it was the AV software - Thanks to Torek for the critical clue that made it possible for me to see that answer - the renaming of the file. I had two people try to convince me not to bother anyone to try the AV software change - as there was 'no way' it could be the issue. But if a process created the file, and it is running as admin, and it gets a 'permission denied' then *someone* has the file open, if not A/V then who? If you want to write up your comment as an answer, I'll mark it as the correct answer.. – Traderhut Games May 08 '18 at 20:20

6 Answers6

47

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.
linuxstack
  • 757
  • 8
  • 19
  • 5
    Then it looks like a permission problem. How could we solve it with proper `chmod`ing? – Matthieu Jul 06 '20 at 14:31
  • 9
    Worked for me, too, I think. In my case I was cloning inside WSL in Windows 10 to a symbolic link to a Windows directory ("/mnt/c/mydir/..."). – Ron Burk Nov 04 '20 at 03:24
  • 1
    I was thinking: "man, i don't need to read all those answers...". Then I found this beautiful asnwer. Thanks a lot! – Daniel Azamar Jan 28 '21 at 04:13
45

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

Blairg23
  • 11,334
  • 6
  • 72
  • 72
  • 10
    I also solved it by restarting windows – Vince W. Dec 30 '21 at 02:17
  • 9
    thanks for the laughter lol. you solved the problem too btw – birajad Jan 08 '22 at 17:53
  • 3
    If you're using WSL2 and cloning under home directory, this is the correct answer. The home directory of a wsl was pointed to windows user directory when it was the first place. Your home directory would become normal when host is restarted. – Louis Go Jul 26 '22 at 08:32
  • 1
    yup, switch off then on, thanks @Louis Go for a possible cause, however I had been trying to use Phpstorm to download files, but git seems faster – Datadimension Nov 08 '22 at 17:53
  • 4
    This sounds dumb, but is essentially correct due to what @LouisGo said - what you need to restart, though, is just WSL/WSL2, which a Windows restart will cover, but is overkill. It's enough to do `wsl --shutdown` from an elevated shell, then start it (WSL) again. – Torque Nov 20 '22 at 14:58
  • 1
    Unfortunately this is the most practical solution if you have just installed a new WSL distro. – Hanxue Jun 26 '23 at 17:51
4

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.

torek
  • 448,244
  • 59
  • 642
  • 775
2

I was getting this error when running git init on a windows shared drive mount into linux via samba. I used sudo for init, then chown back to original user, and all was good from there on:

sudo git init # no error
sudo chown user:user .git -R # drop sudo requirement
git add file1 # works normally
git commit -am bla # works normally
Shadi
  • 9,742
  • 4
  • 43
  • 65
0

For me it was a matter of commenting out two lines in /etc/nsswitch.conf

the lines I commented out were:

group: files # db
db_enum: cache builtin

then closing and reopening cygwin

Shōgun8
  • 482
  • 10
  • 20
0

This error appeared in Windows WSL, when I tried to first create a newuser and then git init . from the folder under windows tree. newuser was able to create git repository in its linux home.

Restarting Windows did not work for me to get rid of this in WSL. In my use case, I needed to issue wsl --shutdown from the windows command line. Before doing so, I have created /etc/wsl.conf in WSL linux with the following content, inspired by https://stackoverflow.com/a/50856772:

[automount]
options = "metadata"

and added newuser to the sudo group

usermod -aG sudo newuser

When the folder is not owned by newuser, to be able not only to git init . but also to actually work with given git repository, then newuser have to run

git config --global --add safe.directory /mnt/c/...repositorypath
VojtaK
  • 483
  • 4
  • 13