I remember implementing git in my team. I think it was more than 6 years ago. At that time, A successful git branching model by Vincent Driessen was required reading if you wanted to learn how to work with git effectively. Since then, I've been following the "Git Flow" style. But, this past year, I've been influenced by many developers from the community, and started using git in different ways depending on the projects I was working on.
Before getting into the different branching styles, it's important to remember that, although many git clients treat slashes ("/") as a directory separator, there is no such thing as folders or directories in the git specification. You will see this implemented in many UI clients, but I never found it on console clients, or on websites like Github or GitLab.
That being said, Let's explore some ways of organizing branches, so you don't get lost in a sea of code.
Gitflow
Although Gitflow doesn't mention branch folders, many devs use "Feature branches", "Hotfix branches" and "Release branches" and create folders accordingly.
So basically, a GitFlow organization would have these three folders:
- feature[s]
- hotfix[es]/fixes
- release[s]
As there is no public document talking about this, I've seen some working copies using those folders in plural and others in singular.
Gitflow with steroids
I found myself adding two more folders to my Gitflow repos:
- Docs: For branches related to markdown or release documents.
- Task: For branches which are neither features nor fixes. Such as, clean up scripts or refactors.
BPMP (Branch-Push-Merge-Prune)
I’ve seen this a lot in many projects. The branch-push-merge-prune is the anti-folder method. I'm not saying that chaos is a way of organizing branches. People using this method like to have their working copy clean. They would just branch, push, create a pull request and then delete the branch (manually or via git fetch prune) as soon as the PR is merged.
Module-based
I found myself using what I call a "module-based" branching model on a big project where I got quite lost in a sea of features and fixes. So I started to create branches based on its modules.
You could mix Gitflow with this module-based approach, something like "backoffice/billing/fixes/billing-values", but that may be too much.
Version-based
I first saw Meir using this approach and I loved it. It’s great for projects like Puppeteer-sharp where the roadmap is clear.
In a version-based repo you create each branch inside a "vX.X" folder. What is cool about this is that it’s time-based, so it's easier to find branches and also it's super easy to delete old versions with this simple git command:
git branch | grep -e "vX.X/" | xargs git branch -D
Again, this could be mixed with Gitflow folders, but...
Ticket-based
If tickets numbers (tickets, issues or whatever you call them) are part of your team's language using a ticket-based system could be a perfect fit.
You could use a folder, such as "tickets/242" or "issues/242", or just simply call it "242".
Emoji-based
If none of these systems is for you, you can follow Nick's idea and implement an Emoji-based system :)
Final words
Two final thoughts to close this post. First, if you work on a team where you normally checkout each other branches, e.g. for local testing, I'd recommend you share the style with your team.
And finally, clean your working copy frequently. This will help you find your branches quickly, and also speed up your local repo.
Don't stop coding!
Originally posted on harkoded.com
Top comments (26)
I do a lot of ticket based naming but also like to tack on a little blurb about the ticket name so I can look at the branch and know right away which ticket. So something like "T-123/add-new-button". Then when you are in your git bash, and run git branch you can figure out your branches a bit better. I do need to get better at remembering to delete stale local and remote branches.
Oof, ticket-based prefixes virtually eliminates the benefit of tab completion! Do you memorize ticket numbers?
git co 9<tab>
is not going to give me anything useful, nor will97<tab>
or974<tab>
. With ticket based prefixes you have to type every digit of the ticket number, down to probably the one's place. Given that most companies are probably in the thousands or more of tickets, you're typing at least 4 characters before you can even hope to get a completion match. I get cranky if I have to type more than 2 characters to get a completion match.I could see it getting a little tricky. I usually do a git branch so I can see my local branches, and it makes it a bit better for typing it out, especially with the little quick summary blurb that is also in the branch naming. I do love my tab completion too!
I do the same. Usually, in a professional setting, you're working with something like JIRA so it makes sense to prefix a branch with a ticket (as a way to say "this branch is related to this story") and then a short human-readable description of the feature.
As a general rule of thumb, if your brain has to pause and make sense of a branch name, it's too complex.
That's cool, I like it.
Nice post! Even though Michael Larson did not elaborate the answer enough, he has a point :)
Papers and other publications like DevOps show that the most effective way to organize code branches is trunk based development.
Team productivity, release time even test coverage have a beneficial impact when using this strategy.
You might want to check out the Continuos delivery book and the devops report.
In case what I m saying is not new to you, then a little mention in the article would make it even nicer and would give people the opportunity to dig into an alternative approach.
Thanks for sharing!
I have done both, Trunk Based Development is the way to go for teams with high code velocity. Feature branches can be manageable for very small teams. But it's not scalable.
We’ve also used both for a team of 6 and Feature branches often end in merge conflicts especially at the end of a sprint. Although you can build it, it usually prevents you deploying and system testing your code on a production like environment. Quick feedback is important. So we commit on develop branch and only follow git flow for releases.
Yeah I do commits on dev branch as well. I always pull from dev to prevent conflicts, but you don't always win but it's not a last minute scramble to get the code on the feature if too close on the files working.
Right. Because the Linux kernel doesn't scale. TBD is based on pseudo science, usually coming from the agile dogma proponents. I'll show you peer reviewed papers on the benefits of smoking too.
I can't really speak to how Linux project works or how they organize their code. What I can tell you is that there has been research done that shows that TBD allows an organization to scale as their code velocity increases and the number of developers increases too. Great book that has results from a multi year study said this:
Forsgren PhD, Nicole. Accelerate: The Science of Lean Software and DevOps: Building and Scaling High Performing Technology Organizations (Kindle Locations 971-985). IT Revolution Press. Kindle Edition.
I can also attest to this from personal experience working on a large volunteer project with lots of developers, before starting TBD merging feature branches was stressful event and took hours to complete. We went from quarterly releases to weekly after we switched to TBD and other changes that where made to support that. We could not do that if we still had those long lived feature branches, and we no longer have to deal with the pain of merging large branches of code.
Adam, if you have any research that shows the opposite I would be certainly interested in reading it. At the end of the day its up to you to decide how you want to organize your projects. I know there is a time places for branches, but the trouble I have seen is the longer these branches live, the more pain they cause. There is a tipping point where any benefit to placing code in a feature branch is out weighed by pain it causes the team when they need to integrate that code back into the main line.
Three words: trunk based development.
GitFlow by Driessen is indeed a must-read when you want to design your git branching strategy, but in past years two more articles are added to that:
endoflineblog.com/gitflow-consider...
endoflineblog.com/oneflow-a-git-br...
I highly recommend reading all three before approaching the whiteboard.
Cheers!
I think the number of screenshots of GUI tooling is telling with regards to the various prefix naming schemes. Primarily because branch name prefixes are hostile to CLI users due to the fact the prefixes hamper tab completion.
For each and every "directory" level in the prefix, you've added 2 extra characters minimum that are must be typed before even potentially getting a completion match. Given the sheer number of times that branch names are typed out, I find it astonishing why anyone would increase the friction in that area.
I optimize my branch names to actually facilitate my development workflow, which means making it more efficient to switch, merge, rebase or otherwise use the branch names. Branch names are the interface for how we work with git. They are not a metadata storage system.
I too used to think that adding all this metadata to my branch names was valuable. But after seeing how much friction it actually caused in my day to day (nay, minute to minute) workflow, I had to think more critically about the value such a scheme was actually providing. And unfortunately, besides the slightly-OCD "good, clean, organized" feeling, the value list came up pretty short. As in, I can't think of any solid value it actually provides.
You're working on a bugfix, that includes a tiny refactor. So it's not a fix/ or refactor/. Your feature branch better include documentation updates along with it, so it's not purely feature/ or docs/. And even if those prefixes were accurate, what decision do they help with? What actionable information do they carry? None, in my experience. Only added frustration at the extra characters I have to type every single time I type a branch name in git (hundreds of times a day).
I've never had a way to organize my git branches. 'Gitflow with steroids' seems a good idea to start. Thanks!
We use a mix of git flow with ticket based. So each feature corresponds to a ticket and we have a naming convention like : [us|b|t]-[number]-[initials] where:
us = user story
b = bug
t = task
we end up with branches like: us-01234-ye, b-65432-jq and so one.
at the end of each one we just do a feature finish.
I've always preferred BPMP because I've seen projects where feature branches live an eternity.
Also, depending on the project and management tool, a combo between ticket and BPMP is fine as well.
I like keeping things in order and BPMP let's me do that in git branches.
What does „BPMP“ stands for?
Ours is ticket based but I also tie it to bugfixes, features, release(through tagging and a dev and staging branch respectively) and master being prod.
I like these folders but what if you are not using gitflow? My guitgui splits it with the prefixes bugfix/, features/ which is pulled from the ticketing system.
I really like the idea of the documentation being in there and just tasks being seeing as tasks (I can do this now actually - neat idea).
I do love the logical splitting of modules. If you have a current repo with the folder setup I've mentioned, how do you translate it with an old repo or current? But I'm also worried about it conflicting with my current setup but maybe there is a way to mix? I think there is. This has given me some really good things to think about.
Also how to you get gitflow on a current repo?
Thank you for this awesome post. :)
I've also seen author initials used to prefix the branch.
John Smith work on ticket FOO-42 -> js/FOO-42-doing-cool-stuff
Cannot say it's a way to go, but it has some pros
Git already has a mechanism to prefix author initials... remotes. If you need to segment branches by author, I would humbly submit that you ought to be using forks.