DEV Community

Adrián Norte
Adrián Norte

Posted on

why branching on git is wrong

Lots of people often code using feature branching on git to avoid the hassle of conflicts while doing pull and/or to avoid pushing incomplete features that would break the system for all the team.

I find these reasons to be baseless and some even harmful to the development cicle. Trying to develop in your little temporal bubble without being distracted by the rest of your team it's a bad idea, imagine the following:

A team of five people have to do a painting of a big landscape, so they split the canvas in five pieces and then each of them paints their part without even looking at what their partners are doing and in two weeks they put all the five pieces together to deliver the product. What do you expect will happen? of course the painting will be a mess with miss aligned items on it that will need to be redrawn at the last minute pulling an all nighter on the worst case. Sounds familiar?

How can we work on a single branch without breaking stuff and without continuous conflict?

First the conflict part: Communication is key, daily meetings are there for a reason and should be used to smooth cooperation between developers working at the same classes.

Now, the scariest part: How to commit half baked features without breaking stuff? or even more, how to commit a new feature that we aren't sure is working correctly? Well, one of the best things about everyone working at the same branch is that if something breaks it will be noticed quickly and fixed at an early stage and therefore less painful process.

For the part of committing without breaking the system for everyone there is a very good technique called "feature toggling". Basically what you do is put an if like this:

if (useNewLogic) {
    awesomeNewFeatureEntryPoint();
} else {
    legacyEntryPoint();
}
Enter fullscreen mode Exit fullscreen mode

This allows to run the new code when you want and where you want without risking all the environments and such.

This way of working also benefits of the fact that because everyone is working at the same place if your new feature conflicts with some change of class contract you can fix it quickly, it means that you are doing continuous integration.

One way I have found in my personal experience that people that comes used to work with branches feels more comfortable to do the switch is to have two branches, for example: develop and master. With the only way to put things on master is via a pull request.

I would love to read your opinions of this matter on the comments.

Top comments (179)

Collapse
 
nezteb profile image
Noah Betzen • Edited

I disagree with most of this article, but respect that it works for you.

Any project I've ever worked on where multiple people are commiting to the same generic "development" branch results in lots of merge conflicts unless people are super careful to always pull the latest changes and merge master often. It's also difficult for audit purposes in the future because many features will be added simultaneously on every PR merge.

If anyone decides to try this, I highly recommend that you keep a changelog and follow some sort of commit message guideline.

In my experience, proper use of Git Flow, CI/CD tools, PR status checks, and merge conflict resolution as needed should take care of most of the issues you have with feature branching.

Some useful Git tooling:

Collapse
 
gypsydave5 profile image
David Wickes

So my team practices continuous delivery / continuous deployment. The idea here is that we're always pushing to master and deploying to live, leaning on our tests to ensure integration. There are other ways, but it's all essentially 'trunk based development' and is definitely opposed to 'git workflows' á la Gitflow.

We're not large, and we're 'colocated' (management speak for 'sit together') so that might be a factor.

A caveat: I am definitely not an expert at any of this.

Any project I've ever worked on where multiple people are commiting to the same generic "development" branch results in lots of merge conflicts unless people are super careful to always pull the latest changes and merge master often.

You don't need to be 'super' careful. You just need to pull -r from upstream on a very regular basis. I mean, every few minutes. The first point of integration of your code is your machine, the first tests of integration are on your machine. You hit a merge conflict sometimes - it inspires you to pull more often.

It's also difficult for audit purposes in the future because many features will be added simultaneously on every PR merge.

There are no PRs. There are no merges. There are only commits, to master, on your machine, and rebased pulls.

Everything you push will go live on a continuous delivery pipeline. So you cannot be lazy - you must write automated tests to document the features you are implementing.

The key driver here is continuous delivery - no 'releases', no 'big bang deployments'. Just the regular (every 15 minutes usually) integration and deployment of code to live.

I do agree the original author is saying some odd stuff, like:

Now, the scariest part: How to commit half baked features without breaking stuff? or even more, how to commit a new feature that we aren't sure is working correctly?

Just don't deploy broken code. But, conversely, if your code isn't breaking the tests of your other features - then nothing is broken. Feel free to deploy.

A corollary to this: break down your 'features' into small, valuable, deliverable parts. Stop swallowing the elephant whole; use a knife and fork.

Feature flags are a good idea - but only to separate deployment from delivery (i.e. deploy code but prevent its 'delivery' to the user in live). But they should be extremely short lived and probably live in the interface layer. They should not be quite unusual.

Take a look at these just to make sure I'm not mad...

and also

Maybe I should write some of this stuff up in a post if there's interest?

Collapse
 
f666uct profile image
Gray Hattus

Not all heros wear capes. Some have the power to merge code. Fully agree

Collapse
 
droidmonkey profile image
Jonathan White • Edited

I really cannot agree with this approach at all. It is dangerous to suggest this for new programmers looking for guidance. This defies the whole point of Git which is to decentralize development so that only working, tested code gets put on the main line. Adding logic switches creates complexity, untested pathways (even only 4 logic switches is 24 possible execution pathways), and requires cleanup work and refactoring once completed and agreed upon by the team.

If you want to work like this proposal suggests, just use SVN. However, reflect on the fact that there is no such thing as svnhub for a reason.

Collapse
 
anortef profile image
Adrián Norte

This defies the whole point of Git which is to decentralize development so that only working, tested code gets put on the main line. Adding logic switches creates complexity, untested pathways (even only 4 logic switches is 24 possible execution pathways), and requires cleanup work and refactoring once completed and agreed upon by the team.

If you have a good CI system (it's 2018 we all should have one) nothing untested nor unclean code enters the repo.

Collapse
 
droidmonkey profile image
Jonathan White

I am not going to try to convince you against your thesis. However, I believe you have missed the point of Git (and other decentralized version control tools). Branches are not meant to be lived in for ever, in fact we enforce strict rebasing or develop merge commits into branches throughout their lifecycle. The CI is run on each branch, each mainline, and each bugfix line for every commit. I encourage you to check out my project to see how branching can be very successful: github.com/keepassxreboot/keepassxc

The develop line stays absolutely pristine such that we can post "nightly" snapshots without worry. Nothing is merged in until it passes the branch CI and a merge CI.

Thread Thread
 
szymach profile image
Piotr Szymaszek

I'd say he does understand git, but simply chooses to use it differently. In my company we do not use feature branches, unless absolutely necessary, which would mean a big rewrite of a considerable part of the system, where you just can't roll out changes progressively. It happened like 3-4 times in my 3 years of working here.

The issue he brought up with feature branches, where people work in separation from each other, is pretty substantial (not unsolvable, but still). Imagine you need something from another feature branch, but it will not be merged until a couple of days, because there something else needs finishing on that branch. And also, that required thing is based on lots of other changes made on that specific branch, so you can't just cherrypick it. Now what, rebase on a partially finished feature branch? Manually copy paste the code? Now, what if you need things from more than one feature branch?

In my experience, it is best to simply compartmentalize changes in a way, where a PR to master branch contains a small subset of changes that does not break anything. That way the changes are incorporated by the rest of the team and they can provide you with an actual feedback and vice versa. I know that is not always possible, but I would advocate for this approach in most cases where it is applicable.

Thread Thread
 
joineral32 profile image
Alec Joiner

I'd say he does understand git, but simply chooses to use it differently.

I cannot agree more with the notion that there are many 'correct' ways to use git.

Imagine you need something from another feature branch, but it will not be merged until a couple of days, because there something else needs finishing on that branch. And also, that required thing is based on lots of other changes made on that specific branch, so you can't just cherrypick it. Now what, rebase on a partially finished feature branch? Manually copy paste the code? Now, what if you need things from more than one feature branch?

In the scenario you're talking about, where Developer A needs some code from Developer B, but that code has dependencies on unfinished code that is not ready to be incorporated with master, I would argue that having that code on master instead does not improve the situation. If the unfinished code were on master, it would imply one of two things; Master is broken, or you're using feature flags. If you're using feature flags, you would have been able to cherry-pick the necessary code onto a separate branch and merge to master.

I would argue, however, that it's the development process that matters here, not the git workflow. If you're consistently finding that you need work from other features in order to complete your features, there are probably other things you should consider: Are your features broken down enough? It could be the case that the work needed by both features should have been done and released in a previous task, as a prerequisite for the two tasks that need it.

The team I'm working on uses feature branches, and also deploys to production multiple times a day. There are other teams who do not use feature branches, but still have many of the issues feature branches are suggested to create. At the end of the day, I think most of the problems brought up in this article and in this comment section are not caused by feature branches.

Thread Thread
 
droidmonkey profile image
Jonathan White

This is a great point, thank you.

Thread Thread
 
megawattz profile image
Walt Howard

Have your developers commit their unfinished branches to the repo (but not master), or use forks, then you have access to their code. Easy. Seriously, I push my branch to remote repo often because there's almost nothing in life worse than losing code (except maybe root canal). So if I screw up my personal work computer, delete something or the hard disk goes bad, I have my latest work safe on a remote repo.

Collapse
 
joineral32 profile image
Alec Joiner

I'm not sure what kind of CI setup you're using (maybe some kind of server hook?), but every CI system I've used (Travis, GitLab, Jenkins) would require code to enter the repo in order for the CI process to run. The CI process isn't going to prevent bad code from entering master; you just end up with a red build on master. Unless of course you use feature branches and use your CI build outcome as a quality gate. But you're advocating the opposite.

Collapse
 
carleeto profile image
carleeto

Sure. How does a feature toggle work when a feature requires a change to the build process?

Do you feature toggle the build instructions too?

Thread Thread
 
anortef profile image
Adrián Norte

Build steps:

  • execute unit tests.
  • execute sonarqube analysis and coverage.
  • deploy it on a testing environment.
  • execute integration tests.
  • execute system tests.

If all green then build the artifacts and ship it.

What feature can require to change that?

Thread Thread
 
maurosanchezd profile image
Mauricio Sánchez

What if something is red and I need to ship a bugfix?

Thread Thread
 
atebmt profile image
Mike Thomas

If you use trunk based development and have a decent continuous deployment process, you don't ship a bugfix. You rollback production to the previous release version, revert changes in git, then add a regression test that fails due to the bug, fix the bug and then commit.

Thread Thread
 
maurosanchezd profile image
Mauricio Sánchez

My bug is not in the latest release so "You rollback production to the previous release version, revert changes in git" won't help.

"Fix the bug and then commit" is exactly what I was referring to as ship a bugfix.

The problem here is not how to ship a bugfix or how to revert/rollback changes. The problem here is what if I need to send code to production if the trunk is unstable.

Thread Thread
 
megawattz profile image
Walt Howard

In my environment a "bug" is not always like that. I can be something that has been there for awhile so you cannot roll back. Also the bug may be due to something missing that should be there. The bug may be related to an essential feature that you cannot just roll back entirely. You can't roll that back. Plus you also have environmental issues like a new version of a browser ships and you have to deal with something that a rollback cannot fix.

HOWEVER, if you discover a bug close to when that code was released, then rollback and breathe a sigh of relief, and fix it un-rushed.

Collapse
 
lazzu profile image
Lasse

I agree that using branches can be used to develop your features in a bubble. But I think that is a great and awesome feature of git. Perhaps the most important one. You can focus on your stuff in your little bubble, and after you think you're done you just rebase to the develop branch to get all the latest stuff in, and then fix whatever broke.

After your stuff works again, you do the rebase again and repeat this until there is nothing to fix, and then you make the pull request and let others review and then approve it. I can not see how this is a bad thing. Also we at our team are not making pull requests from half-baked stuff anyway. And we rebase often, multiple times a day, which keeps the codebase fresh and prevents the large hassle of fixing the code after it's "done". There are no excuses to not do rebasing multiple times a day, and we have integrated it seamlessly in our workflow.

Do small commits, rebase after each one. That's a recipe to success instead of having to fear large conflict resolving when you're done with the feature.

Just my two cents.

Collapse
 
anortef profile image
Adrián Norte

After your stuff works again, you do the rebase again and repeat this until there is nothing to fix, and then you make the pull request and let others review and then approve it. I can not see how this is a bad thing.

Then you realize is 4am and all of you are still on the office because two guys on their bubble made architectural decisions that impacted each other because they forgot to rebase frequently and now all of you need to code a third set of classes to handle the communication between those two subsystems.

No thanks I don't want to return to those nightmares.

Collapse
 
lazzu profile image
Lasse

Sounds a lot like there is a problem in communication and planning. This is not because of git or branching.

Thread Thread
 
anortef profile image
Adrián Norte

Nothing is because git or branching, those are just tools what I like about not branching is that it doesn't requiere for the developer to be systematic and remember to do this and that.

Thread Thread
 
carleeto profile image
carleeto

If the developer isn't going to be systematic, how well do you think the product is going to work?

Thread Thread
 
anortef profile image
Adrián Norte

Well enough if you have a well configured CI server and QA processes.

Thread Thread
 
peoplearmy009 profile image
Peopelearmy009

I think this is more of a band aid approach which will eventually lead to further problems. If the issue is communication then you should fix that instead. Committing directly to development doesn't mean you resolve the issue of two individuals who decided to implement their own architecture. It just means if you weren't communicating then you get to see it sooner when you pull their recent commits but the issue still exists. It's just now it's been committed to the main dev branch.

Thread Thread
 
anortef profile image
Adrián Norte • Edited

and you fix it when is still a minor issue instead of a fully developed feature with, in the worst case, several days of work on it.

Communication problem are unavoidable or so says my experience.

Thread Thread
 
lazzu profile image
Lasse • Edited

CI is not a fix for bad planning and bad code. Fix the communication and planning and you end up with surprisingly good results. CI exists to help with quality, but the quality must start from the planning. CI does not help with maintainability and performance. Maintainability and performance directly affects to upkeep costs of the project.

I think you need to read a book called The Clean Coder. And The Phoenix Project while you're at it.

Thread Thread
 
peoplearmy009 profile image
Peopelearmy009 • Edited

"and you fix it when is still a minor issue instead of a fully developed feature with, in the worst case, several days of work on it."

This again is a communication issue. Poor architectural design or not following implementation guidelines will not be resolved by checking in directly to a dev branch vs having a feature branch. It actually results in forced roll backs because things are being directly checked in to the same branch as everyone else. Just because they checked in code directly into the dev branch does not mean they didn't implement something incorrectly and didn't spend several days doing it.
Proper use of PRs for code reviews and communicating implementation with the team will help alleviate this issue.

Thread Thread
 
majohmo profile image
Marty X

There are different projects with different people and different needs. For my research project, where most of developers are non-professionals and do not follow all the rules (and cannot be forced), we use only single branch. It may sound crazy and really counter-intuitive, but it works best. People commit small and often, mistakes and bad code get quickly noticed. Everything is exposed to others and not hiding in their own branches. We don’t even have resources to do much code reviews. But main branch is heavily tested and we use CI. Now, all the features are in the maim branch and work together. Earlier (with cvs, svn and git) we ended up having dozens of branches living on their own since many people never cared pushing them to master. Or if they did, they ended up into integration hell - while sorting the merge problems somebody else pushed his 3 months work to master. Yes, we have a communication problem since the project is very loose. Now, we have always a working version on single remote branch (except occasional hickups between pushes and finished tests). Branching works well only when it is tightly coordinated. Of course, people still can have local branches.
Our “project” is quite special, what I want to say that not all projects are the same.

Thread Thread
 
peoplearmy009 profile image
Peopelearmy009

I think just because some are non-professionals (I assume they want to someday be one) it doesn't constitute bad practices. I think it's important to teach good practices so that they can use good practices moving forward. I also disagree that branching only works when things are tightly coordinated. I think when everyone is on the same branch coordination becomes even more important because you are on the same branch. Again working on the same branch will not prevent someone from pushing in 3 months worth of work.

Thread Thread
 
majohmo profile image
Marty X

You are right, it does not prevent. But most people do follow the commit small and often principle. The important thing is that code gets as early visibility as possible and it is not hiding anywhere. In a loose and distributed team, the early pushes serve as an important way of communication - hey, my name is N.N. and I am working on this feature. Often, others step in and propose a better way to do it. In separate feature branch, it often happened that a guy worked months on conflicting/duplicate or badly implemented feature. Then senior developers noticed the problem too late. Then we were left with 2 bad options, accept bad merge to main or loose months of work. In both case, we have at least one angry and frustrated developer... Although we try to force people (esp. the newbies) to communicate their plans in Jira before they do single line of code. Another major problem was that earlier certain branches started to live their own lives, causing serious fragmentation of the code base.

Thread Thread
 
peoplearmy009 profile image
Peopelearmy009

I understand the importance of code visibility and this can easily be done with feature branches via a pull request that does not get completed until code is reviewed and accepted. Direct commits and push to development does not fix issues of poorly implemented code. A developer can easily lose months of work because they committed to their local development branch that tracks origin and then push all their work once. The issue here is that you now are faced with an issue where that code is now in development and you have no chance to deny or approve it. This results in higher need to roll back commits on your development branch as opposed to only accepting code that meets requirements.

Thread Thread
 
megawattz profile image
Walt Howard • Edited

You have to prevent people from committing to master willy-nilly. Either make master a protected branch and require the tech lead to approve any merges, or have an automated regression test that runs before merging to master. At least make sure it compiles, or runs even a small "smoke test" (for non-compiled languages)

If a problem comes up, the person who caused the problem has to fix it, and it hasn't polluted the working master. The simplicity of that is probably too much for some people.

Collapse
 
gitaaron profile image
Aaron Surty

Another way to put this is avoiding feature branches enables a team to achieve better continuous integration. Its related to continuous delivery and continuous deployment but those are downstream benefits to achieving better continuous integration.

A team can use feature branches and still achieve a high level of continuous integration, but it requires more discipline.

Reading this discussion, I think I have concluded that there are a lot of pain points for a team to encounter when switching from feature branches to trunk based development. However, I think I would argue that those pain points already exist and just aren't as apparent when using feature branches.

Collapse
 
vitalcog profile image
Chad Windham

I think something to consider for all the nay-sayers... The author sounds like he has working experience on teams making branches and on teams without branches. He also claims that having a workflow that doesn't involve branching has aided in communication and healthy coding practices. Most of the people arguing against what he said seem to be in the realm of theory. But he is actually letting you know what his practical work experience has been. There is a difference in theory and actual experience. The author isn't theoretically saying he thinks this works better, he is saying he has literally experienced it working better. Git and branching are tools that you and your team can use as you see fit. If you don't want to use the same tools the way he is suggesting that is fine, but why are people trying so hard to convince him he is wrong? He already knows whether or not his teams workflow improved by making the changes he told you about.

Collapse
 
marcoslhc profile image
Marcos Hernández • Edited

Then you have a crappy team, somebody failed to communicate how to work on the team or something else; definitively flesh based problem rather than software tooling problem

Collapse
 
owais profile image
Owais Lone

Same problem as you described in the original post and same solution: communication.

Collapse
 
nssimeonov profile image
Templar++ • Edited

Do you realise, that you have much bigger problems with your development process and colleagues, than how you use your source control system? Seems like a big mess and here is why:

  1. You need features from other incomplete branches, i.e. you are not planning ahead correctly and your branch lifespan is too high

  2. Your colleagues can't properly use git and branches just like you (why am I not surprised?)

  3. You need better tools to merge code maybe (can I suggest Araxis Merge?)

  4. Everyone works on their own and nobody knows what the other is doing, then you are "surprised" of the outcome and you have to stitch it all together.

Don't be offended by my words - I intentionally wrote it this way, so you can pause and think a bit.

Thread Thread
 
katsanos_george profile image
George Katsanos

Exactly my thinking. They have serious issues in how they work, I also bet it's not a team that one enjoys working with, and they just blame it on "the system".
I'm pretty sure their task breakdown is also wrong and they start working on huge epics in one branch without properly splitting the work. Probably their tech isn't allowing it.

Thread Thread
 
gitaaron profile image
Aaron Surty

Chalking things up to poor communication is like saying that the key to standardizing deployments is better documentation. Its true that a wiki can work, but why leave it up to human error when there is a better solution which is automation? Automation is essentially working documentation so you were right if you said the answer is documentation, however, I would give a better grade to the person that answered 'working documentation' over 'documentation'.

The problem we are talking about here is having people and teams come out of sync that can result in integration issues later down the road. Better communication is the right answer. To me, trunk based development essentially means 'working communication'.

Collapse
 
joelnet profile image
JavaScript Joel • Edited

I recently left a large codebase that didn't branch. I worked in this code base for 3 years.

As a result, we were forced to cherry pick change sets ready to deploy into a stage branch.

Once stage was certified, we had to again cherry pick change sets into a release branch.

The amount of feature flags required to support this would have been unmaintainable.

The amount of bugs that resulted from this were incredible.

The only way to describe it was a nightmare.

I don't see any possible way a large team can work in this environment.

I would never recommend "no branches" to a team over 3 people.

Collapse
 
anortef profile image
Adrián Norte

Because you guys were branching you had all those problems, from your comment I can see at least 3 branches being used.

Collapse
 
joelnet profile image
JavaScript Joel

That was not the cause of the problems. It was the symptom.

The cause was a failure to create a proper branching strategy from the beginning.

Thread Thread
 
quii profile image
Chris James

No it isn't. Your problem is you are scared to release your own software and instead you are cherry picking changes in your trunk.

Thread Thread
 
joelnet profile image
JavaScript Joel

Being scared lol. I can tell if you are you being serious or a troll. Has to do with a multi tenant platform that has SLA with it's clients that gives a 30 day review period to sign off on any changes before prod it's updated.

There are legit compliance reasons for staging deployments.

Collapse
 
carleeto profile image
carleeto • Edited

First, the analogy of splitting the canvas into 5 doesn't work. Even though you're working on a single feature, you can see the whole canvas and (one would assume) you're communicating to make sure that the changes are harmonious.

Second, feature toggles are a bad idea in my opinion. They basically translate to increasing the cyclomatic complexity because someone can't decide whether a feature should be on or off. The real problem isn't branching, it's indecision and poor planning. I could very easily see four or five half baked features becoming a testing and maintenance nightmare. If you do this for any length of time, your "bitfield" of features will be a lot more than 4 or 5. Good luck changing things when you realize a half baked feature needs a design change in order to complete and you have a few other half baked features to deal with.

Branches are good for a reason. They follow the UNIX philosophy of "Do one thing and do it well". Nothing will replace good planning and prioritisation.

While feature toggles might seem good in the short term, you're essentially building up more technical debt than you need to and are accelerating paralysis due to it in the long term.

Finally, I'd say if branching on Git is actually wrong, then why is it the cornerstone of so many CI/CD workflows? These workflows have been designed by extremely smart and experienced people and have been proven to work. So either you're missing something or the rest of the world has. Which do you think is more likely?

Collapse
 
anortef profile image
Adrián Norte

First, the analogy of splitting the canvas into 5 doesn't work. Even though you're working on a single feature, you can see the whole canvas and (one would assume) you're communicating to make sure that the changes are harmonious.

That is the idea of each project, then reality comes and some people don't even listen on the daily standup much less take a look at slack or whatever they just want to be left alone and code.

Second, feature toggles are a bad idea in my opinion. They basically translate to increasing the cyclomatic complexity because someone can't decide whether a feature should be on or off.

If the feature is marked as delivered then it should be on unless it creates a critical bug on production.

The real problem isn't branching, it's indecision and poor planning.

You will have those you want it or not therefore I prefer a system more resistant to it.

I could very easily see four or five half baked features becoming a testing and maintenance nightmare. If you do this for any length of time, your "bitfield" of features will be a lot more than 4 or 5. Good luck changing things when you realize a half baked feature needs a design change in order to complete and you have a few other half baked features to deal with.

Don't bite more than you can chew. Why start 5 new features if your team can only handle 2 per sprint?

Collapse
 
carleeto profile image
carleeto

It sounds like the problem you're experiencing is lack of communication and agreement. Code isn't going to fix a human problem.

I suggest you tackle the problem at the layer it manifests instead of trying to reinvent a square wheel at a lower layer.

Thread Thread
 
anortef profile image
Adrián Norte • Edited

After years of working on several companies and projects the only thing I saw in common were two:

  • lack of communication.
  • the managers always wanted more.

If you have some suggestions on the communication part please tell.

Thread Thread
 
carleeto profile image
carleeto • Edited

Based on personal experience, I would say, don't give in. Instead push for change, hard. Sometimes you will hit a brick wall and will have to move on. But then you find a team (and a manager) that's a joy to work with and work becomes a pleasure.

Collapse
 
martinfeineis profile image
Martin Feineis • Edited

The last company I worked at had every dev forking the repos they were working on, and then making PRs to the company repos. For me (being a messy brancher) that worked pretty good, nobody could see my mess, I obviously only committed clean working code, and the company branches were clean and few.

Collapse
 
anortef profile image
Adrián Norte

Interesting approach.

Collapse
 
jmorandook profile image
Jorge 🇦🇷

wait, you are posting an opinion about git branching and you never heard of forking? this, i think, tells us everything we need to know.

Thread Thread
 
anortef profile image
Adrián Norte

Of course I know what forking is but I never seen a company working that way.

Collapse
 
martyonthefly profile image
Sylvain Marty

We work like that in my company, this is a very good way for branching without messing with the main repositories branches 👍 Pull request in a lovely team, this makes all my days at work 😍

Collapse
 
thehanna profile image
Brian Hanna

I like that approach. Sounds like it would work well with really large codebases

Collapse
 
jeffeb3 profile image
Jeff Eberl

This article confuses long lived branches with topic branches.

1) long lived branches are the worst and I'd rather not have branches if long lived branches were unavoidable.
2) not all branches are long lived, and short, feature specific branches are a useful tool to organize developement.

Your feature toggling is the worst suggestion I've seen in a long time. Although it's common to see this, it leads to code rot and maintaining code that's not used. If you're good at organized feature branches, you can immediately toss the old function and get it back in a merge free revert with one command. Forking the code for different versions is every devs worst nightmare.

If you were talking about long lived branches (stuff that lives longer than a sprint) then I would totally agree with most of what you said.

To put this back in your painting analogy, topic branches are more like brush strokes and each time you make one, you get a chance to step back, see if that made it better and find where in the painting it makes sense to work on next.

Having a clean history, and being able to review changes on a topic by topic basis are the hallmarks of git and it's power. When you can just revert a merge commit and cleanly delete a feature the night before a deadline, you'll understand the power

Collapse
 
atebmt profile image
Mike Thomas

Wow, I'm surprised by the negativity to this post from the majority of the developers here. The idea is spot on, but the article title and tone could be better - as in all things there is rarely a right or wrong answer to a problem.

I'm gonna argue the case for using one one branch - trunk/master. It may not work for your organisation, but for my organisation it's an essential way of shipping features to customers quickly.

We have 40+ engineers and we all commit directly to trunk - no branches, no pull requests, no QA department. Every push to git is deployed to production, provided that the push passes the pre-push test and quality checks, CI automated tests, etc. We pair-program on pretty much everything, the extra set of eyes is the equivalent of a pull request for us.

When bugs are introduced, it's trivial to rollback production to an earlier version and identify the commits that have likely introduced the problem. It's much harder to identify where a bug was introduced when you have multiple changes from multiple feature branches. Adrian is right failing fast is good! Quick feedback loop is incredibly useful. (That's why we all practise TDD, yeah?) When a problem does happen, engineers quickly pick up on the issue. ("Oh yeah, that was my recent commit on XYZ, I'll rollback production now and then revert those changes"). They are in the zone at that point. Compare that with a release that introduces a bug and engineers are already on a different task or feature. They have to context switch back to the earlier work, which makes problem identification harder. All engineers using the same code base and pushing to production daily helps with this rapid feedback loop.

Feature flags are not used simply as an on/off state to control "half-baked features" not being released. If you want to perform experimentation on your features or canary release features then feature flags are a must. Services like LaunchDarkly or SplitIO can provide matching rules for feature flags that allow you to target cohorts of users and give those users a different UI experience or feature. For example, we can easily create a new sign-in page and target 10% of all users to use that sign-in page while the other 90% get the existing sign-in. If all goes well and we don't get any major problems we can continue to rollout that new page to more users. Increasing or decreasing the percentage rollout is a configuration change and is instantly reflected on production. Experiments are also easy to implement with these feature flags. (For example, what's the affect on user registrations if we change the text? Make the register button bigger? Add a coloured background to the register button?). The results of these experiments allow us to continually improve the customer experience. Experiments and canary releases can also be turned off instantly (no deployment needed!).

If you don't want/need to deploy to production daily, then feature branches will work just fine. But, if you want to move towards continuous deployment, rapid feedback on experiments, canary releases then trunk based development and feature flags is a good approach. It's scary at first, but it's worth it. Not one of our engineers will go back to the bad old days of feature branches and merge conflict hell.

Collapse
 
itenev profile image
Ивелин Тенев

Above all, the purpose of branching is to isolate the impact of said changes. Feature toggle works well in most cases, but not all. It does not handle dependencies well, for one. Also, how do you run your integration and functional tests? With all changes in develop, these will be failing all the time.

The worst part of "gitflow w/o feature branches", I believe this is what we are talking about here, is that a defect introduced by any of the teams working on develop will impact all other teams as well.

Collapse
 
anortef profile image
Adrián Norte

how do you run your integration and functional tests? With all changes in develop, these will be failing all the time.

The CI server does it for me.

The worst part of "gitflow w/o feature branches", I believe this is what we are talking about here, is that a defect introduced by any of the teams working on develop will impact all other teams as well.

That is the idea, you want to fail fast to fix it faster.

Collapse
 
itenev profile image
Ивелин Тенев
Collapse
 
jefferai profile image
Jeff Mitchell • Edited

Ask yourself which is more likely:

  1. You are using the wrong tool for your workflow
  2. Everyone else is using the wrong workflow for the tool
Collapse
 
ferdnyc profile image
Frank Dana • Edited

What I don't get about this argument is, with distributed version control, in a sense everyone "paints their part without even looking at what their partners are doing" even if you don't branch. Unless everyone regularly pulls from the repo, they're only going to see what's in their checked-out copy.

If you want to mandate that they regularly pull in order to stay up to date with others' changes, you can just mandate that they regularly merge master (or develop or what have you) into their topic branches.

I don't see how organizing or not organizing your own development into topic branches affects how integration with the rest of the codebase is handled. And as someone else pointed out, if every developer has their own fork of the code (the GitHub model), then that adds a further wrinkle that even this crazy "no branches" position doesn't solve.

I feel like this is trying to solve the wrong problem, by thinking that branching is the problem.

Collapse
 
ctrlshiftbryan profile image
ctrlshiftbryan • Edited

Without branching you can't have pull requests. Without pull requests code reviews are very difficult. I work on shared repos with as many as 10 other devs working on feature PRs at a time and this simple model just won't work for us.

If you think about it branches are just "groups" of commits. Being able to break big features down into small commits and group them is actually something that helps avoid conflicts and increase communication in my experience.

The only time not branching ever worked for me was back when I first started using GIT and was basically just a single developer that used source control as a giant undo history.

Collapse
 
anortef profile image
Adrián Norte

In my personal experience PRs are almost useless unless all your team knows how to do them well. In my opinion PRs cannot beat a well configured Sonar + CI Server.

Collapse
 
lukas1 profile image
lukas1

Then you have no idea what you're talking about. You can configure PRs such that if the code is not building, or passing tests, it will never be possible to merge that code to the main branch. With your approach, this is not possible and who knows if you even pay attention to failing tests at the moment. Because when you're not FORCED to solve these issues, sooner or later somebody will say to leave it to later, because now you're busy with other stuff.

Also, you still didn't answer how you conduct code reviews. I'm guessing you don't. But even if you do, the result is that code pushed to main development branch is messy.

In some other comment you mentioned that developers changed architecture in their feature branches. Well, with code reviews, you'd see that and comment on that and tell the developers to not change the architecture, or resolve the situation before it gets to main development branch.

I'm thinking maybe you just never worked in a technically mature team and you never conducted proper code reviews and that's why you have these opinions.

Collapse
 
xvlcwkh profile image
Chris

PRs cannot beat a well configured Sonar + CI Server

There is no race between those. Those are supposed to work together.

Collapse
 
alainvanhout profile image
Alain Van Hout

You have an amazing Sonar + CI Server if it can give warnings for inappropriate architectural approaches, business requirement issues, or rolling your own libraries when those already exist in the codebase or in existing dependencies.

Collapse
 
katsanos_george profile image
George Katsanos

"PRs are useless".
I'm seriously more and more horrified I would accidentally one day work for that team. I'm sure I'll see a nightmare tonight. Dude you need a good mentor who can show you how it's done. No offense, try to work with people having worked abroad and have a wide experience in leading teams. You have many misconceptions and dogmas.

Collapse
 
kraftman profile image
Chris Tanner

You're treating the symptoms not the cause, and misusing tools in the process.

Your team shouldn't be going off on their own for 2 weeks at a time, they should constantly be pushing small PRs. They should be constantly reviewing these PRs so they know what's going into the codebase, and your codebase should be decoupled enough that conflicts are rare.

Collapse
 
quii profile image
Chris James

What's the difference between constantly pushing small PRs and just committing to master?

Collapse
 
ilmtitan profile image
Jim Przybylinski

If someone writes a mess of a PR, it will get hung up in the code review process until it is clean. The only people it will affect are the writer of the PR and the reviewers.

If someone writes a mess of a commit and pushes it directly to master, it affects everyone who wants to push.

Thread Thread
 
quii profile image
Chris James

What's to stop the PR process pushing something that is "a mess" ? We're not all knowing and make mistakes.

The beauty of software is that it can be changed, so if someone pushes up a "mess" then it can be fixed.

In practice, if you trust your team... then people wont be pushing "messes". Sub-optimal? Sure, but its not a big deal.

The problem with this kind of ceremony is its trying to optimise for perfection, which no one is capable of. What you should be optimising for is fast feedback loops so you can quickly iterate to something that resembles useful software.

Collapse
 
joelnet profile image
JavaScript Joel

I strongly believe there is no one size fits all solution to anything. And for small teams 3ish and under this may work.

I also strongly believe in the "do what works for your team" motto.

If your article had some conditions, for example: very small teams, I could have agreed with you.

But a blanket statement saying git branching is wrong is not only false but dangrous and harmful.

Before branching, this is how software was done. And there were problems with it, which is why the concept of branching was created. To solve the problems with source control that didn't support branching.

For those of us that have been through the advent and evolution of source control systems, we understand why branches exist because we have experienced the pains of not having them.

Collapse
 
erickmendonca profile image
Erick Mendonça

Communication is key. But we also have another keys:

  • merge your master or parent dev branch into your feature branch often
  • avoid long lived branches

I agree with some suggestions you made, like feature flags. They help a lot to keep the branches short-lived.

Collapse
 
anortef profile image
Adrián Norte

All those premises are the same everywhere I worked that used branches, the result? Years old, thousands of commits behind and totally forgotten branches.

The problem with branching is that it actively requires the developers to be clean.

Collapse
 
erickmendonca profile image
Erick Mendonça

Forgotten branches are forgotten features or projects - they may happen with or without branches. All proposed solutions also require the developers to be clean at something.

I think lack of planning and communication are the main problems in these situations, or at least that was the case on my experiences.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.