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

Surprising behavior of "catching up" with multiple branches.

    • Icon: Improvement Improvement
    • Resolution: Unresolved
    • Icon: Minor Minor
    • git-plugin
    • Official Jenkins Docker image (and this week's Jenkinsci weekly image

      I was confused by the git plugin's behavior when catching up. I expected it to run a build for the head of each branch that hadn't been built.

      Instead it seems to run a build for each unbuilt leaf, ignoring any branch heads that have children. I first noticed it when master wasn't being built and wasted a bunch of time worrying that I had something wrong with my branch specifier, e.g. that ** only matched paths that contains / or some such.

      This means that e.g. I can have branches that do not have current status-es displayed in the GitHub repository.

      You can recreate it by creating a new repository on e.g. github and using the following script to make/push a bunch of commits (leave the last few lines commented out):

      commits.sh
      git clone http://<server>/<user>/foo
      cd foo
      echo 'FOO' >> 'master'
      git add master
      git commit -a -m 'master'
      git push origin
      git checkout -b feature/foo
      echo 'FEATURE' >> feature
      git add feature
      git commit -a -m 'feature'
      git push --set-upstream origin feature/foo
      git checkout -b feature/foo2
      echo 'FEATURE' >> feature2
      git add feature2
      git commit -a -m 'feature2'
      git push --set-upstream origin feature/foo2
      git checkout feature/foo
      echo "YAY" >> yay
      git add yay
      git commit -a -m 'yay'
      git push
      git checkout master
      git checkout -b bugfix/bar
      echo 'BUG' >> bug
      git add bug
      git commit -a -m 'bug'
      git push --set-upstream origin bugfix/bar
      git checkout master
      # echo 'DOG' >> pet
      # git add pet
      # git commit -a -m 'pet'
      # git push
      

      And then setting up a simple job that refers to the repository and tracks all branches (e.g. **) and tha tis trigger-able by the /build?token=ape URL, e.g. with this Jenkins Job Builder configuration:

      foo.yaml
      - job:
          name: foo
          description: |
            HANDS OFF! This jobs is managed by Jenkins Job Builder.  Any changes
            HANDS OFF! you make will be overwritten the next time it runs.
      
            FOO!
          auth-token: 'ape'
          scm:
            - git:
                url: http://<server>/<user>/foo.git
                git-config-name: 'Your Name'
                git-config-email: 'you@foo.com'
          builders:
              - shell: |
                  #!/bin/sh -eu
                  printenv | sort
                  ls
      

      Finally, trigger the job by URL, e.g. using {{httpie} like so:

      http 192.168.99.100:8080/job/foo/build?token=ape
      

      If you run the script with the final few lines commented out, you'll end up with a repository that looks something like so:

      * [91cefe8] (origin/bugfix/bar, bugfix/bar) bug
      | * [f294c69] (origin/feature/foo, feature/foo) yay
      | | * [422983f] (origin/feature/foo2, feature/foo2) feature2
      | |/
      | * [4e86cfc] feature
      |/
      * [2e52f18] (HEAD -> master, origin/master, origin/HEAD) master
      * [84d9d20] Initial commit
      

      and you'll build feature/foo, feature/foo2, and bugfix/bar, but not master.

      If you clean everything up, uncomment out the final few lines of the bash script (which throws another commit onto master so that its head is also a leaf node), you'll end up with a repo like so:

      * [7771686] (HEAD -> master, origin/master, origin/HEAD) pet
      | * [73d7c6d] (origin/bugfix/bar, bugfix/bar) bug
      |/
      | * [43b1670] (origin/feature/foo, feature/foo) yay
      | | * [a468e73] (origin/feature/foo2, feature/foo2) feature2
      | |/
      | * [baa1264] feature
      |/
      * [46a64cb] master
      * [41f8553] Initial commit
      

      And you'll build run 4 builds (features, bugfix, and master).

      It would be useful if this behavior were documented somewhere.

      I think it would be even more useful if it ran the builds that were necessary to bring all of the branches up to date.

      Thanks!

          [JENKINS-39693] Surprising behavior of "catching up" with multiple branches.

          Marek Sotola added a comment - - edited

          This issue also occurs when you create a non-leaf node branch without any new commits (in the tree diagram above, creating a branch from commit [baa1264] will not trigger a new build that builds [baa1264], instead it will trigger a new build that builds the most recent commit). 

          Marek Sotola added a comment - - edited This issue also occurs when you create a non-leaf node branch without any new commits (in the tree diagram above, creating a branch from commit  [baa1264] will not trigger a new build that builds [baa1264] , instead it will trigger a new build that builds the most recent commit). 

          Marek Sotola added a comment -

          I think this behavior is caused by the tip-only filtering described in JENKINS-30475

          Marek Sotola added a comment - I think this behavior is caused by the tip-only filtering described in JENKINS-30475 . 

            Unassigned Unassigned
            hartzell George Hartzell
            Votes:
            2 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: