For one of our clients, we noticed their builds started failing at the checkout step. Looking at the logs the error was
error: cannot lock ref 'refs/remotes/origin/<branch>': there is a non-empty directory '.git/refs/remotes/origin/<branch>' blocking reference 'refs/remotes/origin/<branch>'
In this post we will see what was the root cause and how to fix it.
From the logs it was pretty evident that it is to do with the branches. Looking at the branches it became clear that there are few branches which just differ in the letter case. For example, take a look at
Users/Sai/local branches - notice letter
u has different case in those branch names.
The build was happening on a Windows on-premises agent. This meant, the agent machine file-system is case-insensitive. However, Git built originally for Linux and is case-sensitive. This means that on Linux machines a repo which contain
Readme.md are both valid and hence co-exist. On Windows and macOS you will not be allowed to create files with such file names.
So, the issue was that, while Git (and Azure DevOps) allowed branch names to be created that only differ in case (treating them as separate refs). However, when agent tried to clone (Git uses file-system to store refs) the branches on a Windows machines, they conflict and hence the failure.
Solution is to clean (remove or rename) the branches which just differ in case. Fortunately, Azure DevOps makes it super easy to do this by just using the portal.
Head over to the
Repos hub and
Branches page. Navigate to the branch you want to rename and open the context menu on the latest commit of that branch and click
In the dialog that opens, enter the name for the new branch. Make sure you correct the casing. Here I am creating the new branch from
users/Sai/local, so that a new branch with the same commit is available at the new location.
Once done, go ahead and delete the branch causing conflict. In our case it was
Do the same for other branches if you have any.
Once you clean all the conflicting branches, retrigger the build and it should succeed now.
Okay, you solved the problem, but how will you ensure that it does not happen again? Well, Azure DevOps has the setting to the rescue.
Go to your
Project settings  and
Repositories page . Select the repository  and then
Options . Finally enable the option which says
Block pushes from introducing names that differ only in case to avoid case-sensitivity conflicts. Applies to files, folders, branches, and tags.
Optionally, you can also enable this option for all the Git repositories you create. To do that, you will have to select root
Git Repositories node and do the same.