6

We have one Jenkins job which builds every branch except master when there are new commits. This behavior can be configured via git plugin's 'choosing strategy:inverse' so that it listens to every branch except a specified branch.

This functions very nicely. But the problem is that GIT_BRANCH environment variable always refers to the excluded branch('origin/master' in our case). How to query the actual branch that was built by Jenkins?

Currently I am using a workaround that I grep it from generated changelog.xml. But it happens sometimes that changelog.xml is empty when Jenkins switches between different branches and I cannot find this info. What is the correct way of retrieving/querying from Jenkins the branch that was actually built?

harish
  • 1,836
  • 3
  • 21
  • 26

4 Answers4

18

I successfully used this syntax:

GIT_BRANCH=`git rev-parse HEAD | git branch -a --contains | grep remotes | sed s/.*remotes.origin.//`
Piotr Kuczynski
  • 699
  • 7
  • 9
  • 1
    Great! For anyone else, I had to slightly adjust this to: `git rev-parse HEAD | git branch -a --contains | grep remotes | sed -e 's/.*remotes.origin.//'` for OS X – Jonathan Crooke Jan 22 '14 at 14:41
  • With master checked out in a repo I'm currently working with, this results in `HEAD -> origin/master\nmaster` (the `\n` is really a newline in the result), which is clearly wrong. – Matt Kantor Apr 09 '14 at 18:18
  • 4
    Note that --contains will also include branches that are newer than the currently checked out code. This worked better for me: `git show-ref | grep $(git rev-parse HEAD) | grep remotes | grep -v HEAD | sed -e 's/.*remotes.origin.//'` And possibly pipe this to `head -n1` if you want it to arbitrarily pick the first branch name if there are multiple branches pointing to this commit. – Alex Varju Aug 26 '14 at 00:25
  • Where can I use this in Jenkins? I can't seem to use it as an ant property.. where did you configure this to use it? – Rein Baarsma Feb 15 '17 at 07:11
2

Looks like it's a Jenkins bug? You can grab in your build script the name of the checked out branch with this:

git symbolic-ref -q --short HEAD

Actually Jenkins has the working copy in detached HEAD, which is why git branch returns "no branch". See this quite detailed answer for digging into reconciliation with between a detached HEAD and a branch.

Community
  • 1
  • 1
CharlesB
  • 86,532
  • 28
  • 194
  • 218
  • 1
    Thanks Charles. That works in a normal git workarea but not in a jenkins workspace where command returns nothing. Running 'git branch' in jenkins workspace gives '*(no branch)'. Probably the chosen branch must be queried from Jenkins in some way as it seems to make the checkout based on commit-id in the chosen branch. – harish Feb 22 '13 at 08:10
  • Yes, Jenkins works in detached HEAD. see my edit and the linked answer. I'm sure one of the commands linked in it should work. – CharlesB Feb 22 '13 at 08:55
  • This command works in CMD, but not in my Jenkins, why? C:\Tools\Jenkins\jobs\DevOps\jobs\Test-GitHub\workspace>git --version git version 2.7.0.windows.1 C:\Tools\Jenkins\jobs\DevOps\jobs\Test-GitHub\workspace>git symbolic-ref -q --short HEAD C:\Tools\Jenkins\jobs\DevOps\jobs\Test-GitHub\workspace>exit 1 Build step 'Execute Windows batch command' marked build as failure Finished: FAILURE – Jirong Hu Mar 03 '16 at 16:16
2

Because git never checks out a branch just a commit directly you have to do the following:

To get the sha of the checked out commit:

git rev-parse HEAD

To get the all branches that commit is under:

git branch -a --contains SHA

The out put of the second command could look like this

master
remotes/origin/HEAD -> origin/master
remotes/origin/develop
Daniel Little
  • 16,975
  • 12
  • 69
  • 93
0

I can't believe how hard this is. I'm doing this for Jenkins as well. I piggypacked off Piotr Kuczynski's solution:

branch=`git rev-parse HEAD | git branch -a --contains | grep remotes | sed s/.*remotes.origin.//`
branch=`echo $branch | awk '{print $NF}'`

Because sometimes, as Matt Kantor pointed out, Piotr's solution gives a lot of junk back. But the last word in that junk appears to always be correct. Note that this solution only works if the ref you're using corresponds exactly with a branch that exists on remote (so local branches will not work).

Eli
  • 4,874
  • 6
  • 41
  • 50