Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-33984

Git plugin sets wrong branch name GIT_BRANCH (more than 2 branches with same SHA1)

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major Major
    • git-plugin
    • None
    • Production

      Git plugin ver: 2.4.4

      In jenkins job we configure Git plugin ->
      Branches to build/Branch specifier: origin/ready/**

      Developer pushes code to central git repository, which Jenkins check into 2 branches:
      git push origin bugfix:sergey/bugfix
      git push origin bugfix:ready/bugfix

      When Jenkins job kicks in, it provides this output:

      14:01:36 > git branch -a -v --no-abbrev --contains 24ef859065480d5ac965652cfce8a0dd959fd082 # timeout=10
      14:01:36 Checking out Revision 24ef859065480d5ac965652cfce8a0dd959fd082 (origin/sergey/bugfix, origin/ready/bugfix)
      ..
      ..

      14:01:36 HOME=/var/lib/jenkins
      14:01:36 GIT_BRANCH=origin/sergey/bugfix
      14:01:36 EXECUTOR_NUMBER=1

      As you can see GIT_BRANCH got set to "origin/sergey/bugfix"
      and this is wrong because we asked for branch to match origin/ready/**

      This causes problems in our build process

          [JENKINS-33984] Git plugin sets wrong branch name GIT_BRANCH (more than 2 branches with same SHA1)

          Thanks Mark for the explanation. Could you please elaborate on the using custom refspecs? I eventually have to extend my Jenkins job for the following Branch specifiers:

          Branch specifier 1 - origin/develop
          Branch Specifier 2 - origin/release**

          (But would like to ignore these set of branches - origin/feature** and origin/bugfix**)

          Would that require specifying multiple refspecs? Would you have a screenshot to share?

          Pragya Jaiswal added a comment - Thanks Mark for the explanation. Could you please elaborate on the using custom refspecs? I eventually have to extend my Jenkins job for the following Branch specifiers: Branch specifier 1 - origin/develop Branch Specifier 2 - origin/release** (But would like to ignore these set of branches - origin/feature** and origin/bugfix**) Would that require specifying multiple refspecs? Would you have a screenshot to share?

          Mark Waite added a comment - - edited

          Yes, you would need to specify multiple refspecs behind the advanced button of the repository definition for the job. I assume your

          origin/release**

          branch specifier really means

          origin/release/**

          .
          I think your refspec should look like this:

          +refs/heads/develop:refs/remotes/origin/develop
          +refs/heads/release/*:refs/remotes/origin/release/*
          

          The git refspecs documentation gives a very good review of the strengths and weaknesses of refspec definition.

          Mark Waite added a comment - - edited Yes, you would need to specify multiple refspecs behind the advanced button of the repository definition for the job. I assume your origin/release** branch specifier really means origin/release/** . I think your refspec should look like this: +refs/heads/develop:refs/remotes/origin/develop +refs/heads/release/*:refs/remotes/origin/release/* The git refspecs documentation gives a very good review of the strengths and weaknesses of refspec definition.

          Pragya Jaiswal added a comment - - edited

          Thanks Mark. that does resolve my issue. However, how can I extend the functionality of my jenkins job -
          My jenkins job tracks multiple branches and triggers builds if there are changes to any of those branches. For example I have multiple branch specifiers added to my job -
          origin/release**
          origin/develop

          The job is working fine when there are merges to any of these branches.In some cases I want to be able to specify/input a branch to pull the source and build from. How can I accomplish that considering I have the branch specifiers already set? Any ideas on implementing this?

          I tried a couple of things -

          1. Added a build parameters called $BranchOverride and tried 2 test cases. case 1 - Setting the default value to "None" with 3 branch specifiers for release/* , develop and $BranchOverride. Case 2 - setting the default value to origin/develop and set 2 branch specifiers release/ * and $BranchOverride. Both the cases, when I manually input a branch, it doesn't work as I expect it to.

          2. Instead of specifying multiple Branch specifiers, I created a string Parameter $BranchOverride and set the value as a regex : (?=(origin/develop|origin/release)).*
          When I push to one of my release branch, it triggers a build (and multiple consecutive builds) for multiple branches, even those that dont have any push. I see this is the log -

          Seen 1,116 remote branches
          Multiple candidate revisions
          Scheduling another build to catch up with ABC_TestJob
          Checking out Revision 366bdc3674103e4b2479d75508f3971c6f080591 (origin/release/xyz)

          I must add that in the test case where I added a regex, manually giving the branch input works but the automated trigger doesnt behave as expected. Maybe I am not understanding the behavior correctly, am not sure.

          Pragya Jaiswal added a comment - - edited Thanks Mark. that does resolve my issue. However, how can I extend the functionality of my jenkins job - My jenkins job tracks multiple branches and triggers builds if there are changes to any of those branches. For example I have multiple branch specifiers added to my job - origin/release** origin/develop The job is working fine when there are merges to any of these branches.In some cases I want to be able to specify/input a branch to pull the source and build from. How can I accomplish that considering I have the branch specifiers already set? Any ideas on implementing this? I tried a couple of things - 1. Added a build parameters called $BranchOverride and tried 2 test cases. case 1 - Setting the default value to "None" with 3 branch specifiers for release/* , develop and $BranchOverride. Case 2 - setting the default value to origin/develop and set 2 branch specifiers release/ * and $BranchOverride. Both the cases, when I manually input a branch, it doesn't work as I expect it to. 2. Instead of specifying multiple Branch specifiers, I created a string Parameter $BranchOverride and set the value as a regex : (?=(origin/develop|origin/release)).* When I push to one of my release branch, it triggers a build (and multiple consecutive builds) for multiple branches, even those that dont have any push. I see this is the log - Seen 1,116 remote branches Multiple candidate revisions Scheduling another build to catch up with ABC_TestJob Checking out Revision 366bdc3674103e4b2479d75508f3971c6f080591 (origin/release/xyz) I must add that in the test case where I added a regex, manually giving the branch input works but the automated trigger doesnt behave as expected. Maybe I am not understanding the behavior correctly, am not sure.

          Matthew Smith added a comment - - edited

          +1 for this issue

          In my case, GIT_BRANCH is not even getting set to a branch name. It is getting set to the name of a tag in the repo.

          Matthew Smith added a comment - - edited +1 for this issue In my case, GIT_BRANCH is not even getting set to a branch name. It is getting set to the name of a tag in the repo.

          Dan Porter added a comment -

          This is still a problematic issue. It seems that $GIT_BRANCH is set to whatever the first identified branch is for that commit, rather than the triggering branch received by Jenkins.

          Example of feature/awful, as the only branch pointing at this id, working:

          Checking out Revision d0903cd1d7fab333f84fa8094af14552cc17355c (origin/feature/awful)
          GIT_BRANCH is 'origin/feature/awful'

          Example of master, of which develop is also pointing at this commit id, not working:

          Checking out Revision 62e085f7ab8163c305bef91e07314a5f09d2ed5a (origin/develop, origin/master)
          GIT_BRANCH is 'origin/develop'

          Dan Porter added a comment - This is still a problematic issue. It seems that $GIT_BRANCH is set to whatever the first identified branch is for that commit, rather than the triggering branch received by Jenkins. Example of feature/awful , as the only branch pointing at this id, working: Checking out Revision d0903cd1d7fab333f84fa8094af14552cc17355c (origin/feature/awful) GIT_BRANCH is 'origin/feature/awful' Example of master , of which develop is also pointing at this commit id, not working: Checking out Revision 62e085f7ab8163c305bef91e07314a5f09d2ed5a (origin/develop, origin/master) GIT_BRANCH is 'origin/develop'

          Jon Starbird added a comment -

          For us, the job will build the correct branch and if you look at the Environment Variables after the build the GIT_BRANCH variable is set to the correct value but if you use the GIT_BRANCH variable for Email for example the value is wrong.  Recorded Revision numbers are correct as well.

          Does anyone know of another, more reliable way, to get the Branch built? Hard to believe with how long Git has been around in Jenkins that this is still an issue.

          Jon Starbird added a comment - For us, the job will build the correct branch and if you look at the Environment Variables after the build the GIT_BRANCH variable is set to the correct value but if you use the GIT_BRANCH variable for Email for example the value is wrong.  Recorded Revision numbers are correct as well. Does anyone know of another, more reliable way, to get the Branch built? Hard to believe with how long Git has been around in Jenkins that this is still an issue.

          Mark Waite added a comment -

          jstarbird you could use a multi-branch pipeline with a Jenkinsfile in the root directory of each branch, then let it create a job for each branch.  When a change arrives on a branch, it is built, with the settings for that branch.  That has the added benefit of placing the job definition into source code instead of capturing the job definition as Jenkins job definition.

          Mark Waite added a comment - jstarbird you could use a multi-branch pipeline with a Jenkinsfile in the root directory of each branch, then let it create a job for each branch.  When a change arrives on a branch, it is built, with the settings for that branch.  That has the added benefit of placing the job definition into source code instead of capturing the job definition as Jenkins job definition.

          Jon Starbird added a comment -

          markewaite I'm new to Git so I'm not to sure how to work that out for the GitFlow setup we're using and building feature branches. But I'll look into that. Thanks.

          Jon Starbird added a comment - markewaite  I'm new to Git so I'm not to sure how to work that out for the GitFlow setup we're using and building feature branches. But I'll look into that. Thanks.

          Jeff Chong added a comment -

          using git version 4.0.0, this problem is still there.

          I guess you cannot trust GIT_BRANCH variable.

          Jeff Chong added a comment - using git version 4.0.0, this problem is still there. I guess you cannot trust GIT_BRANCH variable.

          Gene added a comment -

          2023 and the issue is still here. In my case, a multibranch pipeline checks out a branch. If the branch has some new commits, the GIT_BRANCH is the actual branch name. But if the branch points to the same commit as `origin/master`, then GIT_BRANCH is "master".

          Here's the offending code: https://github.com/jenkinsci/git-plugin/blob/20feaecbb9b2a1271aa7058f632e677cfb981754/src/main/java/hudson/plugins/git/GitSCM.java#L1334

          Indeed, it just blindly picks the first of the branches that contain the commit.

          Gene added a comment - 2023 and the issue is still here. In my case, a multibranch pipeline checks out a branch. If the branch has some new commits, the GIT_BRANCH is the actual branch name. But if the branch points to the same commit as `origin/master`, then GIT_BRANCH is "master". Here's the offending code: https://github.com/jenkinsci/git-plugin/blob/20feaecbb9b2a1271aa7058f632e677cfb981754/src/main/java/hudson/plugins/git/GitSCM.java#L1334 Indeed, it just blindly picks the first of the branches that contain the commit.

            Unassigned Unassigned
            sleonovich Sergey Leonovich
            Votes:
            14 Vote for this issue
            Watchers:
            21 Start watching this issue

              Created:
              Updated: