介绍一个成功的 Git 分支模型 已翻译 100%

Joe Guo 投递于 2013/02/25 11:21 (共 15 段, 翻译完成于 03-01)
阅读 58712
收藏 292
Git
50
加载中

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.

It focuses around Git as the tool for the versioning of all of our source code.

已有 1 人翻译此段
我来翻译


Why git?

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.

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).

As a consequence of its simplicity and repetitive nature, branching and merging are no longer something to be afraid of. Version control tools are supposed to assist in branching/merging more than anything else.

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.

已有 1 人翻译此段
我来翻译

Decentralized but centralized

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 asorigin, since this name is familiar to all Git users.

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 tooriginprematurely. In the figure above, there are subteams of Alice and Bob, Alice and David, and Clair and David.

Technically, this means nothing more than that Alice has defined a Git remote, namedbob, pointing to Bob’s repository, and vice versa.

已有 1 人翻译此段
我来翻译


The main branches

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:

  • master
  • develop

Themasterbranch atoriginshould be familiar to every Git user. Parallel to themasterbranch, another branch exists calleddevelop.

We considerorigin/masterto be the main branch where the source code ofHEADalways reflects a production-ready state.

已有 1 人翻译此段
我来翻译


We considerorigin/developto be the main branch where the source code ofHEADalways 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.

When the source code in thedevelopbranch reaches a stable point and is ready to be released, all of the changes should be merged back intomastersomehow and then tagged with a release number. How this is done in detail will be discussed further on.

Therefore, each time when changes are merged back intomaster, 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 onmaster.

已有 1 人翻译此段
我来翻译


Supporting branches

Next to the main branchesmasteranddevelop, our development model uses a variety of supporting branches to aid parallel development between team members, ease tracking of features, prepare for production releases and to assist in quickly fixing live production problems. Unlike the main branches, these branches always have a limited life time, since they will be removed eventually.

The different types of branches we may use are:

  • Feature branches
  • Release branches
  • Hotfix branches

Each of these branches have a specific purpose and are bound to strict rules as to which branches may be their originating branch and which branches must be their merge targets. We will walk through them in a minute.

By no means are these branches “special” from a technical perspective. The branch types are categorized by how we use them. They are of course plain old Git branches.

已有 1 人翻译此段
我来翻译


Feature branches

May branch off from: develop
Must merge back into: develop
Branch naming convention: anything except master,develop,release-*, orhotfix-*

Feature branches (or sometimes called topic branches) are used to develop new features for the upcoming or a distant future release. When starting development of a feature, the target release in which this feature will be incorporated may well be unknown at that point. The essence of a feature branch is that it exists as long as the feature is in development, but will eventually be merged back intodevelop(to definitely add the new feature to the upcoming release) or discarded (in case of a disappointing experiment).

Feature branches typically exist in developer repos only, not inorigin.

已有 1 人翻译此段
我来翻译


Creating a feature branch

When starting work on a new feature, branch off from thedevelopbranch.

$ git checkout -b myfeature develop
Switched to a new branch "myfeature"


Incorporating a finished feature on develop

Finished features may be merged into thedevelopbranch definitely add them to the upcoming release:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop


The--no-ffflag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature. Compare:

In the latter case, it is impossible to see from the Git history which of the commit objects together have implemented a feature—you would have to manually read all the log messages. Reverting a whole feature (i.e. a group of commits), is a true headache in the latter situation, whereas it is easily done if the--no-ffflag was used.

Yes, it will create a few more (empty) commit objects, but the gain is much bigger that that cost.

Unfortunately, I have not found a way to make--no-ffthe default behaviour ofgit mergeyet, but it really should be.

已有 1 人翻译此段
我来翻译


Release branches

May branch off from: develop
Must merge back into: developandmaster
Branch naming convention:release-*

Release branches support preparation of a new production release. They allow for last-minute dotting of i’s and crossing t’s. Furthermore, they allow for minor bug fixes and preparing meta-data for a release (version number, build dates, etc.). By doing all of this work on a release branch, thedevelopbranch is cleared to receive features for the next big release.

The key moment to branch off a new release branch fromdevelopis when develop (almost) reflects the desired state of the new release. At least all features that are targeted for the release-to-be-built must be merged in todevelopat this point in time. All features targeted at future releases may not—they must wait until after the release branch is branched off.

It is exactly at the start of a release branch that the upcoming release gets assigned a version number—not any earlier. Up until that moment, thedevelopbranch reflected changes for the “next release”, but it is unclear whether that “next release” will eventually become 0.3 or 1.0, until the release branch is started. That decision is made on the start of the release branch and is carried out by the project’s rules on version number bumping.

已有 1 人翻译此段
我来翻译


Creating a release branch

Release branches are created from thedevelopbranch. For example, say version 1.1.5 is the current production release and we have a big release coming up. The state ofdevelopis ready for the “next release” and we have decided that this will become version 1.2 (rather than 1.1.6 or 2.0). So we branch off and give the release branch a name reflecting the new version number:

$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
1 files changed, 1 insertions(+), 1 deletions(-)


After creating a new branch and switching to it, we bump the version number. Here, bump-version.shis a fictional shell script that changes some files in the working copy to reflect the new version. (This can of course be a manual change—the point being that some files change.) Then, the bumped version number is committed.

This new branch may exist there for a while, until the release may be rolled out definitely. During that time, bug fixes may be applied in this branch (rather than on thedevelopbranch). Adding large new features here is strictly prohibited. They must be merged intodevelop, and therefore, wait for the next big release.

已有 1 人翻译此段
我来翻译
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(20)

Phoenix4458
Phoenix4458
relaese分支第二段
"当在Release分支完成这些所有工作以后,对于下一次打的发布,develop分支接收features会更加明确。"翻译的很有问题
宅男小何
宅男小何
我想知道最左边那条分支为什么没有merge 中间的develop分支,因为在最左边那条分支merge到develop分支中途有其他分支merge到develop分支
l
linsea

引用来自“spudhsu”的评论

全局添加--no-ff可以通过
git config --global --add merge.ff false
来完成
参考:http://stackoverflow.com/questions/2500296/can-i-make-fast-forwarding-be-off-by-default-in-git

我也是觉得这个模式蛮好的,但是测试环境是个问题啊如果developer上有东西要测比较久,有一部分又是要尽快上线的,这种模式就难办了。
这个简单嘛, 可以再临时开个分支, 测试完成了, cherry-pick 选择需要的提交, 合并进目标分支就好了.
DarkAngel
DarkAngel

引用来自“Hu_JiaJun”的评论

请问“Bumped version number to 1.2.1”是什么意思啊?因为我在commit里面看到这句话,一直不理解这是什么意思?哪位好心人可以为我解答一下!非常感谢!
就是说版本直接跳到了1.2,而不是在1.1.5的基础上慢慢增加,比如1.1.6、1.1.7
DarkAngel
DarkAngel
“完成一个release分支”这一段是机器翻译的么?
DarkAngel
DarkAngel
发现翻译中有好几个小错误,不知道该怎么办
Hu_JiaJun
Hu_JiaJun
请问“Bumped version number to 1.2.1”是什么意思啊?因为我在commit里面看到这句话,一直不理解这是什么意思?哪位好心人可以为我解答一下!非常感谢!
假正经哥哥
假正经哥哥
受益非浅啊
lonpo
lonpo

引用来自“ruanjf”的评论

引用来自“耀耀”的评论

我挺好奇他是用什么工具画的图(==)

我也想知道

mac电脑上的keynote
ruanjf
ruanjf

引用来自“耀耀”的评论

我挺好奇他是用什么工具画的图(==)

我也想知道
返回顶部
顶部