GitFlow is a branching model created by Vincent Driessen on 2010 ( ). Since it was published, many companies had tested and implemented it, which allows us to have many reviews about how well (or not) it works. After some discussions within our team, we decided to not go with GitFlow, but use a simpler model instead, together with a tightly defined workflow. Some of the discussed reasons of why not go with GitFlow are the same written on . original article this blog post The Feature Branch Model Compared to GitFlow, it is easier to implement and does not require any plugins to be properly used. The step-by-step of this model would be: Create a branch from the master (feature-x), which is where the feature will be developed: git checkout -b feature-x Push the branch to the remote: git push -u origin feature-x. With the branch in the remote repo, a pull request should be opened with it ( ). A pull request is where all modifications are available to other members and they will be able to review it How to open it in GitHub Fix the reviewed code and wait for approval. If a new release on the master generates a conflict, a best practice would be to rebase it (instead of merging) (optional) If a rebase is needed: checkout to master git checkout master, pull the changes git pull, go back to the feature branch git checkout feature-x, do the rebase git rebase master and then sync the rebased branch git push --force-with-lease . . A good tutorial about merging x rebasing is available on this Atlassian article If there are no conflicts and it was approved ⇒ squash + merge This Atlassian article have a more detailed view on the feature branch model Why Squash + Merge instead of just Merge? The squash and merge is made up of two processes: the squash, which compact all commits in one big commit/patch, and then the merge itself. After squashing + merging, you will have only one commit in the target branch (usually master) containing all your modifications. This enables two things: It is easier to move this feature, as the whole patch/feature will be on one commit hash The target branch will be cleaner, less messy and more readable — without those 67 commits you have made to finish the feature. There are more information about . about why devs prefers squash and merge, instead of only merging, on this article Managing release versions with git tags In the feature branch model, a merge is considered a new version release. To track each release version, tags can be used. These will be used as reference to choose which version should be deployed at the servers. To manage these tags/release, a good practice is the usage of semantic versioning : Given a version number , increment the: MAJOR.MINOR.PATCH 1. MAJOR version when you make incompatible API changes, 2. MINOR version when you add functionality in a backwards-compatible manner, and 3. PATCH version when you make backwards-compatible bug fixes. The process to create the releases can be automated using or . But, following the steps bellow, it can be easily done by hand: grunt-release gulp-release-tasks Checkout to the master branch: git checkout master Pull changes from the remote git pull Get the most recent tag using git describe --abbrev=0 (let's say it returns v0.1.0) Create a tag using git tag -a <version>⇒git tag -a v0.2.0 Push the modifications and the tag: git push origin v0.2.0 --follow-tags Done! Deploying In many PaaS, such as AWS Beanstalk or Heroku, a remote repository is set-up where, when changes are pushed (eg. git push heroku master), a deploy is triggered using the latest commits on master. In these cases, a simple push force using the release tag will deploy the desired version: git push -f <deploy/env-remote> v0.2.0^ :master. Easy, eh? {} NOTE: At Chaordic New Offers Team, a grunt script was developed where we publish which tag should be deployed: grunt deploy:<version>:<env>:all What happens if a hot-fix is needed? At some point, an issue will be raised and the production version will need a hot-fix . A feature branch can't just be opened to develop a fix, as the master will probably be ahead of the production version. In this case, the fix needs to be done directly on the production version: ASAP Checkout to the production version tag git checkout v0.10.0 Create a new branch from this tag git checkout -b hotfix-v0.10.1-weirdbehavior Create the fix and commit it Create a tag for this new release git tag -a v0.10.1 (notice the SEMVER pattern) Push the branch and tag to remote git push -u origin hotfix-v0.10.1-weirdbehavior --follow-tags Deploy the tag v0.10.1 to the production environment A push request should be opened, as the fix should be applied at the master afterwards If more patches are needed, this process can be repeated on the same version, incrementing only the patch version. <a href="https://medium.com/media/364660922d3d96660250608a21ca716a/href">https://medium.com/media/364660922d3d96660250608a21ca716a/href</a> What about applying it to other environments? This patch probably should be applied to other environments as well, which can be done through <commit-hash> . It basically applies the chosen commit to the actual HEAD. git cherry-pick Checkout to the environment version tag git checkout v0.13.0 Create a new branch for the patch git checkout -b hotfix-v0.13.1 Do a git cherry-pick v0.10.1 or a git cherry-pick <commit-hash> to apply the desired commit git tag -a v0.13.1 and git push origin v0.13.1 (push just the tag) Deploy it What if I want to get a modification from master and sent to one of the environments? It is very similar to the above one: a git cherry-pick should be done using a commit hash from the master as, after a push request, a new commit is generated with all changes (big patch of commits condensed in one). squash + merge Just keep in mind… The gap between the environments versions should be as short as possible. Otherwise, some issues may appear: If the production is on v0.1.10, the latest release is v0.10, but the version v0.3 will be deployed: the team members will have to check if some of the production patches are still required and then apply them, one by one. If some feature was only finished on v0.10.0, and it is required for the roll-out, but the v0.7.0 is still not well tested: the release should be hold until the v0.7.0 has been tested Usually, these version gaps occur when the producing capacity is higher than the testing capacity (developers x testers ratio). Conclusion The model is still being tested but, until now, it has been working well. The only faced drawbacks were the ones pointed on the session above.