原文
A successful Git branching model
In this post I present the development model that I’ve introduced for all of my projects (both at work and private) about a year ago, and which has turned out to be very successful. I’ve been meaning to write about it for a while now, but I’ve never really found the time to do so thoroughly, until now. I won’t talk about any of the projects’ details, merely about the branching strategy and release management.
這篇文章,將介紹所有一年前我工作中或者個(gè)人項(xiàng)目的開(kāi)發(fā)模型,這個(gè)模型已經(jīng)被證明是十分有用的(successfull)。我老早就想寫(xiě)一些關(guān)于這個(gè)模型的文章,但是總是抽不出時(shí)間。在這篇文章中,我將不會(huì)介紹項(xiàng)目的詳細(xì)情況,僅僅對(duì)分支的策略和發(fā)布管理作一個(gè)介紹。
It focuses around
Git as the tool for the versioning of all of our source code.
我們將圍繞這使用
Git作為所有項(xiàng)目源碼的版本控制工具。
For a thorough discussion on the pros and cons of Git compared to centralized source code control systems,
see the web. There are plenty of flame wars going on there. As a developer, I prefer Git above all other tools around today. Git really changed the way developers think of merging and branching. From the classic CVS/Subversion world I came from, merging/branching has always been considered a bit scary (“beware of merge conflicts, they bite you!”) and something you only do every once in a while.
關(guān)于Git作為集中的源碼控制系統(tǒng)的優(yōu)缺點(diǎn),可以查看一下
鏈接,關(guān)于這個(gè)話題,有激烈的爭(zhēng)論。作為一個(gè)開(kāi)發(fā)者,與其他版本控制工具相比,我更喜歡Git,Git真正的改變了開(kāi)發(fā)者關(guān)于合并和分支的思考(think)。我曾經(jīng)也用過(guò)CVS、svn,分支和合并,真的很讓人頭疼(合并時(shí)產(chǎn)生的沖突),因此,有時(shí)你每次只能做一會(huì)工作(個(gè)人理解:因?yàn)閟vn這種版本控制庫(kù)只有一個(gè)服務(wù)倉(cāng)庫(kù),涉及公共資源,只能鎖定編輯)
But with Git, these actions are extremely cheap and simple, and they are considered one of the core parts of your
daily workflow, really. For example, in CVS/Subversion
books, branching and merging is first discussed in the later chapters (for advanced users), while in
every Git book, it’s already covered in chapter 3 (basics).
但是對(duì)于Git來(lái)說(shuō),做這樣的工作(分支、合并),太簡(jiǎn)單!它真的可以作為你日常工作流程中最核心的部分。例如,在有關(guān)CVS/svn的
書(shū)籍中,分支和合并要放到最后一章才會(huì)闡述(針對(duì)高級(jí)用戶(hù)),然后在Git相關(guān)的
書(shū)籍中,首先就先跟你闡述分支和合并(第3章)。
Enough about the tools, let’s head onto the development model. The model that I’m going to present here is essentially no more than a set of procedures that every team member has to follow in order to come to a managed software development process.
關(guān)于這個(gè)工具的介紹,我們不再贅述,現(xiàn)在我們回到開(kāi)發(fā)模式的話題上來(lái)。這個(gè)模型,基本上和每個(gè)開(kāi)發(fā)團(tuán)隊(duì)管理軟件開(kāi)發(fā)流程是類(lèi)似的。
The repository setup that we use and that works well with this branching model, is that with a central “truth” repo. Note that this repo is only considered to be the central one (since Git is a DVCS, there is no such thing as a central repo at a technical level). We will refer to this repo as origin
, since this name is familiar to all Git users.
我們使用這個(gè)分支模型很好工作的倉(cāng)庫(kù),是真正意義上的中央倉(cāng)庫(kù)。這個(gè)倉(cāng)庫(kù)是唯一的中央倉(cāng)庫(kù)(因?yàn)镚it本身就是分布式版本控制系統(tǒng)DVCS,所以這沒(méi)有技術(shù)問(wèn)題)。我們稱(chēng)這樣一個(gè)中央倉(cāng)庫(kù)為origin,所有Git用戶(hù)都知道origin這個(gè)名稱(chēng)。
Each developer pulls and pushes to origin. But besides the centralized push-pull relationships, each developer may also pull changes from other peers to form sub teams. For example, this might be useful to work together with two or more developers on a big new feature, before pushing the work in progress to origin
prematurely. In the figure above, there are subteams of Alice and Bob, Alice and David, and Clair and David.
每個(gè)開(kāi)發(fā)者,都可以從origin獲得(pull)資源,同時(shí)也能推送(push)到origin。除此之外,每個(gè)開(kāi)發(fā)者可以從其他開(kāi)發(fā)者那里獲得資源,以此組建自己的一個(gè)小組。例如,當(dāng)我們要開(kāi)發(fā)一個(gè)大的新功能時(shí),我們將和其他人一起協(xié)作,在提交到中央倉(cāng)庫(kù)origin之前,我們需要小組內(nèi)部能夠互相協(xié)作,這將是十分有用的。上圖中,Alice和Bob是一個(gè)小組,同時(shí)Alice和David是一個(gè)小組,Clair和David又是一個(gè)小組。
Technically, this means nothing more than that Alice has defined a Git remote, named bob
, pointing to Bob’s repository, and vice versa.
從技術(shù)實(shí)現(xiàn)上講,這無(wú)非是在Alice的項(xiàng)目里,定義了一個(gè)指向Bot的遠(yuǎn)程鏈接而已(git remote add bob git@bobserver bob.git),反之也是一樣,如此簡(jiǎn)單!!

At the core, the development model is greatly inspired by existing models out there. The central repo holds two main branches with an infinite lifetime:
中央倉(cāng)庫(kù)有2個(gè)主要的分支,這些分支將一直存在:
The master
branch at origin
should be familiar to every Git user. Parallel to the master
branch, another branch exists called develop
.
中央倉(cāng)庫(kù)的master分支已經(jīng)為所有Git用戶(hù)熟知,與master分支并行的另外一個(gè)分支,我們稱(chēng)之為develop。
We consider origin/master
to be the main branch where the source code of HEAD
always reflects a production-ready state.
我們稱(chēng)origin/master為主要分支,因?yàn)榉种У腍EAD指向的源碼總是反映了一個(gè)可以發(fā)布的產(chǎn)品狀態(tài)(production-ready)。
We consider origin/develop
to be the main branch where the source code of HEAD
always reflects a state with the latest delivered development changes for the next release. Some would call this the “integration branch”. This is where any automatic nightly builds are built from.
我們稱(chēng)origin/develop為主要分支,因?yàn)榉种У腍EAD指向的源碼,總是反映了下次發(fā)布前最新提交的開(kāi)發(fā)代碼。有些人稱(chēng)之為“集成分支”(integration barnch),因?yàn)槲覀兊拿客碜詣?dòng)構(gòu)建都是基于此分支進(jìn)行的。(例如hudson,可以做自動(dòng)構(gòu)建工作)。
When the source code in the develop
branch reaches a stable point and is ready to be released, all of the changes should be merged back into master
somehow and then tagged with a release number. How this is done in detail will be discussed further on.
當(dāng)develop分支的源碼穩(wěn)定并且準(zhǔn)備發(fā)布,所有的改變應(yīng)該合并(merge)到master分支,同時(shí)做一個(gè)發(fā)布版本的標(biāo)簽(tag),我們將在后面討論這個(gè)細(xì)節(jié)。
Therefore, each time when changes are merged back into master
, this is a new production release by definition. We tend to be very strict at this, so that theoretically, we could use a Git hook script to automatically build and roll-out our software to our production servers everytime there was a commit on master
.
因此,當(dāng)每一次將所有更改合并回master時(shí),將會(huì)產(chǎn)生一個(gè)新的可以發(fā)布的產(chǎn)品狀態(tài)。我們往往對(duì)于這個(gè)操作的控制是比較嚴(yán)格的,每當(dāng)往master分支提交時(shí),我們可以使用Git的hook來(lái)自動(dòng)構(gòu)建和轉(zhuǎn)出到產(chǎn)品服務(wù)器上。