Branches vs. PR's vs. Option C

Question for the folks who:

  1. Are using git to version control their robot software, AND
  2. Have a team of more than one software developer, AND
  3. Are using github/gitlab/similar for hosting code online.

What does your workflow look like for coordinating software changes between developers, and merging those changes back together?

Traditionally I hear two camps: One involves the Github constructs of forking the repo then PR’ing specific changes back. Another involves adding permissions to the main repo for everyone, having folks push development branches for their own work, and eventually working together to execute merges back to a special “integration” or “mainline” branch.

Does your team do either of these? Or something else?

And, most importantly: why?

166 used to use forks, but we rapidly ran into issues with students needing to pick up each others’ work, and dealing with the hassle of maintaining and updating pull requests from one fork, by another person. Last year or so we switched to having everyone make feature branches in the main repository, and locked down the master branch (which we keep meaning to rename to main but we have so many clones of it by this point that it’ll be annoying) so that only the mentors and the software lead are able to merge to it - and even then only when TravisCI passes and there’s an approval review and no reject reviews. It may be too strict at times, we’re still working on adjusting the process, but it’s working alright so far.


Our workflow has always been a branch for each added feature, even when there is only one active developer on the team. We’ve found that branches are fine for our team as we have a max of three devs on the robot code at once, and our project management system means only one dev is working on a specific part unless there is a “formal” handover. For instance, in our 2020 code, there is a branch for drivetrain development, superstructure development (climber and intake), and shooter development. Once all of these features are mature enough, they are merged into main and then main is what is actually deployed onto the robot (save from testing on our testbeds)

1 Like

Depnds a lot on your coding setup, if everyone is working remotely it would be more challenging for sure. In 2019 and 2020, our programming team was 2 people and they used our teams programming laptop. We ended up making a “team-coder” github account and used that to commit from the laptop to main. We used a couple branches for experimental changes but not for full features.

We had tried full issue->branch->pr->merge pipeline before but it was too much hassle for such a small team

1 Like

Feature branches (hopefully not long lived, or if so, occasionally squashed and rebased off master). Code review using github’s standard PR process. Squash and merge once all the review issues are addressed.

We didn’t change permissions on master - we trust programming lead students to do the right thing. Worst case we can just git revert and heckle them mercilessly until the next fire breaks out (MTBF ~ 1 day or less during build season).

So yeah, master is our integration branch. This isn’t life-saving medical equipment, just a prototype robot. If something is broken, we’ll fix and merge it from the next branch.

Biggest issue we had was having branches live too long. For example, a “write all of the low level control code for 8 weeks” branch, rather than doing much smaller pieces. Learned our lesson, branches are more focused and hopefully shorter lived. Totally new features might get big, but hopefully they’re also relatively self contained so bugs there will be self contained … so long as the rest of the code still builds and runs it is no worse than not having the new feature. And we try to keep fixes to just the fix, plus the occasional “while I was in there” minor cleanup as well. So for a typical build season, maybe 100-150 merged PRs, plus the random dev branch that never panned out.

Programming team of ~10-15 each year, so lots of parallel development. Our code is kinda-modular enough, which helps prevent major merge conflicts most of the time.


We use a single repo with feature branches, with subsequent PRs. We protect the main branch so that it requires at least 1 review.

Using separate forked repos seems like way too much work, unnecessarily hard for maintenance, and confusing for rookies.

1 Like

Forks are a terrible idea. If you can’t trust your programmers with access to the main repo, then they probably need more git training.

1 Like

And branch protection solves most of that for small development teams. Forks are mainly needed for large “public” projects when you can have contributions coming from a wider community and you want to limit feature branch churn on the main repo (that everyone is forking). If you have a relatively small and constrained group of contributors, feature branches and a protected main branch is definitely the right way to go.


If you have multiple people working on the same feature (like we just did with our trajectories), do you have each person create a feature branch with an identifier (like trajectoryJd or or something; I feel like I have seen some teams do this)? Or, do you do something else?

1 Like

Here’s how we do things at my day job. We use bitbucket instead of github, but they are similar.
Bitbucket starts with branches develop and master.
Developers clone develop to their machine
Developers make a branch (named for the JIRA that has the feature request or bug report).
When the developer is done they commit their branch locally and then push it up to bitbucket and then make a pull request (theirBranch -> develop) on Bitbucket.
After the pull request is approved, it is merged on Bitbucket.
Typically then developers will pull develop back down to their machine.
From time to time somebody makes a (develop->master) pull request on bitbucket.
When it is approved, it can be merged.
Probably out of scope for FRC, but we also use Jenkins and whenever something is merged into develop, it is automatically built and installed on the develop server.
(we manually choose when to install master into prod machines via Jenkins).


We don’t have multiple developers (We do but we really only use 1 programming laptop), but when we make major changes (for example, adding in pathfinder), we create a new branch and merge it when necessary

We don’t do testing. We don’t have enough time to do regular robot programming, let alone testing. Testing is often done on the robot.

Anyways Master branch gets cloned to a new branch, then new branch gets developed on, then merged back into master if necessary

Simple setup. Same with what I do at work, except we use bitbucket

1 Like

This is a little rare for us, but does happen. We use one branch, otherwise it would be too confusing. We try to have the students do “team programming” in general, and especially when working on a single feature.

1 Like

Thanks. It is common for us because of two use cases.

  1. In a lockdown, people are working together on a project in different places. This happened with each of the NEFirst Romi competitions thus far. Currently, we are focussing on the programming, not the versioning, but it is time to change that :smiley:

  2. Out of a lockdown, we have people who work on a project together, but may not come to the same meeting. Member one is here day one, and member two is here day two. They may be using the same computer, or they may not be.

1 Like

Yes, that is true for us. This year, in most cases, we have been getting together on Zoom for the group programming, with one student being the “scribe”. Not sure it really gets everyone involved, but at least a few more students have a view of what is going on and a little of why.


3468’s strategy is to just use branches and branch permissions to protect from happy accidents. More detail, 3468 will have our primary branch main,master, ect. Then a staging branch develop, integration, ect. and then finally our feature branches.

Feature branches are where the development happens, but 95% of the time, we won’t have access to a robot to test them on for quite a while, if we’re lucky we’ll have a test-bed available to validate some of the more basic changes, but most of the time they can’t really be properly tested individually… So when the student(s) working on a feature believe it is done, I will walk through the change with them, do some deep static analysis and if I believe it looks good and the student(s) think it looks good, I will merge it to the staging branch.

Code in the staging branch however will not be merged to the primary branch until it has been tested on an actual robot. In some cases we won’t merge to the primary branch until right before or even right after a competition depending on how everything else is going in a particular season…

So the primary branch will be a default generated project for most of the season, but once it contains actual code, that code should always be known working code barring any later bugs discovered.