{"id":1985,"date":"2011-04-27T16:31:09","date_gmt":"2011-04-27T19:31:09","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=1985"},"modified":"2016-09-28T10:31:14","modified_gmt":"2016-09-28T13:31:14","slug":"a-successful-git-branching-model","status":"publish","type":"post","link":"https:\/\/blog.plataformatec.com.br\/2011\/04\/a-successful-git-branching-model\/","title":{"rendered":"A (successful) git branching model"},"content":{"rendered":"
*This blog post tells about how we improved a VCS workflow to another one that suited our and the consumer needs. It was a great result: we minimized the chances of occurring one of the worst problems for a developer in a project: big integration while we maintained an ‘almost releasable branch’ all the time<\/em><\/p>\n In the last months we’ve been working on a project with a mixed development team (Plataformatec’s team and the customer’s team). We, of course, used a version control system (specifically git) and we set up a nice git branching model for our team. As agilists, we know that we should not use anything that requires a lot of bureaucracy (things like opening a ticket to integrate a branch into the trunk).<\/p>\n Using nvie guide<\/a> as base, we developed a git workflow. First of all, we had three main branches:<\/p>\n For each feature that we developed, we created a git branch (almost all of them we pushed it to the remote server to facilitate code review and to deploy to the “dev” environment). Everyday, we ran Close to the production deploy, we merged (always using –no-ff) master branch into staging branch and deploy to staging. Once approved, we merged to production, and created a tag telling the current version of the application and then we do the deploy. When we deployed to production we also removed the merged branches from the remote repository.<\/p>\n One of the great advantages of this schema is: Master is always “almost” ready for a release. Yeah, some features really deserves to be validated right before the deploy, because another feature can break them, but we kept the master as an “always releasable stable” branch (and also we used a continuous integration tool in order to enforce all tests passing). Another great advantage is: as we updated our code everyday, it was very\u00a0unusual\u00a0for us to face big integration scenarios.<\/p>\n For the “dev” environment deploy we also set up a capistrano task that asks which branch we want to deploy to be possible to deploy something from any branch.<\/p>\n This workflow has worked really well for us and maybe it is useful to you (maybe for you to adapt it to something that works better for you as we did with the workflow suggested on nvie<\/a>).<\/p>\n To summarize, this is our git workflow in commands (supposing that we are on master branch): Well, this is how we improved a git workflow based in another one. As almost everything, there is no bullet proof for it, but we found interesting to share this experience with you as it was a success (every developer on the team enjoyed it). But please, we would like to receive some feedback about it :-). Have you used something similar in your team? Do you have any ideas on how we can improve it?<\/p>\n","protected":false},"excerpt":{"rendered":" *This blog post tells about how we improved a VCS workflow to another one that suited our and the consumer needs. It was a great result: we minimized the chances of occurring one of the worst problems for a developer in a project: big integration while we maintained an ‘almost releasable branch’ all the time … \u00bb<\/a><\/p>\n","protected":false},"author":12,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[1],"tags":[147,149,148],"aioseo_notices":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/1985"}],"collection":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/comments?post=1985"}],"version-history":[{"count":36,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/1985\/revisions"}],"predecessor-version":[{"id":5706,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/1985\/revisions\/5706"}],"wp:attachment":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/media?parent=1985"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/categories?post=1985"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/tags?post=1985"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}\n
git rebase master<\/code>, to update our branch code (except for features developed by more than one developer). Once the feature is complete, we rebased master into it, and merge it using –no-ff (to create a merge commit). For the branches that more than one developer worked on, we usually talked and set up a “rebase period” where one does the rebase, forces the push (because you changed your local tree so git does not accept it as a non forced push) and updates the remote branch.<\/p>\n
\n
\ngit checkout -b my-awesome-feature<\/p>\n(... you do some code and some commits and you go home to have some sleep or maybe play some starcraft 2 ...)<\/code><\/h1>\n
#(arrived at the office on the next day)
\ngit rebase master<\/code><\/p>\n#(... continue working and commiting and sleeping (or maybe playing some starcraft 2 ...)
\ngit rebase master<\/code><\/p>\n# (... some commits ... and voila ... you've finished...)
\ngit push origin my-awesome-feature
\ncap dev deploy
\n<\/code><\/p>\n# (...YAY! QA analyst just approved it ...)
\ngit pull origin master
\ngit rebase master
\n<\/code><\/p>\n# (run the tests to ensure all of them pass)
\ngit checkout master
\ngit pull --rebase origin master
\ngit merge --no-ff my-awesome-branch
\ngit push origin master<\/code><\/p>\n#(... it is time to validate on staging)
\ngit checkout staging
\ngit pull origin staging
\ngit merge --no-ff master
\ngit push origin staging
\ncap staging deploy<\/code><\/p>\n#(... QA analysts validate the staging ...)
\ngit checkout production
\ngit merge --no-ff staging
\ngit tag -a v1.4.2 -m \"Releasing on 13th February\"
\ngit push origin production
\ngit push --tags origin production
\ncap production deploy
\n<\/code><\/p>\n