21 ms·
A successful Git branching model (2010)
- nstj 9y ago@dang this is old
- otp124 9y agoIt's okay if it's old, but it should have a (2010) year tag to inform potential readers.
- watt 9y agoThe advice here given to avoid using "master" branch for development, and advice to create non-default branch named "develop" (or variations thereof) is quite harmful. If you must have a "release" branch or "stable" branch, ok, go for it, but leave the "master" for developing. Why? Strive to have sane defaults. Frankly, the idea that somebody must check out some extra special branch after cloning repo in order to start properly developing, is not sane.
- brad0 9y agoI'm assuming you think it's harmful because master is the branch committed to and pushed by default?
- watt 9y agoYes, 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, always remember if you used "development" as base". and then the mistakes eat up lot of cycles in the end.
- madeofpalk 9y agoall they've done is just rename master.
- _chris_ 9y agoI 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.
- rleigh 9y agoPeople 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 not even that helpful for an end user. master can change on a whim, while using actual release tags gives you something stable.
- geezerjay 9y ago> 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.
- viraptor 9y agoYou can have both. With the right tooling you can prevent direct push to master, but at the same time implement CI to which you can submit your branches to be merged to master. This way you can develop against master, you won't push garbage into it by mistake, and you can guarantee that each (first-parent path) commit on master passes the automated tests.
- jph 9y ago> Leave the "master" for developing. IMHO do developing always on topic branches, never on master. This keeps master available for fully-working software, such as for the most-recent successful build using continuous integration, or for always-available deployment, or for external users, etc. To create topic branches, here are git alias commands that you can customize as you like for your git workflows: topic-start = "!f(){ b=$1; git checkout master; git fetch; git rebase; git checkout -b "$b" master; };f" topic-finish = "!f(){ b=$(git branch-name); git checkout master; git branch -d "$b"; git push origin ":$b"; };f" branch-name = rev-parse --abbrev-ref HEAD
- watt 9y agoWhat'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 the branch, and do point release from the branch: problem solved. That's if the client running the (older) release version is large enough to justify releasing hotfix instead of doing fix to main stream and just asking to upgrade to latest release. Yes to topic branches. Yes to "cactus model" of rebasing the topic to master. No to the idea that you need extra long-lived "develop" branch in parallel to master.
- sillysaurus3 9y agoI was researching some of this a few weeks ago, and there are many posts about tags being a bad idea. The arguments are that they have to be maintained separately and they lack context. But yes, master branch master race. Also related: "What are the problems with 'a successful Git branching model'?" https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/ https://barro.github.io/2016/02/a-succesful-git-branching-mo... Speaking of bad ideas, anyone want to weigh in on merge commits? I've seen arguments in favor of using `git rebase` everywhere, both ways, and to never squash commits. This makes `git bisect` usable, since you never run into a situation where it points to a massive commit as the problem. On the other hand, that seems pretty terrible from a `git log` perspective, since many commits are WIP. But maybe it's not a big deal. My bigger concern is that merge commits provide real context: whenever you merge a topic branch into master, it seems to make sense to have a merge commit for that entire operation. But wouldn't that cause `git bisect` to always point to that merge commit rather than one of the smaller commits?
- balladeer 9y agoI don’t think this article gives advice to not use master for development but rather what it means is: 1. master must only have stable, tested, and production (not production “ready”) code and nothing else 2. If something in production breaks the hotfix should go into master and strive to achieve step 1 In fact this is really a good model. Keeps development streamlined and disciplined. This has nothing to do with breaking the idea of having sane git defaults. In fact it’s a sane utilisation of defaults. Non default branching is a necessity anyway. Default branch usually means just a master branch and committing directly into master, I believe, would lead to disaster. If one has to create branches it should be done for lifestyle steps below production.
- mcv 9y agoFor a moment I thought: Has someone figured out something better than git-flow? But no, it's the original git-flow article again. It's good, but now exactly "news". Every git user should be aware of git-flow, even if you do have a better way of using git.
- imron 9y ago> Every git user should be aware of git-flow Agree. Every git user should be aware of it and should use it on a project at least once so they know to avoid it forever after.
- Froyoh 9y agoWhy avoid it?
- Rafert 9y agoBecause it's complicated and most people don't need that complexity at all. For some reason a lot of people happily jumped on the band wagon when this was released and started writing scripts to make it more bearable. If you have multiple versions of your codebase that you need to maintain for a longer time to justify those release branches, gitflow might be for you. IMO GitLab flow is much more applicable for most people: https://about.gitlab.com/2014/09/29/gitlab-flow/ https://about.gitlab.com/2014/09/29/gitlab-flow/
- imron 9y agoBecause it creates a large amount of needless busywork. It's much easier to develop on master and/or on feature branches that can be cleanly merged in to master, and then tag master (or create branches) once a release is hit. See for example the simple git workflow: https://www.atlassian.com/blog/git/simple-git-workflow-simple https://www.atlassian.com/blog/git/simple-git-workflow-simpl...
- mcv 9y agoIt's not awful, but there is room simplify it and tune it for your own needs. Using master as the develop branch is a fairly simple and sensible one. Most simpler workflows are basically git-flow trimmed down in some way. In a big team, I do like to keep release branches to isolate the polishing of the release from other development work. (Without it, teams tend to have a code freeze, which is unnecessary with a release branch.)
- bschwindHN 9y agoOh I guess no one has posted it this month, let's argue about git again.
- Sujan 9y ago(2010)
- stonewhite 9y agoThis was very much valid before the docker workflows came to happen. Now maintaining two mainline branches forces you to break "don't build a container per environment" cardinal rule. Trunk based development should be the go-to repository strategy for dockerized apps.
- icebraining 9y agoWhat's the purpose of that rule?
- stonewhite 9y agoIf you properly externalized the configurations, Docker provides bit-by-bit parity between environments granted you use the same image. This results in increased confidence to test environments and lessening the chances of a surprise during production deployments. It is the next logical step in immutable deployment paradigm[1]. [1]: https://martinfowler.com/bliki/ImmutableServer.html https://martinfowler.com/bliki/ImmutableServer.html
- icebraining 9y agoBut why not use the typical solution of having two testing environments, in this case based on "develop" and "master", with the latter being bit-by-bit equal to what gets deployed?
- stonewhite 9y agoWhat purpose does it serve but to double QA efforts. If you are testing the same stuff both in develop and master, why not just test only one and save some time. Ramming gitflow into a docker workflow efficiently is not really possible I believe.
- twic 9y agoThat's a good rule, and a correct deduction from it. However, it's not new to Docker workflows - you shouldn't build a good old fashioned binary per environment either!
- mabbo 9y agoI'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 seem to pass CI). The time between code being written and a bug being seen can be reduced to minutes and hours, making finding the root cause a breeze. Just my preference, but very open to debate.
- sillysaurus3 9y agoFeature 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 release code and strip out the disabled feature flags? With what? - What do you use to control feature flags? Just a json file filled with `"foo-bar-feature": true/false`, or something more sophisticated like a control panel that you can use to say "10% of our users will see this feature"?
- NicoJuicy 9y agoWho says no one is embracing them? There are tons of tools available if you check for it. But you should google for "feature toggle" libraries and not feature flags
- mabbo 9y ago> How do you prevent your codebase from becoming if-statement spaghetti? A valid point- if you're not careful that can happen. Key things: remove those ifs after a launch, and launch fully or remove the feature; consider 'hiding' the ifs behind factories that build the objects that implement the different logic; also, if you have 20 features is development for the same area of your codebase, worry- you may be trying too much! > How do you prevent new features from being leaked to the user? I haven't had to worry about this very often just based on my projects, but there are strategies. You could be sending the user a different version of the js/html based on the feature flags (preprocessor as you said). Haven't had to do that, but woah that would be a fun little project. > What do you use to control feature flags? My favorite implementation was an S3 json file that effectively encoded a decision tree based on variables used. In code, we could say "here are the five variables about this request, feature object are you enabled?". By modifying that json file, you could change the features state at run time. (Note: this was not perfectly implemented/designed by me and caused a few issues when we first used it. Oops. But you can do very quick solutions too, read a file or make an object that decides based on non-dynamic logic.
- mkempe 9y agoI've used the git-flow approach successfully with a small team working on a medical product (so, embedded software system) -- every feature branch had to be reviewed before being merged with `develop`, which was submitted to nightly, extensive functional tests (initially one-hour long, eventually kept as a nightly subset of the more than 24-hours complete QA run) before it could be approved as a new (monthly) release and be merged with `master`. Every new feature branch was automatically treated to quick continuous integration tests, and available for manually-triggered full functional tests (on the target devices). This approach ensured that we had a full trace of development work, (signed) code reviews, and software changes -- compatible with FDA audits. We also automated collection of code coverage data during functional tests, to inform analysis and revisions of the battery of functional tests.
- hdhzy 9y agoInteresting. How did you do signed code reviews?
- mkempe 9y agoWe used PRs with BitBucket for all code reviews. The reviewer(s) had to digitally sign their final approval of the review comments+answers and of the related code changes, if any. The only way to merge a feature branch into `develop` was via the PR + code review process.
- hdhzy 9y agoWas it something like exporting PR history to a file and then signing (X.509/PGP)? Thanks for answers, it looks like a nice, lightweight auditable system.
- mkempe 9y agoNo, simpler than that; we used the BitBucket web interface to enter the approval message and click the approved button to allow for merge. These actions are recorded and visible in the overview page of the PR. However the BitBucket server's web interface was not approved/validated for long-term storage and evidence for the audit trail, so the PR owner was responsible (before triggering the merge) for saving a PDF copy of that PR page and committing the PDF file into a git-controlled code-review directory. So it's digitally signed to the extent that your account/identity is recorded in the approval step and in the collection of PDFs. I did ask about a more systematic export method but it was not considered important given the PDF-based approach.
- kuharich 9y agoPrior discussion: https://news.ycombinator.com/item?id=1966820 https://news.ycombinator.com/item?id=1966820
- xydinesh 9y agoGitLab has a good discussion on Git flow too. https://about.gitlab.com/2014/09/29/gitlab-flow/ https://about.gitlab.com/2014/09/29/gitlab-flow/
- Froyoh 9y agoHow is this feasible for projects worked on by multiple development teams?
- activatedgeek 9y agoIt 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 master and the diversion for a while). Delete the diversion once the job is done. If you are never able to delete the diversion, it is not your git branching model that failed, it is you and your code who failed. Diversions may be long term (and I hope you have the workforce to maintain that branch as well) but still finite time. How to prepare that diversion is a software engineering problem and not git's fault.
- rtpg 9y agoHow does this work if you have multiple ongoing changesets? I'm often working in 3 different features at once, all needing to be merged separately in the review process
- gregmac 9y agoMerge from master back to your branch. This is how my team handles merge conflicts: your branch must cleanly merge for the pull request to be approved (which means you must resolve conflicts in your branch first). If there are two branches that may conflict in terms of functionality (but not at a source level) we call that out, and have the people involved reviewing both. When it comes time to merge, we usually merge the first one done to master, merge master to the second, then do extra testing in the second branch before merging it. Sometimes if we know one branch blocks the other, we simply merge one to the other, but then still go to master separately. This makes the pull request review much simpler and keeps the code isolated while not duplicating effort. This works best when a big bug has a quick and simple but incomplete fix, and a more risky and complex but complete fix, or when there's multiple aspects to a new feature. We can decide to ship the first branch earlier if necessary.
- activatedgeek 9y agoThat is a standard problem you face in all projects and the conflict resolution generally happens on a First Come First Serve basis. Of course, the maintainer could decide it on the basis of priority and then the person merging to master next is responsible to fix the new conflicts.
- antoncohen 9y agoDo 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 branch. If you do Continues Delivery you don't need "hotfix" branches because every changes goes out as soon as it is ready, so you don't need any of the complexity of Git Flow. By saving up changes for a release event it means more things are getting released at once. If there is a problem after deployment it will be harder to narrow down the cause. Git Flow fosters a harmful development mentality where developers merge untested changes to the develop branch, then move on, and expect someone to test and stabilize their changes before release. With trunk-based development (https://trunkbaseddevelopment.com/ https://trunkbaseddevelopment.com/) or GitHub Flow (https://guides.github.com/introduction/flow/ https://guides.github.com/introduction/flow/) developers take ownership of their code, and only merge to master after they have tested it. With a good deployment pipeline they can own their code all the way to production. 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. The artifact systems (packages, containers, etc.) may need something, but it can just be an incrementing number that no on thinks about. Git Flow wastes so much time, and makes everything it touches so complex, all to enable the harmful behavior of saving up changes for later, and enabling the pointless use of version numbers. Trunk-based development and Continues Delivery is the default way people develop, it is how you would work if you had a one person company with one customer. It also is how the biggest web companies in the world work. It scales from smallest to largest. Just use trunk-based development. Stay away from Git Flow. Edit: Fixed spelling of incrementing.
- ddlatham 9y agoAn incriminating number indeed.
- geezerjay 9y ago> 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/ http://semver.org/