Jenkinsfile: git rev-parse --abbrev-ref HEAD returns HEAD

Viewed 14949

I am new to jenkins/devops; I am following this example. When I locally do (from the terminal):

git rev-parse --abbrev-ref HEAD

I get the current branch's name. However from within Jenkinsfile, in the logs I am getting:

HEAD

Been researching online for a while and couldn't find the reason so far. What are potential causes for this outcome?

Additional Details

In my jenkinsfile, i am trying to get the current git branch's name (the one that triggered the webhook) and then pipe it inside 'git branch' command, so code is as follows:

pipeline {
agent {
    label 'ubuntu'
}
stages {
    stage('check') {
    steps {
            script {
               env.GIT_BRANCH_NAME=sh(returnStdout: true, script: "git rev-parse --abbrev-ref HEAD").trim()
            }

            sh 'echo BRANCH_NAME ${GIT_BRANCH_NAME}'
            git branch: GIT_BRANCH_NAME, credentialsId: '******', url: 'https://*****/*****/*****.git'
      }
....
}

In the line

sh 'echo BRANCH_NAME ${GIT_BRANCH_NAME}'

Returns HEAD

I found a way around this using git name-rev --name-only HEAD and modified the script code to:

script {
    env.GIT_BRANCH_PATH=sh(returnStdout: true, script: "git name-rev --name-only HEAD").trim()
    env.GIT_BRANCH_NAME=GIT_BRANCH_PATH.split('remotes/origin/')[1]
}

Now I get the right branch name and the steps work, but I would rather have a less hacky way of doing things.

What is the best method to achieve what I want to achieve using best practices?

PS I am not using multi-branching pipeline and the requirements were to not use multi-branching.

4 Answers

The solution that I've found for this situation is:

checkout([$class: 'GitSCM', branches: [[name: '*/' + branch]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'LocalBranch', localBranch: "**"]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'cred', url: 'git@bitbucket.org:repofolder/repo.git']]])

The key here is [$class: 'LocalBranch', localBranch: "**"]. It allows to checkout a branch not a revision.

The source for it is taken from here.

Problem:

As torek mentioned, if you've checked out a commit (vs a branch) you are in a "detached HEAD" state (HEAD detached at 123abc).

Why?

--abbrev-ref returns a non-ambiguous short name of the objects name. The current object is the commit you checked out, not a branch. Further, git wouldn't be able to determine which branch you wanted anyway because the commit you checked out could easily live in multiple branches.

Solution:

I would use Vijay Ramaswamy's suggestion, however, you could also hard-code the branch name in your script:

env.GIT_BRANCH_NAME='my-branch-name'

or more simply

git branch: 'my-branch-name', credentialsId: '******', url: 'https://*****/*****/*****.git'

If you are using the multibranch pipeline, branch name should be available in the environment variables as env. BRANCH_NAME. you can use sh 'printenv' inside your step to print all the available environment variables

Related