Managing Git branch level permissions with TeamForge and Gerrit

  25 comments for “Managing Git branch level permissions with TeamForge and Gerrit

  1. January 15, 2013 at 3:18 am

    Great blog post, just wanted to point out that webinar series is starting today where you will learn how to use those categories to marry Jenkins with Gerrit properly:

  2. Jonas Christensen
    February 17, 2014 at 12:44 am


    A few comments and questions:

    1) If I create a new category in gerritforge.mappings, and mention it in the Description, which Repository Category to choose then? Default? Other? Or doesn’t it matter?

    2) When I create a new repo the parent is default set to “– All Projects –”. In a native Gerrit installation I can choose, at creation time, which project to set as parent. This is not possible in the CTF integration. As I find the category handling in gerritforge.mappings a bit cumbersome, have you any plan to implement the ability to manually choose parent at creation time? Or, the ability to change parent to other than “– All Projects –”? This will allow for a very common Gerrit setup where you create a “access control” repo which only serve as parent for all your code repos.

    Jonas Christensen
    Schneider Electric

    • February 17, 2014 at 3:00 am

      Hi Jonas,

      regarding 1): Suppose your new category is called foo, you would have to mentioned it in the repo description like [RepoCategory:foo] if you are using TeamForge 6.2 If you are using a newer version, you would select “Other” as category in the repository settings and enter foo in the text box.

      regarding 2): At the moment, all Gerrit projects are direct children of –All projects–. We have an item in our roadmap to rather use the TeamForge project hierarchy instead. It is not our goal to allow arbitrary parent/child project relationships as in our opinion this undermines one of the main value props of our integration: Most end users are overwhlemed with Gerrit’s access rights (in our newest supported version, there are 24 differenct access rights categories). We have often seen that people feel unsure on how to properly configure those access rights and not accidentally expose their source code to a broader audience than anticipated. Think about it like an electro oven with 24 different knobs and your job is to just warm up your pizza. You started turning those knobs until your Pizza is warmed up but do not realize that by turning on the second knob, you also activated something different until your apartment is on fire (== you managed to get your team access to your Gerrit project but did not realize you granted everybody permissions because one obscure detail about rule inheritance was misunderstood). Our goal is to shield most users from Gerrit’s complexities by using predefined repo categories and rather generic TeamForge SCM permissions without hiding advanced features for power users. More experienced end users can still configure things themselves by switching off the TeamForge auto pilot “custom category” and fine tune things themselves in the Gerrit Web UI. Allowing arbitrary parent child relationships will introduce another layer of complexity that due to its right inheritance nature will also affect repositories of not so experienced end users. To strike the balance between those two user groups, we will probably only allow a hierarchy as defined in TeamForge, so that our support and casual Gerrit users still have a chance to find out what is actually going on and how to fix things if broken.

  3. Jonas Christensen
    February 25, 2014 at 12:22 am

    Hi Johannes,

    Thanks for your explanation. I have a few comments.

    Is it possible to use a CTF role in a repository category, e.g. instead of “branch_based.scm_commit.3=pHD,1,3,refs/heads/devel/*” then use “branch_based.role2547.3=pHD,1,3,refs/heads/devel/*” ??

    If not, then I can’t see how your repository category implementation is usable in a standard CI/CD setup where you have developers which are allowed to commit to some branches (e.g. develop), integrators which are able to commit to other branches (e.g. release), and ci robots which are able to commit to pristine branches (e.g. master). Because they all have “scm_commit” permission, but need different branch access rights.

    I know that in this case the “custom category” can handle such a setup, but with 20+ or 100+ or more repositories it gets really tiresome to setup custom access controls for each repo, especially when aware of the fact that a simple change of parent would solve it.

    I also know that, at least in Gerrit 2.6 coming with CTF 7.1, it is possible to push a “groups” and “project.config” file to each repo instead of manually changing access controls in the web gui, but still you would have to push those files to all your repos each time you change access control settings. Instead of changing it once in the parent project.

    So, please think about how you can support medium and large scale companies (in terms of number of repositories) to configure access controls for a standard CI/CD setup.

    Jonas Christensen
    Schneider Electric

    • February 25, 2014 at 1:34 am

      Hi Jonas,

      our mappings file does not support any references to roles as we wanted it to be applicable across TeamForge projects. I completely get your CI use case. Your proposed solution of pushing that config into refs/meta/config would make sense and I also agree with you that parent/child project hierarchies would help here (see my response above, it is in the road map).

      Independent of both options, here are some thoughts what you can do (independent of Gerrit 2.1/2.6):
      * you can create internal Gerrit groups and assign those to Gerrit projects/access rights
      * you can assign access rights to TeamForge user groups (like CI users)
      * when access rights change in TeamForge, we will not touch configurations for internal Gerrit groups or TeamForge user groups (independent of repo category selected)
      * internal Gerrit groups can include both TeamForge project roles as well as TeamForge project groups
      * internal Gerrit groups and TeamForg user groups can be assigned on the – All projects — level as well
      * both Gerrit 2.1 and 2.6 support exclusive ref spects (in Gerrit 2.6 there is a check box, in Gerrit 2.1 there is a – in front of the refspec).

      With that model, you could put your CI users in a TF user group or internal Gerrit group and grant them PHD+3 access to -refs/heads/master (exclusive push permissions only for CI)

      If you wanted to extend certain TF project roles with access to a secret branch, create an internal Gerrit group (secret), include the project roles in question and give them access to refs/heads/secret

      Last but not least, Eryk is going to publish a new blog post series very soon how to handle a variant of gitflow with very similar access restrictions as the one you just described. The idea here is that developers get View&Commit rights in TeamForge, integrators would get View&Commit+Delete/View and CI would get SCM Admin. With that approach, you can actually work with a user defined repo category.

  4. Jonas Christensen
    February 28, 2014 at 2:21 am

    Hi Johannes,

    Currently we are using TF user roles for Developer, Integrator, CI robot, CI admin with custom access controls. Using internal Gerrit groups would make access granting a bit less straight forward, I think.

    Anyway, the setup is manual with custom access controls, no matter if you use TF roles or TF groups, correct, or have I misunderstood some feature when using TF groups?

    The way to ease the access control maintenance is some usage of a parent. As you propose, a solution could be to use the 3 different source code permission categories, and create a user defined repo category. The restriction would be only 3 different roles though.

    I’m unsure exactly how it would work if you implement project hierarchy to determine repository parent in terms of access rights inheritance. The project I’m working in has a number of repositories, but there are no parent/child relationship, they are all on the same level. Or is it the “top level” TF project which needs to have a parent, and then the repositories in the child TF project(s) can inherit the access controls?


    • February 28, 2014 at 2:37 am

      >Anyway, the setup is manual with custom access controls, no matter if >you use TF roles or TF groups, correct, or have I misunderstood some feature when using TF groups?

      Manual in the sense of not completely controlled by TeamForge unless you push your additonal access rights in refs/meta/config during repo creation with a custom event handler:

      >The restriction would be only 3 different roles though.
      Well 5 “role types” are possible: no access, view access, commit&view, delete&view, scm admin

      >I’m unsure exactly how it would work if you implement project hierarchy to determine repository parent in terms of access rights
      Step one will be that all Git repositories within the same TeamForge project would get a new Gerrit parent project which is named after the TeamForge project they are in. You would not be able to commit anything but config changes into that parent project but can use it to manually set access rights (for certain internal and TF managed Gerrit groups) which will apply to all git repos of the same TF project.

      Step two would be, to have this parent Gerrit project also have a parent other than –All projects — if the TeamForge project in question had a TF parent project. With that approach you can define access patterns that inherit to all Git repos of any TF project with the same parent.

      We are currently spiking on step one (highest priorities for Q1 are to finally release our advanced Gerrit notification plugin (ability to get same messages as git-multi-mail sends out into TF forums) and the upgrade to Gerrit 2.7 though), it does not seem unlikely that we can have this one in early Q2.

  5. Jonas Christensen
    March 6, 2014 at 6:20 am

    Ok Johannes, seems your “step one” solution will do the trick, looking forward to giving it a spin ;o)


    • March 6, 2014 at 8:00 am

      If you already wanted to give it a spin now:

      * once our integration created a project, it will not try to change its parent project again
      * there is a Gerrit command to change parent projects yourself: and

      It will require Gerrit Administrator permissions though as selecting a different parent than –All Projects — (even at project creation time) is an operation which in our opinion requires more privileges than just having SCM Admin (as you could reparent a repo into an entire different part of the hierarchy and by that strip access rights away from other SCM Admins).

      Knowing that, you could already achieve what you want today, if you
      * create a Git repo in TeamForge with custom category and use this as an “umbrella Gerrit project”
      * reparent the Gerrit projects of your choice so that they can inherit permissions from there

      We tested that with our Gerrit 2.6.1 based integration and it worked as expected, don’t see any reason why it would not work with Gerrit 2.1.10

  6. Jonas Christensen
    March 7, 2014 at 3:33 am

    Hi Johannes,

    Well, now I’m confused …

    In my first blog post I ask if it is possible to “change parent to other than “– All Projects –””. And from your answer it seems that that is not possible.

    I have also asked our CTF contact here at Schneider Electric about if it was possible to change parent using “cmd set project parent”, but was told that that was not possible (from a CTF employee).

    So, a bit confused about you now stating that it is indeed possible to change the parent using “cmd set project parent” … but, great if it works, this has been my preferred solution all along ;o)


    • March 7, 2014 at 3:40 am

      Hi Jonas,

      my development team has tested what happens if you use that command with Gerrit 2.6.1 and could not spot any problems. We also think it will work with Gerrit 2.1.10 but have not tested this.
      From official support, you will only get statements regarding scenarios we officially qualified. This prevents unexperienced customers getting into situations where we cannot help them recover from it any more.

      That said, I think your knowledge of Gerrit is strong enough to test this approach in a sandbox project first and it works, apply to mission critical projects. If you want an official statement that we support parent/child hierarchies, you will have to wait at least until April this year (and this statemengt will only apply to the hierarchies we set up programaticcaly with Gerrit 2.7).

      Best, Johannes

  7. Jonas Christensen
    March 7, 2014 at 3:59 am

    Hi Johannes,

    Thanks for clarifying :)

    I will test “cmd set project parent” with our Gerrit 2.1.10, but as you also state, it should work. I just need to find out who is Gerrit Administrator ;o)

    And then I will look forward to getting the Gerrit 2.7 CTF integration and test how the parent handling is implemented in details.


    • October 6, 2014 at 8:06 am

      Hi Jonas,

      happy to inform you that we now implemented nested project hierarchies, IOW the full TF project hierarchy reflects in Gerrit. This feature is available right now, starting to work with our TeamForge-Git-Integration version 8.1.2. As a nice additional feature, it finally supports TF site admin capabilities too.

      Best, Johannes

      • October 6, 2014 at 8:14 am

        Sorry, meant to say version 8.2.1 (based on Gerrit 2.8)

        • Jonas Christensen
          October 7, 2014 at 2:12 am

          Hi Johannes,

          We have TF ver. and Gerrit ver. 2.7-137-g26b864f currently, and we do have nested project hierarchies, meaning that I have a Gerrit project called “TF-Projects/proj1207″ where I set all generic access controls, and each of my own created Gerrit projects / repos by default inherits access controls from “TF-Projects/proj1207″, no longer from “All-Projects”.

          Or is this not what you meant?

          Now I just need CNSC-165852 fixed ;o)


          • October 7, 2014 at 2:19 am

            Hi Jonas,

            you’re right, you already have one hierarchy level in your current Gerrit integration. Starting from 8.2.1, if a TF project has a parent TF project, this hierarchy step is refelcted too (so you have a deeper, nested hierarchy). By this, you could now define permissions, that inherit down to all Git repos of a certain group of TF projects (the children of a TF parent project), so you got even more flexibility.

            Best, Johannes

  8. veer
    April 9, 2014 at 12:23 pm


    Wanted to check if it is possible to set a role by name lets say as tester, and set reference name as /refs/heads/test*. Basically intent is to create a role who can create branches and push to TF repo, if the branch name is test1 or test2 etc – without having to create role per branch.

    So, what I understand is we can create role and allow user to push to specific branch, can we generalize that by using regular expressions. If not, any other way to give non admin users permissions to create and push new branches to TF repo, without involvement of the admin?


    • April 10, 2014 at 5:34 am

      This is definitely possible, see the reference to the custom repo category in this post or have a look at Eryk’s more recent Gerrit 2.6 post.

    • Jonas Christensen
      April 10, 2014 at 5:43 am

      Hi Veer,

      Yes, by using “Custom Repository Category” you can setup a reference as refs/heads/test/* (this I know works, I haven’t tested refs/heads/test*).

      And then the role Tester just needs Create Reference, Push and Push Merge (if you allow merge commits) on that reference. This will allow them to push directly without review.

      And if you would like to enable your Tester’s to use review for their commits, add a reference refs/for/refs/heads/test/* with Push and Push Merge for them.

      Jonas Christensen (Not CollabNet employee ;o)

  9. Eryk Szymanski
    April 11, 2014 at 2:24 am


    that’s correct. The way to go is to create refs/heads/test/*. Actually it will not work with refs/heads/test* (so you need a ‘/’ before the ‘*’).

    You may also consider to add a personal namespace for each user. This is done by using the special ${username} keyword: refs/heads/test/${username}/*. If you want to do that, consider to give push force permission on that refs so the users can clean-up their own branches.

    • Veer
      April 14, 2014 at 11:08 am

      Works. Thanks all for the reply, and thanks Eryk for this post.

  10. Satish
    April 21, 2014 at 1:04 am

    Thanks for these detailed analysis…
    would it be possible to change the access level for a specific branch in a project from the command line ?

    • April 22, 2014 at 2:13 am

      Starting from Gerrit 2.6 (which corresponds to TeamForge Git Integration versions >= 8.0.0) Gerrit access rights are configured in two files which are part of the special “branch” refs/meta/config.
      You can clone this ref, change the access rights (by modifying the files project.config and groups), commit and push back (all possible using the Git command line client). More information on the specific format can be found on

      Best, Johannes

      • germain
        May 19, 2014 at 1:26 am

        Do you know when is planed to support of GERRIT 2.6.x and the capability to modify directly refs/meta/config branch for custom based process ?

  11. May 19, 2014 at 11:53 pm

    We already support Gerrit 2.7 with TeamForge 7.1, have a look at the more recent blogs on and our online help on

    Best, Johannes

Leave a Reply

Your email address will not be published. Required fields are marked *