42
votes

I'd like to access git variables such as GIT_COMMIT and GIT_BRANCH when I have checked out a repository from git further down in the build stream. Currently I find no available variable to access these two parameters.

node {
    git git+ssh://git.com/myproject.git
    echo "$GIT_COMMIT - $BRANCH_NAME"
}

Is such variables available and in case, where would I find them. I don't mind if they are available through some groovy variables or wherever, just that I can access them.

Maybe I lack the debugging skills in Groovy and this is easy to find, but I just can't find it with my limited skills.

8
I have tried casting git to a variable, but it seems to return null. def gitInfo = git git+ssh://git.com/myproject.gitOldek
I'm trying to do the same thing currently. Would be pretty helpful to figure this one out.Ryan Currah
I have the exact same problem in my script where I'd like to use GIT_URL and GIT_BRANCH env variables (that should be populated in GitSCM if I'm not mistaken). In my case I use a "Pipeline script from SCM" and would like to get those variables in my Git-commited Groovy script. Moreover the mentionned hack does not work in my case because the head is detached from master (or any branch) once the SCM polling has happened... any solution ?Pom12
Is there a reason that these aren't available?mkobit

8 Answers

42
votes

Depending on the SCM plugin you are using, the checkout step may return additional information about the revision. This was resolved in JENKINS-26100. It was released in the 2.6 version of the workflow-scm-step plugin.

For example, using the Git plugin, you can do something like:

final scmVars = checkout(scm)
echo "scmVars: ${scmVars}"
echo "scmVars.GIT_COMMIT: ${scmVars.GIT_COMMIT}"
echo "scmVars.GIT_BRANCH: ${scmVars.GIT_BRANCH}"

This will vary depending on the plugin you use, so the original answer may work better for you.


Original Answer

With the 2.4 release of the Pipeline Nodes and Processes Plugin, you can simply do:

def gitCommit = sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
11
votes

Depending on the information you need, there is a very straightforward solution: get the "checkout scm" operation return: it provides GIT_BRANCH, GIT_COMMIT, GIT_PREVIOUS_COMMIT, GIT_PREVIOUS_SUCCESSFUL_COMMIT and GIT_URL.

node { 
    stage ("Checkout") {

        scmInfo = checkout scm

        /*...*/
        echo "scm : ${scmInfo}"
        echo "${scmInfo.GIT_COMMIT}"


    }
}

This will output:

...
[Pipeline] echo
    scm : [GIT_BRANCH:my-branch, GIT_COMMIT:0123456789abcdefabcdef0123456789abcdef01, GIT_PREVIOUS_COMMIT:aaaabbbcccdddeeeefffe0123456789012345678, GIT_PREVIOUS_SUCCESSFUL_COMMIT:aaaabbbcccdddeeeefffe0123456789012345678, GIT_URL:http://my.si.te/my-repository.git]
[Pipeline] echo
    0123456789abcdefabcdef0123456789abcdef01
...

More details here Jenkins Pipeline SCM Steps

10
votes

This is what I'm doing, based on the example provided in the Jenkins examples repo:

node {
    git url: 'https://git.com/myproject.git'

    sh 'git rev-parse --abbrev-ref HEAD > GIT_BRANCH'
    git_branch = readFile('GIT_BRANCH').trim()
    echo git_branch

    sh 'git rev-parse HEAD > GIT_COMMIT'
    git_commit = readFile('GIT_COMMIT').trim()
    echo git_commit
}

Edit you can do this shorter via

git_commit = sh(returnStdout: true, script: "git rev-parse HEAD").trim()
1
votes

This example might get you further: https://github.com/jenkinsci/pipeline-examples/tree/master/pipeline-examples/gitcommit

In this example they are piping the output of git commands to a file, and then reading the file.

1
votes

You can define your jobs (extracting git info from last commit) inside node for execution in a queue.

node {

  //Code checkout from SCM (here - `git`)
  checkout scm

  stage("GIT INFO"){
    echo ":::::::::::GIT_SHORT_COMMIT::::::::::::::::::::::::"

    GIT_SHORT_COMMIT = sh(returnStdout: true, script: "git log -n 1 --pretty=format:'%h'").trim()
    //echo in jenkins console
    echo GIT_SHORT_COMMIT
    //wanted to send these info to build artifacts, append to any file
    sh("echo ${GIT_SHORT_COMMIT} > GIT_SHORT_COMMIT")

    //Similar proceed for other git info's 
    echo ":::::::::::GIT_COMMITTER_EMAIL::::::::::::::::::::::::"

    GIT_COMMITTER_EMAIL = sh(returnStdout: true, script: "git show -s --pretty=%ae").trim()
    sh("echo ${GIT_COMMITTER_EMAIL} > GIT_COMMITTER_EMAIL-${GIT_COMMITTER_EMAIL}")



    echo ":::::::::::GIT_COMMITTER_NAME::::::::::::::::::::::::"

    GIT_COMMITTER_NAME = sh(returnStdout: true, script: "git show -s --pretty=%an").trim()
    sh("echo ${GIT_COMMITTER_NAME} > GIT_COMMITTER_NAME-${GIT_COMMITTER_NAME}")
  }

After your job is finished, you will see three additional file from above task in your workspace :

. |-- [email protected] |-- GIT_COMMITTER_NAME-username |-- GIT_SHORT_COMMIT_<commit-short-ID-ef9e91c>

0
votes

I good way to fix this for now is to use the Multi-branch pipeline, and it might be good to know that Bitbucket and Github have plugins in Jenkins that sets up an organisation and autodiscovers new projects. This works natively then with env.GIT_BRANCH

For commit ID I would suggest what @mkobit wrote above.

0
votes

The simplest way to fetch the Git variable in Jenkins through Jenkinsfile

node {
  def scmVars = checkout scm
  echo 'scm : the commit id is ' +scmVars.GIT_COMMIT
  echo 'scm : the commit branch  is ' +scmVars.GIT_BRANCH
  echo 'scm : the previous commit id is ' +scmVars.GIT_PREVIOUS_COMMIT
  def commitEmail = sh(returnStdout: true, script: "git --no-pager show -sformat=\'%ae\'")
  echo " the commiter email is'${commitEmail}'"
  def commitName = sh(returnStdout: true, script: "git --no-pager show -s format=\'%an\'")
  echo " the commiter name is'${commitName}'"
}

In console you will get the

GIT_COMMIT:
GIT_BRANCH:
GIT_PREVIOUS_COMMIT:
commitEmail:
commitName:
0
votes

Additional information: If you are using agent, like docker in pipeline, the agent SHOULD have git installed inside of container. Without git it won't add variables like "GIT_COMMIT, GIT_BRANCH, GIT_COMMITTER_EMAIL ... etc"

In case there is no installed git inside the container, you can use a Jenkins git plugin to make a checkout and interact with git variables, like this:

stage ('Clone') {
  steps {
    script {
      def scmVars = checkout BbS(branches: [[name: '*/develop']], credentialsId: 'bitbucket-jenkins', extensions: [], gitTool: 'default-git', id: '436fd534-c616-4a81-94d9-f67f32c03c1c', projectName: 'intuence-discovery-analysis-configuration', repositoryName: 'api-gateway-elasticsearch-proxy', serverId: 'b4943a46-b885-4aa3-90be-033e40460794')
      echo "scmVars.GIT_COMMIT"
      echo "${scmVars.GIT_COMMIT}"
      env.GIT_COMMIT = scmVars.GIT_COMMIT
      sh "printenv"
    }
  }
}