Live data from Hacker News

A successful Git branching model (2010)

nvie.com

101–110 of 121 posts

Re: A successful Git branching model (2010)

#101
post #15

I've got a much nicer branching model- try not to have one. Everyone works off master, and you aren't allowed to check in code that won't run in production. Hide unfinished features behind feature flags, and never merge/push a change that won't pass tests/CI. The chaos of huge feature merges (a key source of bugs I've experienced) is minimized. You deploy fixes hourly, not weekly (or later monthly when it just won't…

> I've got a much nicer branching model- try not to have one. Everyone works off master, and you aren't allowed to check in code that won't run in production. Hide unfinished features behind feature flags, and never merge/push a change that won't pass tests/CI.

You've just described a naive implementation of the Git branching model described in the article which fails to meet some basic real-world requirements experienced on all software development projects. It matches the policy of merging changes from the development branch onto the master branch but lacking any support for very basic aspects of software development such as code auditing, versioning, and continuous integration.

It's silly to let everyone work off master if master is supposed to remain stable. If master is supposed to host stable versions, someone needs to be responsible for keeping it stable. If someone is assigned the task of ensuring the master branch is kept stable then he needs to control what gets into master and what doesn't. If someone needs to control what gets into master then other developers need to commit their changes to some other branch.

Add parallel releases and couple of levels of these real-world everyday aspects of software development and you get exactly the branching model described by Vincent Driessen in his blog post.

Re: A successful Git branching model (2010)

#102
post #51

Earlier quoted context omitted.

I think from the perspective of the central repository, this is a sane approach. Locally though, you should still be routinely using (short-lived) feature branches. Working directly off master on your local machine can make things annoying / complicated when you need to move away from your work for a moment (say to fix a bug) and don't have a good representation of "what's currently on production". Also, I think this…

Depending on the frequency of your deploys you can simply add release branches or tags to the “work on master” model. Any decent deployment system can deploy from an arbitrary arbitrary ref, plus release history in your git log is very useful. The point here is to eliminate long lived feature branches that require their own maintenance.

> Depending on the frequency of your deploys you can simply add release branches or tags to the “work on master” model.

...and then you get the git workflow described in the blog post.

It only takes a single regression to learn the importance of separating the development branch from the main branch.

Re: A successful Git branching model (2010)

#103
post #63

Earlier quoted context omitted.

You remove the feature flag checking code when you turn off or turn on the feature. It's an extra deploy, but it needs to be part of the prod/eng process. This is the most salient issue of feature flagging in my experience and something you need to get ahead of from the get-go. I don't understand. I was asking about the development source code, not the code delivered to the user. The dev source code isn't stripped of…

> The dev source code isn't stripped of if-statements, right? When I use a feature flag as an alternative to branching, then I delete the if statements once the feature becomes permananent and gets released to all users. It's analogous to merging a branch. Obviously I'd leave it there during QA and A/B testing, but once toggling is no longer necessary, I remove the toggle. > Ok, but how? Assume an express server. You…

> I delete the if statements once the feature becomes permananent

Right. In theory. Does this really scale when there's more than a dozen developers touching the same code paths? It's not just you scratching off your own TODOs, it's multiple entagled condiditionals. Can you really delete your flags with confidence that this does not affect any other code path?

Which brings me to my real question: How you you guys test this stuff? When I have experimented with feature flags before this has been to much detriment for testing. Suddenly the new payment API our provider will launch in June needs to be tested with the new backend we'll launching Tuesday, and with the new asynchronous database driver our DBAs wants us to migrate to. And so on. The complexity explodes. Especially when the features have dependencies external to you.

When everything is in master and everything must be in shippable condition you need to test everything with everything else, while previously the new payment API in June could live in it's own branch and test on their own schedule and not bother everyone else everytime the payment provider's test environment took a nosedive for some reason.

So you either end up with brittle tests that can take days to execute, or you end up scratching a lot of the less pressing combinations. Which brings us to the situation above. How can you then be confident to remove conditionals without testing the newly exposed code paths?

It is so far my suspicion that most people who speak of feature flags as an alternative to branches either work with trivial products where most developers fit in a small room (in which you are not the use case for these things) or talk out of some theoretical conviction which has yet to meet with reality. These things are hard, because of all those details which seem small if you squint enough.

Re: A successful Git branching model (2010)

#104
post #15

I've got a much nicer branching model- try not to have one. Everyone works off master, and you aren't allowed to check in code that won't run in production. Hide unfinished features behind feature flags, and never merge/push a change that won't pass tests/CI. The chaos of huge feature merges (a key source of bugs I've experienced) is minimized. You deploy fixes hourly, not weekly (or later monthly when it just won't…

Feature flags are a nice idea, but nobody outside of Facebook seems to be embracing them. The tooling just isn't there. Some concrete questions: - How do you prevent your codebase from becoming if-statement spaghetti? - How do you prevent new features from being leaked to the user? They'll see the new features in the front end source code. At many companies this isn't an acceptable tradeoff. So do you preprocess the…

Feature flags _are_ widely used. They generally manifest as commented out code. Like many features that migrate down from these massive codebases it's a common behaviour thats been systematised.

Re: A successful Git branching model (2010)

#105
post #7
post #5

Earlier quoted context omitted.

I'm assuming you think it's harmful because master is the branch committed to and pushed by default?

Yes, because master is the default implicit branch. (Now, in git is possible to designate other branch as default, but folks who follow the advice in article often are not experienced enough to do it.) I know a team that runs this branching model. It's quite surprising to hear statements "we never commit to master branch". "after cloning, always remember to switch to development branch". "when creating pull request,…

all they've done is just rename master.

Re: A successful Git branching model (2010)

#106
post #16
post #13

Earlier quoted context omitted.

What's the point of running CI on a branch that's effectively for tracking releases only? We run CI on master branch and fix any build breaks or regressions immediately. (That's the job of unit tests and integration tests.) In fact, if your team is smaller, you do release from master branch directly, just tag the release revisions. Then if you need to hotfix it, check out the tag, make a branch, cherrypick a fix to t…

> What's the point of running CI on a branch that's effectively for tracking releases only? I'm recommending using master as the output of a successful continuous integration, and thus always ready for release. I'm rejecting any git flow that has any developer pushing any code directly to master, while hoping/guessing that master branch integration will succeed. Caveat: Bugs will still happen. Caveat: There are more-…

> There are more-advanced release processes such as blue/green

Blue/green is actually very similar to the Git branching model of forking release branches off of the development branch to merge them in the master branch, if not precisely the same thing referred by different names.

Re: A successful Git branching model (2010)

#107

It is good exercise to actually learn this branching model and then use it in practice. You will soon realize that most projects will suddenly start taking unnecessary toll on you just because now you want to maintain multiple branches and it is a huge PITA. Instead just follow this simple routine - stay as close to the master as possible. If a temporary diversion is needed, create a new branch (and maintain both mas…

Yea I find this "successful" branching model in OP to be a huge pain. It does sound nice in theory but it's annoying in practice and honestly I see absolutely no benefit in adopting it.

Re: A successful Git branching model (2010)

#108
post #39
post #9

Earlier quoted context omitted.

I find the idea that master is the default is exactly why it should not be the development branch. For open-source software, that's what people download and try to build -- it should always strive to be production ready.

People should be downloading actual releases. This could be release archives, or release tags. Version control is not primarily for consumption of releases, it's for participation in development, and I think the branching strategy should reflect that. Having the current development state be the default branch is entirely suitable for this purpose. I've always found the use of "develop" vs "master" quite jarring, and…

> People should be downloading actual releases. This could be release archives, or release tags.

Yes, and those versions are represented by tags created on the master branch. Github automatically interprets tags created on the master branch as being releases, and even creates nice little tar files with the branch's contents.

> master can change on a whim

Actually, it can't. According to the Git workflow, the only thing committed to the master branch is either the contents of release branches or hotfixes.

Re: A successful Git branching model (2010)

#109

Do not use Git Flow for a web application deployed on your own infrastructure (SaaS, microservice, mobile backend, etc.). It will slow down development and make your software less reliable. The entire purpose of Git Flow is saving up changes to release later, e.g., saving up for a weekly release event. Don't do that! Deploy your changes as soon as they are ready, if they aren't ready don't merge them into a shared br…

> Git Flow also encourages humans to think about and make up version numbers, like 15.0.5. This is a pointless waste of brain power, web apps don't need version numbers.

Version numbers are used to represent specific states of the project in order to have fixed testable and auditable versions. It's what the user sees when he needs to check which software version he's using when talking about the software he's using, and what programmers need to know when they need to work on bugs/features present in previous versions of the software but not on others. If your app needs to be debugged and there are peopleother than yourself using, testing or working on the software, it needs version numbers. Otherwise, everyone will needlessly waste their time.

Version numbers waste as much brain power as knowing the name of someone you need to contact on a daily basis. You don't need to make up version numbers because plenty of people already did that. For instance, Semantic Versioning is a thing.

http://semver.org/

Re: A successful Git branching model (2010)

#110
post #63

Earlier quoted context omitted.

> The dev source code isn't stripped of if-statements, right? When I use a feature flag as an alternative to branching, then I delete the if statements once the feature becomes permananent and gets released to all users. It's analogous to merging a branch. Obviously I'd leave it there during QA and A/B testing, but once toggling is no longer necessary, I remove the toggle. > Ok, but how? Assume an express server. You…

> I delete the if statements once the feature becomes permananent Right. In theory. Does this really scale when there's more than a dozen developers touching the same code paths? It's not just you scratching off your own TODOs, it's multiple entagled condiditionals. Can you really delete your flags with confidence that this does not affect any other code path? Which brings me to my real question: How you you guys tes…

To be clear, I personally use branching a lot (e.g., for sprint-sized features) and I create new feature flags rather infrequently (for multi-sprint sized features or for A/B tests), and only for pretty large features. But I can see reasons why some teams/environments do go, or want to go, feature-flag always. Before git, feature toggles were more widespread as a workflow.

As far an entanglement with other code, I would evaluate this wrt branching. If it's entangled, the branching analogy is a merge conflict. The most common case is you can delete the toggle without conflict, and occasionally you have to spend ten or twenty minutes untangling. Every once in a rare while it gets messier.

For testing, the prod tests run the prod config, which is likely with all optional feature toggles turned off. My team would run our own tests with our feature toggles turned on, but not with other teams' feature toggles. I don't run all combinations of features. Usually, a feature toggle will also wrap new tests that belong to that feature.

Again, the same question you ask applies to a branch workflow. Do you run all possible branches at the same time? Is it an exponential combinatorics problem to have multiple branches? Not really, each team runs the tests for the features they work on. Same either way.

The great thing about feature flags for testing is that you have greater control over who is exposed to your new feature. With a feature toggle, you can expose some teams in your company outside of your own, without exposing the whole company. You can expose 10% of your customers and do testing without inflicting bugs you didn't forsee on 100% of your customers. If there's an emergency, you can limit the damage radius with a well designed feature flag. Branches can do this only to the extent that the merge structure allows it, and they can't help with customer testing.

> It is so far my suspicion that most people who speak of feature flags as an alternative to branches either work with trivial products [...] or talk out of some theoretical conviction which has yet to meet with reality

I think I know why you feel that way, but that sounds (to me) like you haven't been exposed to (and so can't imagine) workflows outside of git branching. I mean no insult, but you are jumping to conclusions from lack of experience. Feature toggles as a pseudo-branching workflow predate git by decades, they are used on the largest codebases in the world -- did you miss the comments in this thread from MS and Google?

Feature flags are used in nearly all repos where branching exists. It's not one or the other, you can use both workflows at the same time. A/B testing is based on feature toggles, and all sizable websites on the web are doing A/B testing constantly. Chances are high that you use them already and just haven't yet recognized that they're the same thing we're talking about. If you have config files for your project, then you have feature toggles. If you ever change a value in one of them, then you could instead branch your code, remove the config variable and rewrite the code that used to reference the feature flag to be hard coded instead. Is that making sense?

FWIW, just to put some specifics and back up my own 'conviction' with real world examples, I've been on teams that used feature toggles to test and ship features during the production of several animated films, movies you probably saw. When I worked in film, it predated git. We had a hierarchical repo, but there were no branches, only pushing to master and feature flags.

When I worked in games, the team I lead used feature flags to support cross-team testing on a $1B console franchise.

At a certain web company, in addition to constant A/B testing, my team shipped features to customers who signed up to be on the 'beta' versions of features before they were rolled out to all of the >1M users. We used feature flags to control which teams internally could see & test certain features, and we used feature flags for either long-running or large cross-team features when branching & merging would cause undue amount of branch noise.

And at my own startup now, I prefer to wrap my features in feature flags even when I'm branching. That way I can back out a feature when it causes problems or has bugs without having to do git surgery or even risk a merge conflict. With a few thousand active customers, this has saved my ass multiple times.

Post reply on HN