血糖高忌吃什么| 什么是配速| 感冒不能吃什么| 脂蛋白a高吃什么能降下来| 章鱼吃什么食物| 什么动物最安静| 清华大学什么时候成立| 孕晚期羊水多了对宝宝有什么影响| 静脉曲张 看什么科| 7.4是什么星座| 什么手什么脚| 侍中是什么官| 瓜子脸适合什么刘海| 落汤鸡是什么意思| 菊花什么时候扦插最好| 老鼠疣长什么样子图片| 竣字五行属什么| 什么样的白云| 情人是什么意思| 印度人为什么不吃猪肉| 吃饭是什么意思| 垂头丧气什么意思| 非私营单位是什么| 割包皮属于什么科| 老天爷叫什么名字| 什么是黄道吉日| 肺炎吃什么药最有效| 肠胃不舒服挂什么科| 皮疹是什么样子的| 盐酸西替利嗪片主治什么| 蝉的鸣叫声像什么| 属马是什么星座| 56年属什么生肖| 手术后发烧是什么原因| 糖尿病病人吃什么水果| 焦虑症是什么原因引起的| 木加一笔有什么字| 蜘蛛侠叫什么| 雪松香是什么味道| 吃什么能增肥最快| 中性粒细胞百分比高是什么原因| au是什么货币| 湿疹吃什么药好| 肉蒲团是什么意思| 护士规培是什么意思| 口引念什么| 中国国鸟是什么鸟| 老年脑改变是什么意思| 罗红霉素胶囊治什么病| 2007属什么生肖| 喜欢趴着睡是什么原因| 嗜睡是什么病| 膝盖疼吃什么药| 心火大吃什么药| 排比句是什么意思| 忠字五行属什么| 6月19日是什么节日| 夏至是什么生肖| 什么是关键词| mri什么意思| 1213是什么日子| 脾肾两虚吃什么中成药最好| 手心发红是什么原因| 手指麻木是什么原因| 性价比高什么意思| 小孩疳积有什么症状| 芸字五行属什么| 欲钱看正月初一是什么生肖| 为什么说秦始皇还活着| 梦到兔子是什么征兆| 卡介疫苗什么时候打| 嗜碱性粒细胞偏高是什么原因| 钟馗是什么人物| 书签是什么| 满月送什么礼物好| 什么的枫树| 圆是什么结构| 肠梗阻是因为什么原因引起的| 74年大溪水命缺什么| 为什么老是梦见一个人| 一蹴而就什么意思| 脾虚吃什么食物| 指甲盖有竖纹是什么原因| 此起彼伏是什么意思| 日照香炉生紫烟的香炉是什么意思| 骆驼是什么品牌| 周围神经病是什么症状| 治疗阴虱子用什么药最好| 人为什么会衰老| 烂漫是什么意思| 龟吃什么食物| 腰椎疼痛是什么原因| 编外人员是什么意思| 手上脱皮是什么原因| 杨桃长什么样| 尿毒症是什么原因导致的| 尿hcg阳性是什么意思| 密送是什么意思| 旨在是什么意思| 失眠缺什么维生素| 嫂嫂是什么意思| 胎记长什么样| 高血钾是什么意思| 周期性是什么意思| 相夫教子是什么意思| 南京区委书记什么级别| 哪吒为什么叫哪吒| 接地气是什么意思| 蛇信子是什么| 什么什么为什么| 什么的城堡| 处男是什么| 白带呈绿色是什么原因| 人工念什么字| 瓜怂是什么意思| dhea是什么药| 丙肝是什么病| 为什么大熊猫是国宝| 外人是什么意思| 缺铁吃什么好| 热火朝天是什么生肖| 手术室为什么那么冷| 基因病是什么意思| 眉毛痒痒代表什么预兆| 什么马不能跑| 跑完步想吐是什么原因| 腋下黑是什么原因| 冬占生男是什么意思| 补钙多了有什么坏处| 吃什么可以让奶水增多| 巨蟹座是什么性格| hcg值低是什么原因| 巨蟹和什么星座最配| 过堂是什么意思| 川芎有什么功效| 五经指什么| 吃青椒有什么好处| 什么药补气血效果最好| 睡觉出汗是什么原因男性| 牙龈肿痛发炎吃什么药| 心火大吃什么药| 为什么会拉水| 肺主皮毛是什么意思| 粉色史迪仔叫什么| 宫腔内偏强回声是什么意思| 开小灶是什么意思| 新生儿湿疹抹什么药膏| 奇行种什么意思| 为什么会得淋巴肿瘤| 疱疹是什么病啊| 为什么会有高血压| yair是什么牌子的空调| 英语四级什么时候报名| 尼特族是什么意思| avg是什么意思| 农历十月是什么月| 多吃木耳有什么好处和坏处| 凉拌菜用什么醋最好| 两岁宝宝不会说话但什么都知道| atc是什么意思| 招字五行属什么| 嘱托是什么意思| 腥辣食物指的是什么| 狗吃什么蔬菜好| 爱而不得是什么意思| 小孩发育迟缓是什么原因造成的| 苹果熬水喝有什么功效| 什么酒不能喝脑筋急转弯| 男戴观音女戴佛有什么讲究| 布洛芬0.3和0.4g有什么区别| 晚睡早起是什么原因| 每天吃一根黄瓜有什么好处| 小孩子注意力不集中看什么科| 子夜是指什么时间| 面瘫挂什么科| 来月经喝什么好| 12月是什么月| 煤气罐在什么情况下会爆炸| 舞象之年是什么意思| 溶媒是什么| 下颌骨紊乱挂什么科| 什么叫阳性| 红色加黑色是什么颜色| 肚脐眼痒是什么原因| 心肌缺血吃什么好| 钓鲤鱼用什么饵料| 术后可以吃什么水果| 31岁属什么生肖| 什么是腱鞘炎| 脑电图是检查什么的| 流产什么样的症状表现| 蟑螂的天敌是什么| 月经来了不走是什么原因| 绿巨人是什么意思| 经常打嗝是什么原因| 施食是什么意思| d二聚体是什么| 女人绝经是什么症状| 胎盘植入是什么意思| 357是什么意思| 初三什么时候毕业| 患得患失是什么意思| beauty是什么意思| 鹦鹉能吃什么| 生姜和红糖熬水有什么作用| 为什么会突然不爱了| hp值是什么意思| 为什么会骨盆前倾| 吃什么补免疫力最快| 王字旁和什么有关| 心肾不交失眠吃什么中成药| 婴儿湿疹用什么药膏最有效| 浸润癌是什么意思| 冲服是什么意思| ch发什么音| 自愿离婚要带什么证件| 妇检是检查什么| 沙土地适合种什么农作物| 经常咬手指甲是什么原因| 尿常规异常是什么意思| 小孩改姓需要什么手续| 什么无终| 什么是梅毒| 子宫复旧是什么意思| epr是什么| 察言观色是什么意思| skechers是什么牌子| 打更是什么意思| 红色的海鱼是什么鱼| 头晕在医院挂什么科| mg什么单位| 羊日冲牛是什么意思| 喝枸杞子泡水有什么好处和坏处| 大便干燥吃什么药| 出其不意下一句是什么| 眉毛上长痣代表什么| 主意正是什么意思| 犟是什么意思| 什么的芦花| 产后漏尿是什么原因| 载体是什么| 总是放屁是什么原因| hpv52型阳性是什么意思严重吗| 白介素是什么| 肺炎吃什么药| 腰肌劳损什么症状| 河堤是什么意思| 尿酸高是什么问题| 肠炎吃什么| 什么是易孕体质| 美国是什么洲| 身上长瘊子是什么原因| pearl是什么意思| 刘五行属什么| 为什么肚子疼| 为什么突然对鸡蛋过敏| 五步蛇为什么叫五步蛇| 心火旺吃什么中药| 豆浆不能和什么一起吃| 急性胃肠炎用什么抗生素| 口腹蜜剑什么意思| 白细胞偏高有什么危害| 喜欢吃冰的是什么原因| 喜大普奔是什么意思| 百度
?? Latest post:
"Why .every() on an empty list is true"
By Vincent Driessen
on Tuesday, January 05, 2010

Note of reflection (March 5, 2020)

百度 此后不久,美国另一大运营商Verizon也终止了华为手机的销售。

This model was conceived in 2010, now more than 10 years ago, and not very long after Git itself came into being. In those 10 years, git-flow (the branching model laid out in this article) has become hugely popular in many a software team to the point where people have started treating it like a standard of sorts — but unfortunately also as a dogma or panacea.

During those 10 years, Git itself has taken the world by a storm, and the most popular type of software that is being developed with Git is shifting more towards web apps — at least in my filter bubble. Web apps are typically continuously delivered, not rolled back, and you don't have to support multiple versions of the software running in the wild.

This is not the class of software that I had in mind when I wrote the blog post 10 years ago. If your team is doing continuous delivery of software, I would suggest to adopt a much simpler workflow (like GitHub flow) instead of trying to shoehorn git-flow into your team.

If, however, you are building software that is explicitly versioned, or if you need to support multiple versions of your software in the wild, then git-flow may still be as good of a fit to your team as it has been to people in the last 10 years. In that case, please read on.

To conclude, always remember that panaceas don't exist. Consider your own context. Don't be hating. Decide for yourself.

In this post I present the development model that I’ve introduced for some 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.

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.

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 as origin, 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 to origin prematurely. 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, named bob, pointing to Bob’s repository, and vice versa.

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

The master branch at origin should be familiar to every Git user.?Parallel to the master branch, another branch exists called develop.

We consider origin/master to be the main branch where the source code of HEAD always reflects a production-ready state.

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.

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.

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.

Supporting branches

Next to the main branches master and develop, 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.

Feature branches

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

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 into develop (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 in origin.

Creating a feature branch

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

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

Incorporating a finished feature on develop

Finished features may be merged into the develop branch to 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-ff flag 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-ff flag was used.

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

Release branches

May branch off from:
develop
Must merge back into:
develop and master
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, the develop branch is cleared to receive features for the next big release.

The key moment to branch off a new release branch from develop is 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 to develop at 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, the develop branch 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.

Creating a release branch

Release branches are created from the develop branch. For example, say version 1.1.5 is the current production release and we have a big release coming up. The state of develop is 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.sh is 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 the develop branch). Adding large new features here is strictly prohibited. They must be merged into develop, and therefore, wait for the next big release.

Finishing a release branch

When the state of the release branch is ready to become a real release, some actions need to be carried out. First, the release branch is merged into master (since every commit on master is a new release by definition, remember). Next, that commit on master must be tagged for easy future reference to this historical version. Finally, the changes made on the release branch need to be merged back into develop, so that future releases also contain these bug fixes.

The first two steps in Git:

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2

The release is now done, and tagged for future reference.

Edit: You might as well want to use the -s or -u <key> flags to sign your tag cryptographically.

To keep the changes made in the release branch, we need to merge those back into develop, though. In Git:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)

This step may well lead to a merge conflict (probably even, since we have changed the version number). If so, fix it and commit.

Now we are really done and the release branch may be removed, since we don’t need it anymore:

$ git branch -d release-1.2
Deleted branch release-1.2 (was ff452fe).

Hotfix branches

May branch off from:
master
Must merge back into:
develop and master
Branch naming convention:
hotfix-*

Hotfix branches are very much like release branches in that they are also meant to prepare for a new production release, albeit unplanned. They arise from the necessity to act immediately upon an undesired state of a live production version. When a critical bug in a production version must be resolved immediately, a hotfix branch may be branched off from the corresponding tag on the master branch that marks the production version.

The essence is that work of team members (on the develop branch) can continue, while another person is preparing a quick production fix.

Creating the hotfix branch

Hotfix branches are created from the?master branch. For example, say version 1.2 is the current production release running live and causing troubles due to a severe bug. But changes on develop are yet unstable.?We may then branch off a hotfix branch and start fixing the problem:

$ git checkout -b hotfix-1.2.1 master
Switched to a new branch "hotfix-1.2.1"
$ ./bump-version.sh 1.2.1
Files modified successfully, version bumped to 1.2.1.
$ git commit -a -m "Bumped version number to 1.2.1"
[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
1 files changed, 1 insertions(+), 1 deletions(-)

Don’t forget to bump the version number after branching off!

Then, fix the bug and commit the fix in one or more separate commits.

$ git commit -m "Fixed severe production problem"
[hotfix-1.2.1 abbe5d6] Fixed severe production problem
5 files changed, 32 insertions(+), 17 deletions(-)

Finishing a hotfix branch

When finished, the bugfix needs to be merged back into master, but also needs to be merged back into develop, in order to?safeguard?that the bugfix is included in the next release as well. This is completely similar to how release branches are finished.

First, update master and tag the release.

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2.1

Edit: You might as well want to use the -s or -u <key> flags to sign your tag cryptographically.

Next,?include the bugfix in develop, too:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)

The one exception to the rule here is that,?when a release branch currently exists, the hotfix changes need to be merged into that release branch, instead of develop. Back-merging the bugfix into the release branch will eventually result in the bugfix being merged into develop too, when the release branch is finished. (If work in develop immediately requires this bugfix and cannot wait for the release branch to be finished, you may safely merge the bugfix into develop now already as well.)

Finally, remove the temporary branch:

$ git branch -d hotfix-1.2.1
Deleted branch hotfix-1.2.1 (was abbe5d6).

Summary

While there is nothing really shocking new to this branching model, the “big picture” figure that this post began with has turned out to be tremendously useful in our projects. It forms an elegant mental model that is easy to comprehend and allows team members to develop a shared understanding of the branching and releasing processes.

A high-quality PDF version of the figure is provided here. Go ahead and hang it on the wall for quick reference at any time.

Update: And for anyone who requested it: here’s the gitflow-model.src.key of the main diagram image (Apple Keynote).


Git-branching-model.pdf

Other posts on this blog

If you want to get in touch, I'm @nvie on Twitter.

野合什么意思 女生的隐私长什么样子 氩弧焊对身体有什么危害 花非花雾非雾什么意思 A型血为什么是完美血型
什么人不能吃榴莲 鱼字五行属什么 胎心不稳定是什么原因 挚肘是什么意思 骨关节炎是什么原因引起的
多多益善什么意思 骨科是什么意思 移情是什么意思 六月是什么夏 位置是什么意思
两栖动物是什么意思 想改名字需要什么手续 为什么新生儿会有黄疸 苦瓜和什么搭配最好 甲钴胺片有什么副作用
蒙奇奇是什么动物hcv9jop6ns6r.cn 肾的功能是什么weuuu.com 急性咽喉炎吃什么药好得快hcv8jop3ns7r.cn 950是什么金hcv8jop3ns3r.cn 疝气吃什么药效果好hcv7jop6ns8r.cn
双规是什么adwl56.com 勾芡用什么粉最好hcv8jop8ns2r.cn 为什么得带状疱疹hanqikai.com 兰蔻是什么品牌hcv7jop5ns1r.cn 记忆力减退是什么原因造成的hcv8jop6ns4r.cn
甲状腺饱满是什么意思hcv9jop7ns3r.cn 肠腔积气是什么原因beikeqingting.com 藤原拓海开的什么车hcv9jop5ns2r.cn 生理期吃什么比较好hcv9jop3ns7r.cn 茶水费是什么意思0735v.com
什么时候不容易怀孕hcv8jop9ns6r.cn 坐月子什么不可以吃hkuteam.com 燕京大学现在叫什么hcv7jop7ns3r.cn 孕期什么时候补充dhahcv7jop4ns7r.cn 在农村做什么hcv9jop3ns6r.cn
百度