Git checkout of a branch destroys local reference to master

When building a branch (let’s say branch1), the Checkout code step will do this after cloning the git repository:

git reset --hard "$CIRCLE_SHA1"
git checkout -q -B "$CIRCLE_BRANCH"
git reset --hard "$CIRCLE_SHA1"

This will make the local reference of master point to the HEAD of branch1 before checking out branch1.
The first command should probably be simply git reset --hard or a git clean -fd (just to ensure that the checkout following it will succeed).

I’ve confirmed the problem with the following build. When building a branch, master is pointing to that same branch:

It creates problems when running SonarCloud analysis, as the scanner will be tricked into thinking that there are no changes in the current branch compared to master:


relates to The checkout step mangles branches, messes the history and Checkout script adds commits to master from $CIRCLE_BRANCH

I am experimenting with using a manual near-identical version of the circle-ci “checkout” step, removing the line that results in the master branch being reset --hard onto the $CIRCLE_SHA1

Another problem with SonarCloud was reported that is linked to this bug:

Yet another issue with git branch mess ?

Anyone have success resolving this?

@timols: the checkout step is optional, so if you wish you can replace it with your own Git calls completely.

It would see them the following will remedy the situation:

git branch -f master origin/master

Exist any workaround to fix this issue?
Is terrible to pay a tool easy like circle-ci and switch to other tools only for this issue.

Thank you

Yes, here:

Sorry I try to explain better my question… " someone have a checkout script that maybe resolve this problem?"

They might do, but it is probably a few lines of Git calls in Bash, so… :slightly_smiling_face:

But I don’t get it… the checkout step provided by circleci is quite… extensive. I don’t want to replace it. When you @halfer say:

(…) replace it with your own Git calls completely

do you mean actually copy paste circle’s checkout step into our own pipeline and then add that extra line:
git branch -f master origin/master ?

It is, and I’ve pretty much no idea what it is doing! If I had a need to do a custom checkout, then writing my own Git calls - and understanding what they do - would be my approach.

Got hit by this issue.

This helps.

Leaving a request for the support.

Hi from CircleCI.

Apologies for this issue lingering for so long. Our team recently got enough bandwidth that I had time to look into our checkout step implementations (there is actually more than one).

Also, as it was developed in the earlier more fast moving days of the company, the test coverage of this part of our build-agent was not as good as it could be. Changing the behaviour of something as mission-critical to the platform as this, with millions of different combinations of Docker image / Git version / etc running through the system is highly challenging and risky.

Anyway, long story short, I spent a few days cranking out many test scenarios to cover the various features the checkout step actually contains, and felt in a good place after this to start trying to fix issues like this. After a staged rollout and a few more regression tests for “unexpected” features. This culminated in a fairly substantial change to the script.

I believe we have covered this scenario now, as well as several others, and I hope this long-standing issue is resolved for you all.