Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detached head in gitlab ci pipeline - how to push correctly

Tags:

git

gitlab-ci

I got some problems with a detached head for my repository in a CI pipeline. In the build stage of the pipeline I am running a script, which changes a specific file. After changing this file get pushed to the repository.

before_script:
  - git config --global user.name "Bot"
  - git config --global user.email "[email protected]"
  - git status
script:
  - npx ts-node ./generate.ts
  - git push "https://git:${GIT_PUSH_TOKEN}@${CI_REPOSITORY_URL#*@}" "HEAD:main"
  - git status

Running the script give me the output

Fetching changes with git depth set to 50...
Initialized empty Git repository in /builds/fKSu5-y_/0/project/.git/
Created fresh repository.
Checking out 9b4a88be as main...

$ git status
HEAD detached at 9b4a88be

$ git push "https://git:${GIT_PUSH_TOKEN}@${CI_REPOSITORY_URL#*@}" "HEAD:main"
To https://gitlab.domain.com/project.git
9b4a88b..98be83e  HEAD -> main

$ git status
HEAD detached from 9b4a88b

I do not understand why the first git status in the before_script already gives me a detached head.

I think the pipeline creates a detached repository by initial fetching. So the question is how to handle my push in a correct way. In my release stage I'm running semantic-release which fails because of detached head if I do the previous push. If I disable the push, semantic release is working as expected. But of course I need the push. I do not see, what I am doing wrong.


Update

Adding git checkout main in the before_script give me for the first git status the expected result. But after the push command I still have the detached head - which I do not understand.

$ git checkout main
Branch 'main' set up to track remote branch 'main' from 'origin'.
Switched to a new branch 'main'

$ git status
On branch main
Your branch is up to date with 'origin/main'.

$ git push "https://git:${GIT_PUSH_TOKEN}@${CI_REPOSITORY_URL#*@}" "HEAD:main"
To https://gitlab.domain.com/project.git
  336b065..8299e43  HEAD -> main

$ git status
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

Although everything the push is working on the release state semantic-release is still not working. I do get: The local branch main is behind the remote one, therefore a new version won't be published.

like image 600
user3142695 Avatar asked Nov 17 '25 03:11

user3142695


2 Answers

I do not understand why the first git status in the before_script already gives me a detached head.

I think the pipeline creates a detached repository by initial fetching.

You are right, GitLab CI does checkout a specific commit as opposed to a certain branch. You could however add git checkout "$CI_COMMIT_REF_NAME" to your before_script:

before_script:
  - git config --global user.name "Bot"
  - git config --global user.email "[email protected]"
  - git checkout "$CI_COMMIT_REF_NAME"
  - git status
like image 120
slauth Avatar answered Nov 18 '25 19:11

slauth


I spend a lot of time to try to resolve the same problem and finally I found that there are git strategy: https://docs.gitlab.com/ee/ci/runners/configure_runners.html#git-strategy

When there is set fetch then it re-uses the local working copy (and falls back to clone if it doesn’t exist). So this is the reason why it worked me for the first time and then it stopped working and my checkouted branch was behind and number of commits ahead increased with another commit.

Then the solution is pretty easy. You just need to define the GIT_STRATEGY variable to clone.

variables:
  GIT_STRATEGY: clone

And my working publish job example:

publish:
  stage: publish
  rules:
    - if: $CI_COMMIT_BRANCH == "master"
      when: manual
  variables:
    GIT_STRATEGY: clone
  script:
    - git checkout -b $CI_COMMIT_BRANCH
    - echo "define what you want to change"
    - 'git commit -am "your commit message" || echo "No changes to commit"'
    - git push --set-upstream origin $CI_COMMIT_BRANCH

You can also define clone strategy in global variables or pipeline configuration https://docs.gitlab.com/ee/ci/pipelines/settings.html#choose-the-default-git-strategy.

like image 35
Saljack Avatar answered Nov 18 '25 19:11

Saljack