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

Surprising behavior of "catching up" with multiple branches.

XMLWordPrintable

    • 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!

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

              Created:
              Updated: