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

Git builds with detached head no matter what

    XMLWordPrintable

Details

    • Bug
    • Status: Closed (View Workflow)
    • Major
    • Resolution: Fixed
    • git-plugin
    • None
    • Ubuntu 10.04 amd64

    Description

      The Git SCM plugin has suffered from this problem since I started using it. Rather than merge the changes to be built into a branch which tracks the remote I want to push to, it checks out one rev and merges the others on, resulting in a detached HEAD. My build expects to be run on a specific branch, and it fails because the repo isn't in that state.

      Other people have encountered the same problem, and there doesn't seem to be any solution other than to fix things in the build steps, which is a big hassle.

      Can we please get this issue resolved, or if it's been fixed, clear instructions on how to make it work?

      I've attached the SCM portion of my job's config.xml. What I'm trying to do is build changes committed to branches in the origin repo (SG), merge those into SG-gold/master and push them back to SG-gold/master.

      Here are the commands where things seem to go wrong:

      [SG-experimental] $ git rev-parse gold/master
      [SG-experimental] $ git checkout -f ceb23d234b1b21006f049d310501082b77b70ae4
      [SG-experimental] $ git merge 172b2d433ee57509f8e886f5d734f226d49166dd
      [SG-experimental] $ git tag -a -f -m "Hudson Build #35" hudson-SG-experimental-35
      Warning : There are multiple branch changesets here
      

      Rather than "git checkout gold/master", it finds the hash of gold/master and checks out that instead. This is the root of the problem.

      In order to fix this, you have to put these in the first build step:

      git branch -D temp_merge || true
      git branch temp_merge ${BUILD_TAG}
      git checkout master
      git reset --hard gold/master
      git merge temp_merge
      

      This is error-prone and requires duplication of the merge target branch that's already in the Git configuration for the job.

      Attachments

        Issue Links

          Activity

            ieure ieure created issue -
            eguess74 eguess74 added a comment -

            You're mistaken. Checking out to gold/master is actually ABSOLUTELY the same action as checking out to revision it points to. It is a "remote" branch so checking out to it will lead to detached HEAD no matter what.
            Git plugin working with revisions in detached HEAD mode is a good thing, IMHO.
            It would be more interesting to see the log when it tries to push back your changes to understand why you're not happy about it.

            eguess74 eguess74 added a comment - You're mistaken. Checking out to gold/master is actually ABSOLUTELY the same action as checking out to revision it points to. It is a "remote" branch so checking out to it will lead to detached HEAD no matter what. Git plugin working with revisions in detached HEAD mode is a good thing, IMHO. It would be more interesting to see the log when it tries to push back your changes to understand why you're not happy about it.
            ieure ieure added a comment -

            As I stated, I have tools which require that the repository be on a branch, which is not the same thing as being detached while pointing to the same commit. I'm referring to git-buildpackage here, which has the notion of a "debian branch" and an "upstream branch." In order to create the diff between the upstream source and the Debian changes, it runs "git diff upstream..debian" (or whatever you tell it the branches are). When you aren't on a branch, this isn't possible. It doesn't make sense to diff "upstream..random sha1", since you would never do that in a normal package development cycle.

            Just because the files on disk are the same revisions with HEAD detached does not mean that it's the same. The context is important, and being in an unusual state causes things to break. I'm not the only one this is a problem for, as a reading of the Git plugin wiki clearly shows.

            The push is not the issue. The build is the issue. If the build succeeds, the push works fine. What's broken is the state of the repo when the build happens. What's broken is that I say "merge into this branch," not "merge into detached head, then push back to this branch."

            Can you give me a concrete list of the advantages of building this way versus merging into the branch I'm telling it to merge into?

            ieure ieure added a comment - As I stated, I have tools which require that the repository be on a branch, which is not the same thing as being detached while pointing to the same commit. I'm referring to git-buildpackage here, which has the notion of a "debian branch" and an "upstream branch." In order to create the diff between the upstream source and the Debian changes, it runs "git diff upstream..debian" (or whatever you tell it the branches are). When you aren't on a branch, this isn't possible. It doesn't make sense to diff "upstream..random sha1", since you would never do that in a normal package development cycle. Just because the files on disk are the same revisions with HEAD detached does not mean that it's the same. The context is important, and being in an unusual state causes things to break. I'm not the only one this is a problem for, as a reading of the Git plugin wiki clearly shows. The push is not the issue. The build is the issue. If the build succeeds, the push works fine. What's broken is the state of the repo when the build happens. What's broken is that I say "merge into this branch," not "merge into detached head, then push back to this branch." Can you give me a concrete list of the advantages of building this way versus merging into the branch I'm telling it to merge into?
            ieure ieure added a comment -

            I would also point out that your argument is contradictory. Building with a detached head is a good thing, except it's absolutely the same as not? That nonsensical.

            ieure ieure added a comment - I would also point out that your argument is contradictory. Building with a detached head is a good thing, except it's absolutely the same as not? That nonsensical.
            abayer Andrew Bayer added a comment -

            Between this and JENKINS-5856, there definitely seems to be a need for the ability to checkout to a branch, rather than just detached HEAD. I'm still not entirely clear on all the git mechanics (and yet I'm the git plugin maintainer - yay for confusion!), but I've made a run at adding an option for checking out to a branch. It's in github at http://github.com/abayer/Hudson-GIT-plugin/tree/JENKINS-6856. If the local branch is specified in the project's advanced configuration, the "git checkout <ref>" commands will instead be "git checkout -b <local branch> <ref>". Which I think fits what you need.

            Give it a look and let me know what you think.

            abayer Andrew Bayer added a comment - Between this and JENKINS-5856 , there definitely seems to be a need for the ability to checkout to a branch, rather than just detached HEAD. I'm still not entirely clear on all the git mechanics (and yet I'm the git plugin maintainer - yay for confusion!), but I've made a run at adding an option for checking out to a branch. It's in github at http://github.com/abayer/Hudson-GIT-plugin/tree/JENKINS-6856 . If the local branch is specified in the project's advanced configuration, the "git checkout <ref>" commands will instead be "git checkout -b <local branch> <ref>". Which I think fits what you need. Give it a look and let me know what you think.
            abayer Andrew Bayer made changes -
            Field Original Value New Value
            Link This issue is blocking JENKINS-5856 [ JENKINS-5856 ]
            abayer Andrew Bayer added a comment -

            Ok, I've merged that to master, and it'll be in the next release (tentatively 1.0, probably coming in the next week or two).

            abayer Andrew Bayer added a comment - Ok, I've merged that to master, and it'll be in the next release (tentatively 1.0, probably coming in the next week or two).
            abayer Andrew Bayer made changes -
            Resolution Fixed [ 1 ]
            Status Open [ 1 ] Resolved [ 5 ]
            abayer Andrew Bayer added a comment -

            Whoops, just realized we need to delete the local branch first.

            abayer Andrew Bayer added a comment - Whoops, just realized we need to delete the local branch first.
            dogfood dogfood added a comment -

            Integrated in plugins_hudson-git-plugin #8
            Last round of tweaks for JENKINS-6856 - had to make sure branch actually existed before deleting it, and had to make sure we ignored branches with -> in parseBranches, since that can't be parsed by rev-parse

            Andrew Bayer :
            Files :

            • src/main/java/hudson/plugins/git/GitAPI.java
            dogfood dogfood added a comment - Integrated in plugins_hudson-git-plugin #8 Last round of tweaks for JENKINS-6856 - had to make sure branch actually existed before deleting it, and had to make sure we ignored branches with -> in parseBranches, since that can't be parsed by rev-parse Andrew Bayer : Files : src/main/java/hudson/plugins/git/GitAPI.java
            eguess74 eguess74 added a comment - - edited

            I might be a bit late, but I will try to answer to two comments from ieure:

            1. What I was trying to explain is that this particular line in your bug description is incorrect:
            "Rather than "git checkout gold/master", it finds the hash of gold/master and checks out that instead. This is the root of the problem."
            You're making the same mistake when you're saying: "Building with a detached head is a good thing, except it's absolutely the same as not? That nonsensical."

            I didn't say that being in detached HEAD state is the same as not being in it. I said that both actions "git checkout gold/master" and "git checkout SHA-1" are having the same effect. Generally speaking, checkout to any remote branch (for example like origin/master) is ABSOLUTELY identical to checking out to SHA-1 this branch points to (actually, it is true for any SHA-1 commit ID). BOTH actions will lead to detached HEAD, which means that the HEAD will be pointing to the commit ID directly, it won't be pointing to the branch, i.e. it won't be a symbolic ref anymore.

            You can take a look at it like this in any repo:
            $ git checkout master
            $ vi .git/HEAD
            $ git rev-parse master
            $ git checkout "SHA-1 from previous command" # (it will printout pretty much the same explanation as i'm trying to make here)
            $ vi .git/HEAD #it is now pointing directly to a commit

            2. Secondly, why working in Hudson with detached HEAD is good? Because the detached HEAD state will guarantee you that NONE of the actions your performing in this state will be recorded in the LOCAL repo unless you will be explicit about it. For example, in detached HEAD state you can commit, but your commits will be lost as soon as you will checkout to an existing local branch, unless you will create a new local branch after you committed in detached HEAD state.

            You're saying that the problem is that your Hudson local repo is in broken state after build. Well, it is not, because detached HEAD is not a broken state! Why you shouldn't care about local Hudson repo? Exactly, because git plugin is working with it using detached HEAD state.

            here is the example:

            you have your gold/master branch pointing to commit aaa
            you have your dev branch pointing to commit bbb

            build process checks out to gold/master revision aaa
            then it resolves the revision to merge bbb and performs the merge. Your HEAD is pointing to the resulting revision ccc (for example there was a recursive merge used which got recorded as new commit) and gets tagged. Now when you take a look at the help message for the git publisher branches you will see that it says that it will merge back the current HEAD! to the specified remote branch!

            I.e. that you will get the merge results in your official repository just fine, unless, for example, there is a conflict during the merge.

            The point is that you don't have to care about the state of your local Hudson repository, becasue it is not important - your mainline (gold) is important.

            OTOH I understand it might be necessary for you to be in some branch because git-buildpackage is requiring it. We are using the default detached HEAD behavior for integration builds, but we use Release plugin in order to prepare production artifact, which has explicit instructions to checkout to master branch, pull latest changes from mainline and then build the code.

            I hope that helps.

            eguess74 eguess74 added a comment - - edited I might be a bit late, but I will try to answer to two comments from ieure: 1. What I was trying to explain is that this particular line in your bug description is incorrect: "Rather than "git checkout gold/master", it finds the hash of gold/master and checks out that instead. This is the root of the problem." You're making the same mistake when you're saying: "Building with a detached head is a good thing, except it's absolutely the same as not? That nonsensical." I didn't say that being in detached HEAD state is the same as not being in it. I said that both actions "git checkout gold/master" and "git checkout SHA-1" are having the same effect. Generally speaking, checkout to any remote branch (for example like origin/master) is ABSOLUTELY identical to checking out to SHA-1 this branch points to (actually, it is true for any SHA-1 commit ID). BOTH actions will lead to detached HEAD, which means that the HEAD will be pointing to the commit ID directly, it won't be pointing to the branch, i.e. it won't be a symbolic ref anymore. You can take a look at it like this in any repo: $ git checkout master $ vi .git/HEAD $ git rev-parse master $ git checkout "SHA-1 from previous command" # (it will printout pretty much the same explanation as i'm trying to make here) $ vi .git/HEAD #it is now pointing directly to a commit 2. Secondly, why working in Hudson with detached HEAD is good? Because the detached HEAD state will guarantee you that NONE of the actions your performing in this state will be recorded in the LOCAL repo unless you will be explicit about it. For example, in detached HEAD state you can commit, but your commits will be lost as soon as you will checkout to an existing local branch, unless you will create a new local branch after you committed in detached HEAD state. You're saying that the problem is that your Hudson local repo is in broken state after build. Well, it is not, because detached HEAD is not a broken state! Why you shouldn't care about local Hudson repo? Exactly, because git plugin is working with it using detached HEAD state. here is the example: you have your gold/master branch pointing to commit aaa you have your dev branch pointing to commit bbb build process checks out to gold/master revision aaa then it resolves the revision to merge bbb and performs the merge. Your HEAD is pointing to the resulting revision ccc (for example there was a recursive merge used which got recorded as new commit) and gets tagged. Now when you take a look at the help message for the git publisher branches you will see that it says that it will merge back the current HEAD! to the specified remote branch! I.e. that you will get the merge results in your official repository just fine, unless, for example, there is a conflict during the merge. The point is that you don't have to care about the state of your local Hudson repository, becasue it is not important - your mainline (gold) is important. OTOH I understand it might be necessary for you to be in some branch because git-buildpackage is requiring it. We are using the default detached HEAD behavior for integration builds, but we use Release plugin in order to prepare production artifact, which has explicit instructions to checkout to master branch, pull latest changes from mainline and then build the code. I hope that helps.
            eguess74 eguess74 added a comment -

            I suggest to fix the help message for the property "Local branch to use" from current very confusing one to something like that:

            "If given, corresponding local branch will be created to store the results of build activities like merges"

            eguess74 eguess74 added a comment - I suggest to fix the help message for the property "Local branch to use" from current very confusing one to something like that: "If given, corresponding local branch will be created to store the results of build activities like merges"
            eguess74 eguess74 made changes -
            Resolution Fixed [ 1 ]
            Status Resolved [ 5 ] Reopened [ 4 ]
            abayer Andrew Bayer added a comment -

            Wording cleaned up.

            abayer Andrew Bayer added a comment - Wording cleaned up.
            abayer Andrew Bayer made changes -
            Resolution Fixed [ 1 ]
            Status Reopened [ 4 ] Resolved [ 5 ]
            markdoliner Mark Doliner added a comment -

            I have some questions about the plugin's behavior regarding detached heads, but I think it might be best to approach this discussion by letting you know what I'm trying to do, and let you suggest the best way to do it.

            I'd like Jenkins to build and run unit tests for all branches in my repository. I'd like to do this in the build commands for my job: "if $this_branch == 'release_21' then release_this_build_to_beta_servers" The particular branch to be released changes from time to time.

            And so it would be convenient for me to be able to see which branch is currently being built. Does this make sense? How would you suggest I accomplish this?

            markdoliner Mark Doliner added a comment - I have some questions about the plugin's behavior regarding detached heads, but I think it might be best to approach this discussion by letting you know what I'm trying to do, and let you suggest the best way to do it. I'd like Jenkins to build and run unit tests for all branches in my repository. I'd like to do this in the build commands for my job: "if $this_branch == 'release_21' then release_this_build_to_beta_servers" The particular branch to be released changes from time to time. And so it would be convenient for me to be able to see which branch is currently being built. Does this make sense? How would you suggest I accomplish this?
            markdoliner Mark Doliner added a comment -

            Two related questions:
            1. Why doesn't the plugin pass --track to the git checkout command?
            2. Would it make sense for there to be a magic string that could be set for "Checkout/merge to local branch (optional)" that means "use remote branch name"?

            markdoliner Mark Doliner added a comment - Two related questions: 1. Why doesn't the plugin pass --track to the git checkout command? 2. Would it make sense for there to be a magic string that could be set for "Checkout/merge to local branch (optional)" that means "use remote branch name"?

            This issue was marked as resolved, and the resolution marked as "Fixed"... but AFAICT this issue wasn't really fixed and Jenkins still checks out remote branches and winds up in a headless state. Is this going to stay this way? It causes serious headaches for us.

            hangtwenty Michael Floering added a comment - This issue was marked as resolved, and the resolution marked as "Fixed"... but AFAICT this issue wasn't really fixed and Jenkins still checks out remote branches and winds up in a headless state. Is this going to stay this way? It causes serious headaches for us.
            jmoody Joshua Moody added a comment - - edited

            I second what Michael Floering says.

            I don't believe this has been fixed.

            The detached head state is causing a bunch of problems for us.

            UPDATE: After sleeping on the problem I, made a changes which I think resolved the detached head problem:

            In the Git plugin Advanced Options, I added: "Checkout to a specific local branch" and provided a branch name.

            jmoody Joshua Moody added a comment - - edited I second what Michael Floering says. I don't believe this has been fixed. The detached head state is causing a bunch of problems for us. UPDATE: After sleeping on the problem I, made a changes which I think resolved the detached head problem: In the Git plugin Advanced Options, I added: "Checkout to a specific local branch" and provided a branch name.
            markewaite Mark Waite made changes -
            Status Resolved [ 5 ] Closed [ 6 ]
            petteyg359 Gordon Pettey added a comment -

            The detached state breaks build tools that attempt to find the current branch name by calling git branch. When running a project that has multiple branches, the workaround in the previous comment requires n jobs for n branches instead of 1 job.

            petteyg359 Gordon Pettey added a comment - The detached state breaks build tools that attempt to find the current branch name by calling git branch. When running a project that has multiple branches, the workaround in the previous comment requires n jobs for n branches instead of 1 job.
            raphsoft Emilio Garcia added a comment -

            I have the same problem. Is there any way to avoid the plugin using detached state? I will suggest this to be reopen.

            raphsoft Emilio Garcia added a comment - I have the same problem. Is there any way to avoid the plugin using detached state? I will suggest this to be reopen.

            I have this workaround, this depends on the plugin setting the GIT_BRANCH environment variable with the remote ref (including the leading "origin/") that it checked out. So have an Execute Shell build step before your commands:

            #!bash
            git checkout ${GIT_BRANCH#origin/}
            

            The above will check out the branch properly, before running your command. Also, have the following commands in another Execute Shell build step after your commands to do the necessary cleanup:

            #!bash
            git checkout $GIT_BRANCH
            git branch -D ${GIT_BRANCH#origin/}
            
            tanzislam Tanzinul Islam added a comment - I have this workaround, this depends on the plugin setting the GIT_BRANCH environment variable with the remote ref (including the leading "origin/") that it checked out. So have an Execute Shell build step before your commands: #!bash git checkout ${GIT_BRANCH#origin/} The above will check out the branch properly, before running your command. Also, have the following commands in another Execute Shell build step after your commands to do the necessary cleanup: #!bash git checkout $GIT_BRANCH git branch -D ${GIT_BRANCH#origin/}
            ceddlyburge cedd burge added a comment -

            I agree, this doesn't seem to have been fixed, and it would help me if it was. It seems like an easy change too. I wonder if there is a complication that we aren't aware of?

            ceddlyburge cedd burge added a comment - I agree, this doesn't seem to have been fixed, and it would help me if it was. It seems like an easy change too. I wonder if there is a complication that we aren't aware of?
            markewaite Mark Waite added a comment -

            Can't you add the "Additional Behaviour" of "Checkout to a specific branch"? That will give you a named branch.

            Changing the plugin from using a detached head to using a branch is non-trivial if the goal is to not break a significant portion of the 70 000+ installations of the git plugin. There are too many use models and too many cases where silently switching to use a branch (instead of a detached head) would cause compatibility problems.

            markewaite Mark Waite added a comment - Can't you add the "Additional Behaviour" of "Checkout to a specific branch"? That will give you a named branch. Changing the plugin from using a detached head to using a branch is non-trivial if the goal is to not break a significant portion of the 70 000+ installations of the git plugin. There are too many use models and too many cases where silently switching to use a branch (instead of a detached head) would cause compatibility problems.
            cedd cedd burge added a comment -

            If its difficult then fair enough. I am running git commands in a batch script to get round this issue, which is fine, although I do end up wondering what I am getting out of the plug in in this case.

            The checkout to specific branch does work, but has complications when building multiple branches (which is a great feature of the plug in).

            Maybe adding another environment variable for the branch name would be useful (eg without the "origin/" bit at the start).

            I do think that this shouldn't be marked as "Fixed", when it definitely hasn't been. It's misleading and means people will spend time trying to work out why it isn't working.

            cedd cedd burge added a comment - If its difficult then fair enough. I am running git commands in a batch script to get round this issue, which is fine, although I do end up wondering what I am getting out of the plug in in this case. The checkout to specific branch does work, but has complications when building multiple branches (which is a great feature of the plug in). Maybe adding another environment variable for the branch name would be useful (eg without the "origin/" bit at the start). I do think that this shouldn't be marked as "Fixed", when it definitely hasn't been. It's misleading and means people will spend time trying to work out why it isn't working.
            markewaite Mark Waite added a comment -

            I think the bug is fixed. I just ran a series of tests which confirmed that I can checkout to the branch

            ${GIT_BRANCH}

            . It expands that variable and performs a checkout of the correct branch.

            Steps I took

            1. Create a new job JENKINS-6856-checkout-to-GIT_BRANCH
            2. Use git as the SCM
            3. Use git://github.com/MarkEWaite/git-client-plugin.git as the repository to checkout
            4. Add "Additional Behavior" to checkout to a specific branch, with the value
              $GIT_BRANCH
            5. Check the "Poll SCM" check box (no polling schedule needed)
            6. Save the job
            7. Click the "Poll Now" link on the left side of the job (assuming you have the "Poll Now" plugin installed

            That series of steps resulted in immediately running 19 jobs, one for each branch in that repository. Each of those 19 jobs used a branch named precisely for the branch in the origin repository.

            What it does not provide is a way to checkout a named branch which is a substring of

            GIT_BRANCH

            . I think that is what you need, and what is requested in pull request 347

            There is some facility to allow substrings of GIT_BRANCH, but I was unable to make it work in the cases I was testing. The GIT_BRANCH variable is implemented inside the git plugin as a "token macro" which takes two optional arguments, fullName and all. If the fullName parameter is false, then the GIT_BRANCH value is to be returned with everything to the right of the leftmost slash character. Unfortunately, I was unable to see the token macro expanded when used in the context of "Branch to build". If I wrote it as

            ${GIT_BRANCH,fullName=false}

            , then the GIT_BRANCH variable was not expanded.

            The token macro facility needs more attention inside the git plugin (as far as I can tell), before I'd be confident saying that it works as intended.

            markewaite Mark Waite added a comment - I think the bug is fixed. I just ran a series of tests which confirmed that I can checkout to the branch ${GIT_BRANCH} . It expands that variable and performs a checkout of the correct branch. Steps I took Create a new job JENKINS-6856 -checkout-to-GIT_BRANCH Use git as the SCM Use git://github.com/MarkEWaite/git-client-plugin.git as the repository to checkout Add "Additional Behavior" to checkout to a specific branch, with the value $GIT_BRANCH Check the "Poll SCM" check box (no polling schedule needed) Save the job Click the "Poll Now" link on the left side of the job (assuming you have the "Poll Now" plugin installed That series of steps resulted in immediately running 19 jobs, one for each branch in that repository. Each of those 19 jobs used a branch named precisely for the branch in the origin repository. What it does not provide is a way to checkout a named branch which is a substring of GIT_BRANCH . I think that is what you need, and what is requested in pull request 347 There is some facility to allow substrings of GIT_BRANCH, but I was unable to make it work in the cases I was testing. The GIT_BRANCH variable is implemented inside the git plugin as a "token macro" which takes two optional arguments, fullName and all. If the fullName parameter is false, then the GIT_BRANCH value is to be returned with everything to the right of the leftmost slash character. Unfortunately, I was unable to see the token macro expanded when used in the context of "Branch to build". If I wrote it as ${GIT_BRANCH,fullName= false } , then the GIT_BRANCH variable was not expanded. The token macro facility needs more attention inside the git plugin (as far as I can tell), before I'd be confident saying that it works as intended.
            markewaite Mark Waite added a comment -

            Earlier comments in the bug report allude to other ways to checkout the exact desired branch name, so long as you have a bash compatible interpreter available (most Unix variants).

            I used this (combined with the earlier checkout to a specific branch name) as a shell script step to checkout a tracking branch

            HEAD=$(git rev-parse --abbrev-ref HEAD)
            CURRENT_BRANCH=remotes/origin/${HEAD##*origin/}
            WORKING_BRANCH=${CURRENT_BRANCH##*origin/}
            git checkout $WORKING_BRANCH || git checkout -b $WORKING_BRANCH -t $CURRENT_BRANCH
            
            markewaite Mark Waite added a comment - Earlier comments in the bug report allude to other ways to checkout the exact desired branch name, so long as you have a bash compatible interpreter available (most Unix variants). I used this (combined with the earlier checkout to a specific branch name) as a shell script step to checkout a tracking branch HEAD=$(git rev-parse --abbrev-ref HEAD) CURRENT_BRANCH=remotes/origin/${HEAD##*origin/} WORKING_BRANCH=${CURRENT_BRANCH##*origin/} git checkout $WORKING_BRANCH || git checkout -b $WORKING_BRANCH -t $CURRENT_BRANCH

            Code changed in jenkins
            User: Mark Waite
            Path:
            src/test/java/hudson/plugins/git/TestBranchSpec.java
            http://jenkins-ci.org/commit/git-plugin/91a1ffc3a6030e8d74fe463edff13d7f1f08fd41
            Log:
            Add tests exploring JENKINS-6856 - token macro expansion

            BranchSpec does not seem to honor token macros. For example,
            $GIT_BRANCH matches as expected
            ${GIT_BRANCH} matches as expected
            ${GIT_BRANCH,fullName=False} does not match
            ${GIT_BRANCH,fullName=True} does not match

            I expected either all of them to match as expected (token macro expansion
            was being applied), or none of them to match (no variable expansion and
            no token macro expansion). As far as I can tell, variable expansion is
            being applied, but token macro expansion is not being applied.

            scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Mark Waite Path: src/test/java/hudson/plugins/git/TestBranchSpec.java http://jenkins-ci.org/commit/git-plugin/91a1ffc3a6030e8d74fe463edff13d7f1f08fd41 Log: Add tests exploring JENKINS-6856 - token macro expansion BranchSpec does not seem to honor token macros. For example, $GIT_BRANCH matches as expected ${GIT_BRANCH} matches as expected ${GIT_BRANCH,fullName=False} does not match ${GIT_BRANCH,fullName=True} does not match I expected either all of them to match as expected (token macro expansion was being applied), or none of them to match (no variable expansion and no token macro expansion). As far as I can tell, variable expansion is being applied, but token macro expansion is not being applied.

            This confused me too, my scripts rely on finding the name of the current branch which was not possible. It did work however using $GIT_BRANCH as mentioned above, but I did not find that out before finding this issue. Couldn't that be documented for the "Check out to specific local branch" field ?

            zitrax Daniel Bengtsson added a comment - This confused me too, my scripts rely on finding the name of the current branch which was not possible. It did work however using $GIT_BRANCH as mentioned above, but I did not find that out before finding this issue. Couldn't that be documented for the "Check out to specific local branch" field ?
            markewaite Mark Waite added a comment -

            zitrax you could also use the "Local Branch" extension that was added to git plugin 2.4.4. Refer to the online help for the local branch extension.

            In the Local Branch extension, you set the branch name to "**" or the empty string, and that then causes the plugin to checkout to a branch name derived from the branch that was the origin of the checkout. That allows a branch specifier to select multiple branches, then the branch which is checked out is based on the specific branch selected for that run of the job.

            markewaite Mark Waite added a comment - zitrax you could also use the "Local Branch" extension that was added to git plugin 2.4.4. Refer to the online help for the local branch extension. In the Local Branch extension, you set the branch name to "**" or the empty string, and that then causes the plugin to checkout to a branch name derived from the branch that was the origin of the checkout. That allows a branch specifier to select multiple branches, then the branch which is checked out is based on the specific branch selected for that run of the job.
            rtyler R. Tyler Croy made changes -
            Workflow JNJira [ 136951 ] JNJira + In-Review [ 204304 ]
            itaiganot Itai Ganot added a comment -

            I'm writing a pipeline which clones a git repository and supposed to checkout to a specific branch, then merge master to that branch and run a MSBuild.

            In reality, git checks out to the sha of the last commit in the branch instead of the branch name itself which is a detached head and the ${GIT_BRANCH} variable is evaluated to 'null'.

            // Started by user itai ganot
            [Pipeline] node
            Running on master in C:\Program Files (x86)\Jenkins\workspace\bbb
            [Pipeline] {
            [Pipeline] stage
            [Pipeline] { (Setup)
            [Pipeline] deleteDir
            [Pipeline] }
            [Pipeline] // stage
            [Pipeline] stage
            [Pipeline] { (Checkout SCM & Merge master to feature branch)
            [Pipeline] checkout
            Cloning the remote Git repository
            Cloning repository http://pctfs1:8080/tfs/DefaultCollection/PC_International/_git/Ensure-pcs-intl
             > git.exe init C:\Program Files (x86)\Jenkins\workspace\bbb # timeout=10
            Fetching upstream changes from http://TFS_SERVER:8080/tfs/DefaultCollection/PC_International/_git/Ensure-pcs-intl
             > git.exe --version # timeout=10
            using GIT_SSH to set credentials javab SSH file
             > git.exe fetch --tags --progress http://TFS_SERVER:8080/tfs/DefaultCollection/PC_International/_git/REPO_NAME +refs/heads/*:refs/remotes/origin/*
             > git.exe config remote.origin.url http://TFS_SERVER:8080/tfs/DefaultCollection/PC_International/_git/REPO_NAME # timeout=10
             > git.exe config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
             > git.exe config remote.origin.url http://TFS_SERVER:8080/tfs/DefaultCollection/PC_International/_git/REPO_NAME # timeout=10
            Fetching upstream changes from http://TFS_SERVER:8080/tfs/DefaultCollection/PC_International/_git/REPO_NAME
            using GIT_SSH to set credentials javab SSH file
             > git.exe fetch --tags --progress http://TFS_SERVER:8080/tfs/DefaultCollection/PC_International/_git/REPO_NAME +refs/heads/*:refs/remotes/origin/*
            Seen branch in repository origin/feature/merge_tfs
            Seen branch in repository origin/master
            Seen branch in repository origin/origin
            Seen 3 remote branches
             > git.exe tag -l # timeout=10
            Checking out Revision 97b3493db4f726e11e334e5ba34fa808b63edec5 (origin/feature/merge_tfs)
             > git.exe config core.sparsecheckout # timeout=10
             > git.exe checkout -f 97b3493db4f726e11e334e5ba34fa808b63edec5
            First time build. Skipping changelog.
            [Pipeline] bat
            [bbb] Running batch script
            
            C:\Program Files (x86)\Jenkins\workspace\bbb>cd C:\Program Files (x86)\Jenkins\workspace\bbb 
            
            C:\Program Files (x86)\Jenkins\workspace\bbb>git branch 
            * (HEAD detached at 97b3493)
            
            C:\Program Files (x86)\Jenkins\workspace\bbb>echo "git branch: null" 
            "git branch: null"
            
            C:\Program Files (x86)\Jenkins\workspace\bbb>echo "git branch: null" 
            "git branch: null"
            [Pipeline] }
            [Pipeline] // stage
            

            How can I make sure that I checkout to the relevant branch_name?

            itaiganot Itai Ganot added a comment - I'm writing a pipeline which clones a git repository and supposed to checkout to a specific branch, then merge master to that branch and run a MSBuild. In reality, git checks out to the sha of the last commit in the branch instead of the branch name itself which is a detached head and the ${GIT_BRANCH} variable is evaluated to 'null'. // Started by user itai ganot [Pipeline] node Running on master in C:\Program Files (x86)\Jenkins\workspace\bbb [Pipeline] { [Pipeline] stage [Pipeline] { (Setup) [Pipeline] deleteDir [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (Checkout SCM & Merge master to feature branch) [Pipeline] checkout Cloning the remote Git repository Cloning repository http: //pctfs1:8080/tfs/DefaultCollection/PC_International/_git/Ensure-pcs-intl > git.exe init C:\Program Files (x86)\Jenkins\workspace\bbb # timeout=10 Fetching upstream changes from http: //TFS_SERVER:8080/tfs/DefaultCollection/PC_International/_git/Ensure-pcs-intl > git.exe --version # timeout=10 using GIT_SSH to set credentials javab SSH file > git.exe fetch --tags --progress http: //TFS_SERVER:8080/tfs/DefaultCollection/PC_International/_git/REPO_NAME +refs/heads/*:refs/remotes/origin/* > git.exe config remote.origin.url http: //TFS_SERVER:8080/tfs/DefaultCollection/PC_International/_git/REPO_NAME # timeout=10 > git.exe config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10 > git.exe config remote.origin.url http: //TFS_SERVER:8080/tfs/DefaultCollection/PC_International/_git/REPO_NAME # timeout=10 Fetching upstream changes from http: //TFS_SERVER:8080/tfs/DefaultCollection/PC_International/_git/REPO_NAME using GIT_SSH to set credentials javab SSH file > git.exe fetch --tags --progress http: //TFS_SERVER:8080/tfs/DefaultCollection/PC_International/_git/REPO_NAME +refs/heads/*:refs/remotes/origin/* Seen branch in repository origin/feature/merge_tfs Seen branch in repository origin/master Seen branch in repository origin/origin Seen 3 remote branches > git.exe tag -l # timeout=10 Checking out Revision 97b3493db4f726e11e334e5ba34fa808b63edec5 (origin/feature/merge_tfs) > git.exe config core.sparsecheckout # timeout=10 > git.exe checkout -f 97b3493db4f726e11e334e5ba34fa808b63edec5 First time build. Skipping changelog. [Pipeline] bat [bbb] Running batch script C:\Program Files (x86)\Jenkins\workspace\bbb>cd C:\Program Files (x86)\Jenkins\workspace\bbb C:\Program Files (x86)\Jenkins\workspace\bbb>git branch * (HEAD detached at 97b3493) C:\Program Files (x86)\Jenkins\workspace\bbb>echo "git branch: null " "git branch: null " C:\Program Files (x86)\Jenkins\workspace\bbb>echo "git branch: null " "git branch: null " [Pipeline] } [Pipeline] // stage How can I make sure that I checkout to the relevant branch_name?
            itaiganot Itai Ganot made changes -
            Resolution Fixed [ 1 ]
            Status Closed [ 6 ] Reopened [ 4 ]
            markewaite Mark Waite added a comment -

            itaiganot please refer to the comment prior to your question.

            The "pipeline syntax" link on the left of most pipeline job pages will open a page where you can prototype the code you need to perform a checkout to a specific branch. Use the "checkout" selection from that list (not the "git" selection), then select "Git" and add the "Additional Behaviours" for "Check out to specific local branch". You can then set a specific branch name, or you can use "**" to indicate that it should use the branch name from the repository where the clone was performed.

            markewaite Mark Waite added a comment - itaiganot please refer to the comment prior to your question . The "pipeline syntax" link on the left of most pipeline job pages will open a page where you can prototype the code you need to perform a checkout to a specific branch. Use the "checkout" selection from that list (not the "git" selection), then select "Git" and add the "Additional Behaviours" for "Check out to specific local branch". You can then set a specific branch name, or you can use "**" to indicate that it should use the branch name from the repository where the clone was performed.
            markewaite Mark Waite made changes -
            Resolution Fixed [ 1 ]
            Status Reopened [ 4 ] Resolved [ 5 ]
            itaiganot Itai Ganot added a comment -

            Thanks, it did solve my first issue.

            But now I have another issue which is also related, I'd like to set:

            // currentBuild.displayName = "#${BUILD_NUMBER}|${BRANCH_NAME}" 
            

            And it cannot be done in pipeline because of the same reason... what can be done to achieve that?

            itaiganot Itai Ganot added a comment - Thanks, it did solve my first issue. But now I have another issue which is also related, I'd like to set: // currentBuild.displayName = "#${BUILD_NUMBER}|${BRANCH_NAME}"   And it cannot be done in pipeline because of the same reason... what can be done to achieve that?
            markewaite Mark Waite added a comment -

            itaiganot please don't use closed bug reports as a forum for questions. You're asking for time from the very few people who read git plugin bug reports, when there are much larger groups (like the Jenkins users mailing list) that can address your questions.

            markewaite Mark Waite added a comment - itaiganot please don't use closed bug reports as a forum for questions. You're asking for time from the very few people who read git plugin bug reports, when there are much larger groups (like the Jenkins users mailing list) that can address your questions.

            Isn't it enough to do the following to get a proper branch head at some point after the checkout?  It seems to work for me. 

            git checkout -b ${GIT_BRANCH} origin/${GIT_BRANCH}

            raulsalinasmonteagudo Raúl Salinas-Monteagudo added a comment - Isn't it enough to do the following to get a proper branch head at some point after the checkout?  It seems to work for me.  git checkout -b ${GIT_BRANCH} origin/${GIT_BRANCH }
            markewaite Mark Waite added a comment - - edited

            Yes, the git checkout command you used is a very good choice, especially if you're not using authenticated submodules or authenticated access to large file storage (git LFS).

            markewaite Mark Waite added a comment - - edited Yes, the git checkout command you used is a very good choice, especially if you're not using authenticated submodules or authenticated access to large file storage (git LFS).
            markewaite Mark Waite made changes -
            Status Resolved [ 5 ] Closed [ 6 ]

            People

              abayer Andrew Bayer
              ieure ieure
              Votes:
              0 Vote for this issue
              Watchers:
              16 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: