why branching on git is wrong

Adrián Norte on October 27, 2018

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 fea... [Read Full]
markdown guide
 

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:

 

Good ol gitflow with pull requests. "Gateflow," if you will. Personally I don't mind it at all and like PRs, however I've worked at orgs that got just as far with manual CRs on a trunk model. It usually boils down to how much you trust your devs, or the dual, are they skilled and reliable enough to not need the merge control hand holding.

 

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

 

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?

 

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.

 

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.

 

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.

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.

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.

 

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?

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?

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.

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.

 

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.

 

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.

 

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.

 

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

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.

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

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

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.

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.

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.

"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.

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.

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.

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.

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.

 

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.

 

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.

 

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

 

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

 

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.

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.

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'.

 

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.

 

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

 

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.

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.

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.

 

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?

 

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?

 

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.

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.

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.

 

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.

 

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 😍

 
 

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.

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

 

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

 

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

 

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.

 

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.

 
 

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
 

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.

 

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.

 

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.

 

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.

 

PRs cannot beat a well configured Sonar + CI Server

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

 

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.

 

"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.

 

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.

 

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.

 

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

 

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.

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.

 

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.

 

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.

 

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.

 

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.

 

writing new features and integrating them into preexisting code are/should be separate tasks. keeping them separate cuts down both on feature creep/"oh i'll just do this too while i'm here" and on tech debt caused by timidity in the face of old code.
relatedly, isolating features makes squashing/rebasing easier (especially now that github has those options), which makes pulling problematic code out easier.

 

A couple of years ago I'd have entirely disagreed with you, but after switching to trunk-based development when I joined my current job (i.e. that was what the company was already doing so it was something I had to do too) I'm right with you.

I think it's easy to think this will be a nightmare, but in practice I can count on one hand the number of merge conflicts I've had in the last 18 months, and they were all very easily fixed. This was the total opposite experience that I've had in the multiple places I've worked that used feature branches.

Edit: okay I do actually disagree with the clickbaity title, branches aren't "wrong". But yeah, I wouldn't be keen to switch back to them.

 

Conflict resolution is easy if you use the right tool. Do you use web storm or some other ide with à visual conflict résolution tool ?
Conflicts don't happen when you have a good architecture and everyone works in their own component. It also doesn't happen when you communicate and if you rebase often.

 

It's even easier when you don't have them in the first place. :-)

 

Agree working in a bubble is bad.
Agree merging to master early and often is good.

Completely disagree with the premise that using feature branches causes the type of problems you describe.

There's definitely something else going on here.

Your feature branch should be short-lived.

You should be merging or rebasing Master into your feature branch one or many times a day so you have the latest commits from everyone else

 

So you disagree with the foundation of what git is all about. Branching is cheap, it is meant to used...a lot. Why not just go back to subversion and forget about using git?

 

I've got to agree with the rest of the sentiments left in this comment section. This is terrible advice and should not be followed. I've worked like this in the past and it's hell compared to gitflow or even a simple feature branch model.

 

Suitably controversial subject, especially for post #1, bravo :)

I note that nobody has yet mentioned structural issues, my first reaction to a situation where close co-ordination is required among a significant number of people (say 4-5+), is to question the coupling of the things being worked on - ask if there are better ways to structure the code so more people / teams can work unhindered (yes, apply Conway's Law!), look for more stable interfaces, domain boundaries, to partition work around.

If short term fixes are needed, perhaps ask if there are known working practices which would help like Mob Coding, or appointing a design authority role to make decisions that affect >1 person (this can be a rotating role, as long as there is someone the team can communicate with immediately for such decisions and they are shared).

 
 

Any agile methodologies will tell you to keep the features small and talk to your teammates regularly. Also, any good backlog grooming should contains evaluation of inter-dependance between features so special care is taken in those scenarios.

So I definitely agree with you that long lived branches are a nasty thing. However, I don't see were this has anything to do with git branching, gitflow or feature switches. Also feature branches allow to validate the team's "definition of done" in code review before integrating a features, so the team never have to put any feature in production that would lack test coverage, documentation or whatever the team deems important.

I suggest you to take a look at the INVEST mnemonic trick, to evaluate your backlog stories.
agileforall.com/new-to-agile-inves...

See ya!

 

I really disagree. Feature branching is an invaluable aspect of development workflow. I agree that code isn't written in a vacuum and individual developers must be aware of everything else going on simultaneously to avoid disjointed software and the bloat that comes with development each developer trying to be independent.

However, feature branching is not the source of these problems. Poor communication is.

My teams are always checking out each other's feature branches to understand changes being made. WIP pull requests are made as soon as a feature's scaffolding is clear enough to be understood by another developer. Comments are made right away suggesting improvements, warning of pitfalls or inconsistencies, or criticizing the entire approach. As commits roll in, particularly affected parties subscribe to notifications so they can see what's changing and discuss.

When developing, I spend at least 20% of my time in other people's branches, piecing together the way everything will work. When I notice divergence between the branches, I start a lengthy thread on Slack and we figure out how to tighten up our architecture.

What about when developing highly-interdependent features? Keep in mind that they're feature branches, not developer branches, and don't exclude cooperative development by multiple developers on a single branch. If the two features are small enough, we develop them on the same branch. If they're more complex, we will often create a branch that acts like a mini-development branch to create feature branches from and make PRs to. When the interdependent features are ready, we make a PR of this mini-dev branch back to development proper.

Trunk-based development (and adding in dev-environment logic) really misses out on the power of Git. The big advantage of version control is that untested code can be rapidly checked out and used without interfering with reliable code. It ultimately increases effort needed to commit and reduces frequency of commits, since developers need to be very careful not to commit code that doesn't work. Moreover, developers must rely on each other to keep the trunk in working condition. One mistake halts all development. No one can test their own features against known working code with the entire codebase in a state of flux. The larger the project, the greater the risk. Soon enough those daily meetings become week-long workshops that resemble change-board reviews. Eventually quality sacrifices are made just to get it working again due to the building pressure of all the developers waiting on the one problem to be fixed.

Git flow is scalable from an individual to a large organization, and allows concurrent, prioritized development with minimal risk of breaking the trunk. When implemented properly with CI/CD and proper merging permissions, there isn't a quality sacrifice. When WIP PRs are made early and a culture of checking each other's work is promoted, the code remains unified and everyone's concerns are heard.

I respect that trunk-based development has worked for you, and I know it's not always unsuccessful for small projects, but I've seen many trunk-based teams slow to a crawl waiting on individuals and become unable to easily produce working builds on demand because their version control was in their way.

 

Thanks for writing pretty much the comment I would have written.

 

I see where you are coming from, but I largely disagree.

Development, especially for big teams, should be loosely coupled. This doesn't mean that the team shouldn't meet and have a unified clear vision, on the contrary, this will allow things to scale properly and gives you options to add or remove features with minimal effect on the actual main branch.

Your painting analogy is a moot point imo, since painting is mostly done by one painter not 4 or 5 or way more, like in software.

A better analogy would be a car assembly line. Engine, suspensions and body parts are manufactured on their own assembly line and then they are put together when they are ready, wouldn't you agree?

 

I assume when you say "in two weeks try to piece everything together" that you are working in two week sprints in an agile process. The issue in my opinion is that the pieces you are working on are too big and needs to be broken down further. If the single thing you are working on takes up the entire two weeks of your sprint then it's too big. In my experience a good rule of thumb is that items you work on should be less than the sprint they exist in. Also a highly functioning team should know how things are being implemented through conversations and proper design specs resulting in less surprises.

 

Don’t agree with this at all. Suggesting that branching be replaced with further time consuming meetings and features toggles just seems ridiculous.

Part of your role as a developer should be a good understanding of source control and having processes in place to support the use of branching (planning, reviews, correctly identified tasks) is a lot more conducive to having a concise code base than filling it full of broken code and feature toggles.

 

This is not a great approach at all. Every time code is touched it should be it's own branch. This is exactly why Git mimics the structure of a tree.

Having a dev team work on the same branch can cause delays. If one developer breaks a branch it can halt development for everyone else. Unless of course, all members are at the same level of efficiency.

Having work on speperate branches allows for better code review and keeps a nice history of commits. If a developer leaves in the middle of work, another developer can pick up where they left of. They can also refer to a ticket with the same naming convention.

If the dev team has unit tests and CICD in place, they can catch the errors there.

I'm typing on my phone after a few beers. Not the best idea to comment in this state of mind.

I guess tagging could be an option as well, instead of branches.

 

Respectfully disagree. This defies the whole point of Git. But if it’s working for you and your team, stick with it! These days I need to get things done fast and with as few bugs as possible. Use whatever technique saves you time.

 

I mean... if it works for you I guess... but I don't think I could disagree with this strategy any more than I do; even if I tried.

Feature branching has been one of the best things we've done to step up our game in years. We have very reliable release process that includes management review of everything that is getting released. We have branches for each environment with builds tied to them. A simple merge to that environment gets the code out for review, QA, and UAT. We have weekly releases; continued improvement.

I am very confused how "resolving conflicts quickly" is useful when you've possibly broken the flow of 5 developers because a sixth pushed something that broke things. that seems insane to me that even if it is fixed quickly it isn't extremely disruptive. Context switching is so damaging to productivity; I cannot see why you'd set yourself and the team up for it to happen frequently inside of your own development process.

Software development branching doesn't translate to your painting example. Of course 5 people working independently on a painting is going to be (most likely) a total mess -- unless they are all working together and discussing what the plan will be. The very element to making no branching work is exactly how you avoid issues in a feature branch scenario: communication. That doesn't change no matter what you do.

Feature toggling is key no matter what branching methodology you subscribe to. It is just a good way to build software; especially if it is a multi-tenant application.

 

i don't understand how to maintain the code clean doing this.

 

sonarqube.org/

Use that, for example. Then you put up a CI Server that takes those metrics and executes the test and marks the commit as good or bad. If bad you remove that commit and make the developer pay for the next beers.

 

If bad you remove that commit and make the developer pay for the next beers.

Removing that commit means you just doubled the merge conflicts and made bisecting impossible.

Sonarqube and CI work way better with Pullrequests where the commit is rated before being integrated into development. Have a single clean mergecommit instead of having a ton of reverts and "fixed spelling" on your mainbranch.

If you need to have a single Branch for your CI to work
you should configure your CI properly (build once after every push, always merge locally with target before building, let CI handle the final merge into target once the PR has enough approvals and a clean build) instead of giving up on branching and PRs.

If you need to have a single branch because of conflicts you need to rebase more often and most importantly keep your issues and thus your PRs smaller.

 

If I have to remove bad commits why not keep the stable code clean in the first place using branches.

 

Based on various comment replies you've made it sounds like you're working in a dysfunctional environment.

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

You don't appear to be communicating, not just effectively, but at all.

Communication problem are unavoidable or so says my experience.

Good communication, through tools, talking, meetings, whatever, is the key to good development. It sounds like you've given up on communicating.

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

CI's can't test code cleanliness. The idea of full coverage is also a bad myth.

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.

Why are you guys even working on the same team if this is the case?

In my personal experience PRs are almost useless unless all your team knows how to do them well.

You're programmers, you should know about pull-request workflows.

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

Why would you not want developers to create clean code? I'd prefer my processes to encourage clean code always.

 

No, this is just terrible. Your description points to severe disadvantages in this situation.

Your code example points to the critical weakness of this approach. You have two pieces of code in the project doing the same thing. Either they both work and its redundant, or one doesn't and it's broken. I don't see value in either of these states.

The idea that you're committing half-baked features also points to a development flaw. Why would you do this? A limited feature is fine, but something that is admittedly "half-baked" shouldn't be in shipping code.

Having several people spend weeks on major features that will conflict when merged also sounds bad. Just because you're branching doesn't mean individual are working independently. There should still be coordination along interfaces, iteration goals, and more.

Two weeks is a long branch life on an active project. They happen, but they require special care, involving lost of merging from master over that time. This merging from master avoids the isolation. If master is going weeks without any changes then your branches are just too big.

What you're describing about branches sounds like you've failed to create a proper branching strategy. The solution isn't to abandon it, but to fix it.

Branching is one of the cornerstones to proper engineering. One may argue with the strategy, but to argue fundamentally against it is a terrible thing. It does everybody a disservice to imply that a branch-less strategy is a viable option.

 

I respect that you have a different flow but saying that git branching is "wrong" is short-sighted at the very least.

It's funny that you mentioned the feature toggles concept because I used to do that back in the days when I was a solo PHP developer and it was only my code and maybe one other person's code.

But on large teams feature toggles would be an absolute nightmare IMO and just not very professional at all. There are literally millions of small to large teams using branches on a daily basis and it all works fairly smoothly.

 

This is your opinion right? Saying it's "wrong" is more like saying it should be a fact.

First of all, an app, a project is not a painting. Yes, of course you're using a metaphor, but no, it's not close enough. A painting is not as flexible as code changes, it's not modular, it's one monolith product whereas a project is a modular structure. If your stuff won't fit in the final product, you can always redesign some parts you've made to work with the current(latest branch) system.

2nd, nobody should be really pushing half baked stuff, branches are there for you to complete the feature and test. If it conflicts with the main working branch, development or master, the one who's pushing those changes is responsible for resolving conflicts and making it sure everything works(automated tests passed, builds successfully). It's a good practice for the one who's on a different branch to stay up to date with the main working branch. If you find yourself having to fix a lot of conflicts, then there's something wrong with your development flow, maybe you're not communicating enough with your colleagues.

Finally, just because it works for you doesn't mean it should work for everyone else. If you think about it, that's the only thing consistent for everyone.

 

Wow am I so sad this article with such a clickbait-y title actually got picked for the weeks top articles :( This sounds more like a rant than an actually useful piece of information.

The way some choose to use branches perhaps is wrong, but stating that branching is wrong on git is just plain wrong. There's git-flow, there's forking flow, there's whatever-you-think-works-for-you-flow. I'm sorry that you had bad experience. As long as you have pull-requests it doesn't matter how a person chooses to build the feature. GIT is a distributed version control so you can do whatever you want in your local clone. But the important bit is to integrate development at least daily so you don't have such issues.

Now what this article is probably about - is feature toggling, unfortunately the subject is touched very lightly. Also "proper" CI was mentioned, but what is "proper"?

 

I read you completely. Took 5 minutes thinking about it and trying to be in your shoes, and yet.. I cannot agree. As others said: I really respect your way of viewing things and, Man, honestly: If it works for you, then Congrats! There is more than a single way of achieving things in programming.

But what works for me is to have feature branches and merge: A wild conflict appears and we resolve it. We check that the resolution works (QA again) and Done!

 

So,

if (useNewLogic) {
  awesomeNewFeatureEntryPoint();
} else {
    legacyEntryPoint();
}

Two months later:

if (useEvenNewerLogic){
    evenAwesomerNewFeatureEntryPoint();
}else{
    if (useNewLogic) {
        awesomeNewFeatureEntryPoint();
    } else {
        legacyEntryPoint();
    }
}

The following March:

if (useMagic){
  magicEntryPoint();
}else{
  if (useEvenNewerLogic){
      evenAwesomerNewFeatureEntryPoint();
  }else{
      if (useNewLogic) {
          awesomeNewFeatureEntryPoint();
      } else {
          legacyEntryPoint();
      }
  }
}

Not sure that I'd like to be the one to refactor that lot after a year or so...

 

Nope, can't get on board with this suggestion. Branches are great for so many reasons:

  • Having a backup of my code on the github server
  • Being able to share changes with colleagues before they're merged
  • I frequently use branches to test out ideas or write up code "in case it's needed at some point"
 

So what if I work in the same branch for two weeks without ever pulling in changes from my co-workers? Would that be exactly the same as how you describe working in branches?

On the other hand, what if I work in my own branch but pull changes from master into my branch consistently? Wouldnt that be the same as working in master and keeping up to date?

Branches are just scratch spaces as far as development goes. Once you are happy with the code that you want to dump on your co-workers, you merge, till then you keep it in your scratch space.

 

I couldn't disagree more. I've worked on teams using a single branch methodology and it was always a mess. I've had no problems at all with a feature-branching approach. You give a cute analogy with the painting but it doesn't really hold up in real life. Of course, there are organizational challenges with it as well, but nothing that isn't manageable. Working in feature branches on a single project is like different mechanics working on the same car. If one works on the exhaust while another is fixing the brakes, you're fine. If you ask both to do different tasks, both on the engine, then sure, you're gonna have problems. So... just don't.

 

It's not wrong, you just like a different approach.
Also painting is not the best analogy. More like cooking a dish or building a house together. Honestly it is a pretty weak reason to avoid branches altogether. Do we not all struggle to make our software as decoupled as possible? Why does one part of it have to know what another part does?

 

Look I'll say this much: working on projects by myself lends well to branching. I can go off on a tangent, fiddle around with stuff, break it all, then decide if I want to merge or not and basically never worry about a conflict. Not 100% of the time but most of the time. Awesome.

But in a team, three or more, I can see the issue. It's not always just "Communicate more. That will fix all your problems". It's also about how other developers work through their process. That process doesn't always include committing code every day, for example. Can you consistently make everybody play ball with a set of rules you have to adhere to? Does putting handcuffs help the team or hinder? I'd say it's arguable.

You've got a lot of nerve posting something like this here. But good for you. That's what I think dev.to is about. You can post an opinion that's not popular and then debate it.

Keep up the good work.

 

If the team can't play ball with the rules any system or technique would fail.

 

For projects that don't want to or is too complicated to implement feature branching, use trunk based development.

Feature branch work fine on small projects, where the conflict chance is low and the team is small (< ~30 devs).

 

So your opinion is not to have no branch at all, but it is to avoid branching for each feature.

But could you tell me how am I suppose to test my feature if everyone is commit half baked code even code not compiling into the same branch I am working on. That will be time wasted to sort out problem that is caused by other developers.

 

I think this approach would change your day job from developer, to merge conflict solver...

I do agree that branches can start growing in separate ways which makes it hard to merge them, but if you keep your stories small, and not let your feature branches exist for weeks, but merge them within a day, or tops three days if there is no one available to check the pull request... Then I think the feature branches are a much better solution then the one suggested.

 

Well said. Small branches, quickly resolved is the way to go.

 

Seriously now, as others pointed out, a proper use of Git flow solves the very same problems you're reintroducing here.

Again, if it works for you flawlessly, go for it 🤞

 

You are trying to solve an organizational problem with a technical solution.

From reading all your responses it seems like your team(s) really need some consulting and discipline.
We work with with feature branching on so many different projects and while our ci is a cornerstone for all this, it wouldn't work without branching.

Imagine a project with 5-10 people working on it, committing an average of 150+ commits a day in total.
This would cause mayhem inside the repo and using no branching there would be no way of doing code reviews.

Code Review is key and without it I wouldn't dare to bring code onto master.
You complain about devs doing changes that are on wanted by the entire team, well you need reviews man.

Nothing gets on master when a) the ci is unhappy and b) somebody asks a change.
Every team member has sort of a veto right. If somebody denies a PR there need to be changes, sync and a consensus. In the end we all are a team and a team has to collectively own it's code and should as such avoid technical debt.

Feature Toggles are great, we use them for release trains, but they are no replacement for a well established workflow.
If you don't trust your team, there is no technical solution that can help you.
No matter what managers ask and what people want, quality is not negotiable.
Don't sacrifice this because there are people in the team not willing to deliver a shared level of quality.
Before working as you suggested in your article or comments, I would rather get rid of the problematic employees or quit.

Sounds like you need a scrum master 😅

 

Oh, even better example.
Our IT does Infrastructure as Code.
Imagine no branching there.

If you have to wait for the whole infrastructure process to fail because there was no testing, review etc. you are doomed.

There are no releases, there only is master for prod and what's there is the state of infrastructure.
Not having branches would break everything all few minutes or so.

 

I have only seen a lack of branching to be beneficial in very specific scenarios. I recently worked on a project where there were only 2-3 more senior devs. We worked directly in master and found it easy to find issues quickly and burn through tasks. We also benefited from the fact that the project was not live yet, so we could keep issues that were incomplete in master at the end of each sprint with the clients knowing that we would be continuing development in the next sprint.

For almost every other project though, branching is a must. For newer devs pull requests are necessary for reviewing code efficiently. Also, in my experience with web development, keeping features in their own branches is necessary when the client changes sprint requirements regularly. If halfway through a sprint a client re-prioritize tasks, pulling items out of master is a pain.

 

Good luck with that... And your 'analogy' is not analogus. Software is not a painting. I cannot pull out a piece from one painting and add it to another and have it 'work'. With software, you can always add new things to it and get it to work.

 

Unfortunately I tend to disagree with your thoughts. On one hand industry is shifting towards microservice based application where each service has it's own git repo altogether.forget about separate branches even. while your thoughts discourage using the branches within the same repo. I think branches are a great means to avoid mess.

 

Well, I think that your premise of finding an issue with feature branching fails due to the fact that it relies on a forced parallel that doesn't reflect a real world case. A product isn't a painting by any means, but even if it was split into pieces (features), you would need a method to do that in a way that will provide a nice partial painting at every step or in any mix of 'features'. Even so, splitting isn't done by piece and even in the beginning there would be a wire frame depicting the whole thing so any painter would be aware of what the others should have. Yes, there Wil be misalignments but not as bad as you'd think.
Also, using feature switching isn't the answer in the case that you started to illustrate. Eg, features that depend one on another. One feature can be switched but what do you do with multiple features? I need to have the case where 3 work together but not the 4th,or just 2 of them available while I have the code for 3rd but it's still have baked. I would need to keep a lot of technically useless code for stuff that product management might just decide to eventually scrap.
Also, feature branching main benefit isn't lack of conflict. There will always be conflicts against the main integration branch (master, develop or whatever). The more integration waits, the greater the risk.
The main benefit of feature branching is the ability to add features or simply scrap them without the need for extra work or risk of leaving garbage code around.

 

Isn't what your call 'feature toggling' just plain old branching, but in code rather than using your VCS ?

 

Working on a separate branch allows programmer to experiment with multiple strategies & concepts without thinking about the risks of screwing the existing workflow (and the hard work of others by extension). On smaller scale, your suggestion may work just fine. However, no one can even think of taking risks on bigger level where moving parts are so many and highly dependent on each other.

 

So you don't understand how branches work or you're scared of merging changes and now you are looking for a workaround? This just doesn't sound right for lot of reasons. Same logic will lead you to "why do we need a source control system, when I can save the previous version of the file as .bak"

 

While I respect that this approach might be working for you and your team, I'm going to strongly disagree here.

Any developer that has work on larger projects, and with a fairly large team will be able to tell you that following your approach is more likely to cause lots of merge conflicts, making the code harder to audit, and slowing down the team.

Not all features are so trivial that can be wrapped in a feature flag while they are worked on, and that is not to mention that you are increasing the cyclomatic complexity of your code with each flag added.

In my experience, short leaved branches (GitFlow), Code Reviews and proper CI/CD tools take care of most if not all issues you can have with topic branches.

Finally, I would urge people to be more careful when expressing "controversial" opinions like this in such a matter of fact on a website that has a great number of developers starting or looking to start their career

 

It seems that you've never worked at a shop that understood and executed Gitflow well. The idea isn't that you all run off and program in isolation, but rather that as work is committed, and PRs are merged into the develop branch, the rest of you pull it into your feature branches to mitigate the "merge hell" that was common place before Gitflow, and that would likely result from merging everything at once.
Feature toggles are a part of a different puzzle because they address a problem that's not directly related to merge conflict mitigation.
Do checkout GitFlow, GitHub Flow, and GitLab Flow, as well as some articles on CICD, and how feature toggles are used in the SDLC in a microservices context.

 

Yep. I've noticed the root of most branching problems is the conjoinment of branch with release strategy. You can and should create a release branch, of course, but the pile of stale feature branches (or even worse the cherry pick tango) is pretty much always guaranteed to fail. The key here is to have short lived feature branches, and make use of effective abstraction at the source control level.

The solution is, as mentioned, feature toggles. The only real question that arises is where does the feature toggle implementation occur? That's down to platform, target, application scale and organization. On my current project, we handle it by role and user identity configuration at the reverse proxy, delivering async modules. On other projects baking it into an assembly or a large module structure might make more sense. Definitely something organizations should learn early in the development cycle.

 

This is not my experience, I think feature branches are a great technique. Just don't keep the feature branch alive for too long, and just rebase/merge from master frequently and you'll be up to date with the changes of the rest of the team. Cheap, fast and easy branching is one of the great things of Git ... so personally I'd advise the opposite.

 

In case you haven't come across them, see branchbyabstraction.com and youtube.com/watch?v=YZstpc2939s

I find the take on release branches a bit too "extreme" (depends on where you are wet trunk based development), but definitely something to lean towards.

 

Thx for your great Post. But I think that many Feature flags in a System spreaded, is not a good maintainable Method.

Because you can forgot many of them to remove on a go live or s.th.

Maybe it will not be possible to create twoe or there Stage for dev test an Integration test. But that is my Personal opinion.

But anyway, good Post about the using of them 😊

 

So many teams work with branches and all is well. It all comes down to how well a feature is defined. If a feature is well thought of, there shouldn't be an issue with branching and merging.

On another note.. The title should be:"why I think branching on git is wrong"..

 

I think I agree with the consensus following a quick scan of comments. Branching is incredibly useful and a really good way to actually avoid conflicts (or rather manage them in a meaningful, insightful way).

If you work on a branch, to avoid what you describe, rebase is your friend. Accompany that with a good test process and good coverage, and I can't see anything going wrong (that wouldn't go wrong bigger without branching!)

Read this for more about how my company does git, I don't think I could work any other way now: about.futurelearn.com/blog/telling...

 

Imagine you make an animated cartoon. Image you split up the work, and everyone draws some parts. Some work on the backgrounds, and some draw different frames. What would you expect to see when it's put togather? Masterworks.

These are no reasons to not to have feat branches. Contracts are key. Aren't develop branches messy feat branches in the end? I think they are. You work on your fork, and organise things as you'd like. Then do a PR. After it works. Until then just push stuff not to loose by accident.

 

Agree on feature toggling, but feature branches still make sense, and yes you have to update your feature branch with trunk code at least once daily, preferably more often.

The feature branch can live a short life, maybe just to get the toggle in and then you commit to trunk. Then start a new feature Branch to do some more work behind the toggle, commit it, merge it. I view feature branching as small pieces that get checked in often. And it is up to the feature Branch devs to merge trunk in first.

 

I don‘t really understand what your problem with fearure branches is.
There 2 scenarios:
1) I have my independent feature, work on it in my branch and merge in develop several times a day to get all the chances. As soon as I push CI runs all tests and tells me if everythings being integrated well. If there r conflicts, I fix them right away.
2) same as above obly that i depend on other branches: I‘d say the main cause is that ur planning is flawed. Obviously the dependencies weren‘t defined peoperly and you shouldn‘t alread work on it.
If you absolutely have to, the solution is to just merge those branches in ur branch.
It takes some communication though bc obvioulsy ur working on related features.

These two strategies never failed me!

But I heard of colleagues who managed to not merge develop into their long running branch for weeks and then wonder why there are so many conflicts 😒

 

This is a joke, right? The solution to not using the best feature of git is to add spaghetti code?

 

Can you please elaborate? because the best and most tested, easiest to read and maintain code I have worked with was a project that only had master and branching wasn't allowed.

 

I agree, mostly. Perhaps you took my comment too literal and perhaps I took the article too broadly. I don't like the develop/next type branching schemes, and perhaps that is what the article is referring to. Branches are the best part of Git and that's what makes PullRequests so powerful. Without branches, we're back in the SVN/CVS stone-ages

 

I'm not sure either.
OK, you should avoid long lived branches. And in any case your change is a bit bigger, rebase regularly with master to "see" the changes of your colleagues.
But in general branching and PRs worked good for me.

 

Do a rebase on a regular base, and no one will have struggle. Merge commits are hurting the history of the master branch very much. I recommend fast forward merge commits. Branches can be a very helpful tool to ensure quality and a green master.

Know your tools you are using. ✌️😬

 

Just so I'm understanding this post correctly...are you saying that long-lived branches are bad? Or that using branches in general is bad? Or having too many branches is bad?

In any scenario, I'm not sure if you're advocating more towards "use less branches" or "use better CI" or maybe neither of those two.

I do see some validity towards your case but I feel like there's some background information missing. Maybe "Why Branching on Git is Dangerous" would've been less provocative but maybe provocative is what you were going for. Regardless, an interesting post indeed.

 

It's a good perspective, but personality i think branching strategy is more practical if we combine it with good communication in the team,like you mentioned, while everyone is working on his branch they should know what's going on in other branches if they are related and will be combined in the release. also the way features are separated by branches must be convenient,

 
 

It's an axiom that you should "commit early, commit often." Likewise your local drive should not be the only place clyour work exists. That means it may be incomplete, broken, even ill-considered. On any reasonably sized team keeping everyone aware and up to speed with what everyone else is doing is very difficult. That means someone might see work that isn't ready and make the logical assumption that it is. Or this code makes difficult to reverse changes that now have to be backed-out on everyone else's environment when it changes. I can only imagine the hell of trying to make my work mesh with someone else's only to have theirs change completely the next day. At least if that only happens once I skip all of the intermediate steps. I don't need to see everyone else's sausage.

 

Long discussion below so I'm not sure it was already highlighted.
I'm completely disagreeing here.
Even if you do not use branch, but just using mainline (master/develop/whatver) you are essentially in a bubble until you fetch and merge from upstream.
So there is no real diff between this and having a branch.
Having a branch makes it easier to start something like an experiment etc... to compare with a human readable string/branch vs just a SHA1 and git is really designed well around it.
The key is, whatever you choose, you need to fetch and merge (or rebase unless someone is working off your branch) as frequent as possible.

 

I've worked in both "feature branch" and "trunk only" development shops, and I haven't had as good of an experience with trunk only. On one project, I made architectural changes that worked well for the main repo... but there were countless one-off scripts that I had no knowledge of (because they weren't committed, or rebasing didn't happen often) that broke. It was a ~happy~ horrible experience. The second "trunk only" project I worked was in another group where communication was poor with remote employees, myself included. Big changes would happen without notice, I would get asked to undo hours or days of work because it broke code someone else hadn't checked in "because they don't do that until code is finished."

All that being said, I agree with your original premise - it works well when the team communicates well. Both of my experiences were the result of poor communication.

 

Git is not SVN.

It's worth learning the tool well and how others use it.

 

To throw in my $0.02, I'd say it entirely depends on what works best for the project and the team - and it won't necessarily be the same if the team changes or the project changes. Hell, it might not even be as productive one feature to the next.

The most important thing - regardless of branching strategy or even VCS - is team communication. Full stop. If the team can't communicate well enough - and that's also arbitrary on a per-team basis - the project will fail. If the team coordinates and communicates great, then you can throw the code on a shared network drive and it'll still go decently.

Yes, a build server is a great thing, but it still needs code to build, and in my experience it gets that from a repo. My company uses Bamboo, which I know can build branches. I'm sure Bamboo is not special on that front. It runs a build on every branch (don't have to pre-configure it, it picks them up on its own), passes or fails, life goes on as it needs to.

We're trying to move towards continuous delivery, so we're trying to go with small stories that can be finished in a day or two. It's be cool if we could do away with branches altogether, but we need PR's and it's nice to keep stuff out of the main line if it's not ready for prime time yet.

Most importantly though, it sounds like you've just had crappy luck for teams. You need to call people on it - diplomatically of course - if they aren't communicating well. Go out of your way to talk to people about what they're working on. If someone isn't paying attention in stand up, find a way to get them to - ask if they have a suggestion on what you're working on or something. If anyone has a problem with it, that's their problem. If management has a problem with it, that's their own fault for not doing their job.

And maybe you need to find another company. I don't know what the market is like where you're at, but in my area - and a lot of places - the only reason to stay at a company doing dev work is normally because you like (or can at least tolerate) the company. You're knowledgeable enough to make a pointed argument on this subject, so you have some reasonable amount of experience coding. You should be able to find a job with people who communicate at a level you can excel with.

 

In the ideal case you always have some kind of architecture laid out, well understood by the team. So the painting example in this article would actually go like this: the painting gets planned before going into details and a draft is drawn on the canvas using pencil. Then the canvas can be taken apart and members can start painting within the lines.

 

Aren't you describing technical debt?

I feel that adding features as soft dependencies like that is generally a bad idea, because your code now contains the new code, the old code and extra code to figure out which one to use. Every time you integrate a new, new feature, you'll need to make sure it works with the legacy code too.

I can't see how that is going to work in a big project. You'll have to spend extra time and resources unpicking the legacy stuff at some point anyway, right?

If it works for you and your team, sure, go for it, but I think most people would be better off using separate feature branches.

 

I politely disagree with this approach although it might work for 5 people team in your case, the scary part is we are human and we don’t make the best decision all the time another thing i like about the git flow branching/PR is it gives you safe space to prototype and to get good feedback from your collegues, especially if someone is new to the project they feel safer to contribute.
For the daily meeting i personally find it unproductive as you can write everything you want to discuss in the PR on the exact piece of code which is very important to get some context.

 

After reading a bit of the discussion below, I'll add that it is very important to align with widely accepted industry methodologies and standards, because it greatly increases the transferability of skills, enabling any dev to walk in and contribute on day one, which cuts onboarding time and cost, and makes your shop more attractive to perspective talent.
If you're going to deviate from a known and accepted branching strategy, or any standard, you have to come at me with a masters level thesis that's been vetted by the industry for a few years with good review.
This method seems convoluted and without merit of a problem to solve in the first place.

 
each of them paints their part without even looking at what their partners are doing

This is the real problem. If you rebase regularly then you are looking at what your partners are doing and those same meetings are a great way to still communicate.

I'm curious how well "feature toggling" scales. Do you remove the toggle at some point or do you have to leave them there forever?

 

Definitely controversial, but I can't say I'm convinced that mainstream branching tactics are absolutely the way to go.

I also look forward to some comments here.

 
 

Not sure I’ve ever disagreed with anything more.

Why not just rebase master/develop into your feature branch more often?

 
 

It sounds like you don't know how to use git or work as part of a team.

 
 

Use smaller branches. Merge often. Rebase whenever upstream changes.

 

Get a real job on a real project, you'll quickly be sorry when some jackass ruins the build & checks in crap. Code reviews & pre-sanitizing a feature-branch for the win

 

For small teams it may work. For large open source projects it will be challenging to avoid conflicts.

 

Should we now go back to copying code to USB sticks instead of git clone xD

 

The best way to get the right answer on the Internet isn't to ask the question, but to provide the wrong answer. 👍

 

TL;DR: branching on git is wrong because I don’t understand how to use it.

 

Having branching paths in the production app for features sounds like an awful idea.

 

That is why have a planning phase. So that everybody has a copy of what the final painting should look like, before they start painting.

 

That's a nice goal, but in practice? Rarely achievable.

 

I think you're using Git wrong brother. You should be using Subversion instead.

 

Making parallels between landscape painting and development doesn't look good for this case, imo

 

hei. here is a better idea.

lets use a usb stick to keep the code, pass it to each other and hope for the best. We can upload it when the deadline is upon us.

 

And, while we're at it, let's just go back to Subversion. Git's too complicated and branching in Subversion is so abominably hard that it will discourage their usage.

 

Here we are. We write push and press enter. We blame push of pushing early. We are so bad. 🎃
Do not push if the floor is dry. 🎃

 

This is what rebase is for. Keep your local branches local and rebase frequently from a common develop branch. That keeps everyone in sync and allows individuals complete control over their own repo.

 

Job application would be denied if someone came to our place with this philosophy. Give you credit for justifying it, but on larger products this causes more harm than good

 

I thought this was going to be about git flow. Now I'm just awkwardly standing here my with my terminal sitting at "git checkout -tb".

 

Branching is really great! You just don't have to divide indivisible and wait for 2 weeks to merge it all together

 

I'm even more thoroughly convinced that Dev.to is a highly functionally click bait site purely devoted to trolling its visitors with inflammatory and ridiculous content. If that happens to not be the case I pray to Bob I never ever have to work on the same Dev team as the author. He is clearly as opinionated as he is ignorant.

code of conduct - report abuse