首页 > SCM > Git开发最佳实践

Git开发最佳实践

回头想想老夫工作已两年余了,在这两年里面有一年半是用Git作为代码版本控制工具的,自从接触到Git,老夫可以说很快就成为了其一个脑残粉,被Git的易用性的强大功能所吸引,上周和我们team的小伙伴们分享了一下老夫以前Git的使用心得(当然分享的效果很不理想,实在是失误),还好老大赏识,让老夫结合自己之前的使用经验整理一个Git的开发规范流程,以供公司项目由SVN迁移到Git之后,大伙统一规范开发,刚好老夫也愿意趁此机会,整理一下自己的思路,结合自己以前使用经验,放在自己的Blog上,以供所有看到这篇文章的小伙伴参考,且大言不惭,定为:Git开发最佳实践。需要说明的是看这篇文章的人,老夫默认为对Git已经有了一定的基础,如果没有请看老夫之前写的这篇文章
其实老夫窃以为Git的开发规范其实最重要的就是Git的分支管理,而分支又分远程分支和本地分支,本文将从远程应该存在哪些分支、本地应该存在哪些分支、为什么要存在这些分支、在这些分支上应该有哪些操作、这些分支的作用以及这些分支的生命周期一一说明。

一、远程

远程分支是由于我们开发人员在和同组小伙伴相互合并代码而生的,如果不是这我们可以不要远程分支,在远程应该存在三种类型的分支:master分支、feature分支和hotfix分支,记着这里说的是三种类型的分支而不是三个分支,下面将对此三种类型的分支一一解释。

1. master分支

首先说master分支的生命周期,master分支是生命周期最长的分支,他诞生于项目一开始,结束语项目的废弃,也就是master分支的生命是同步于项目的,只要项目存在就有这个分支;
master分支上的操作:因为我们所有的操作都只能是在本地,所以远程分支实际上是可以认为没有任何操作的;
master分支的作用:master分支①、是新建项目的默认分支,它不存在也就不存在项目,②、master分支上始终只能是最新的经过测试的可以正常跑的代码,③、每一个里程碑式的版本(可以理解为上线版本)都必须在此分支上打版本号,并注明为什么打此版本号,以供运维上线和将来万一回滚之用,同样也是我们查询我们每一次上线版本历史记录的依据;
为什么要有master分支:同步项目生命而默认而存在的,不可能没有,也不能没有。

2. feature分支

feature分支是功能分支,开发新功能的时候创建,所以feature分支永远应该(记得是应该)是依托于最新版本的master上分支的代码而建立的,该master可以是远程master也可以是本地master分支,后面我会说明原因;
feature分支的生命周期,feature分支生命周期应该是仅次于master分支的,他在我们开发新功能的时候创建,在我们完成新功能(即完成了测试等一系列流程,可以上线了)的时候生命终止,为避免远程分支太多太乱,可以删除;
feature分支上的操作:上文已经说过远程分支实际上是可以认为没有任何操作的;
feature分支的作用:就是我们基于最新代码开发新功能而用,仅此而已;
为什么存在feature分支:一言以蔽之,基于我们开发新功能时不相互影响,具体来说虽然没有此分支也是可行的,但如果不存在该分支,可能的后果,team中A开发了一个新功能,直接提交到了master上,测试人员在测试中,此时team另一个成员B开发了另一个新功能也提交到了master上,并且测试也已经完成,需要紧急上线,但由于master上有A提交的未经测试的代码,上线就会存在风险,如果不上线,大家都懂得,故必须存在此分支。

注:feature分支是开发新功能的时候创建的,所以如果我们同时开发多个新功能,那么远程就会同时存在多个feature分支

3. hotfix分支

hotfix分支可以理解为线上代码出现紧急bug时,为修复此bug为紧急建的一个分支,因为是为修复线上系统出现的紧急bug而生,所以其也应该是依托于最新版本的master分支上的代码而建立的。
hotfix分支因为是为修复紧急bug而生,那么其生命周期是随bug的出现而出现,随bug的修复而终止;
hotfix分支也是远程分支,同样可以认为没有任何操作;
hotfix分支的作用,自然就是修复线上系统出现的紧急bug而生;
至于为什么存在该分支,看了上面就不用多说了吧;
好了,远程的三种类型的分支说完了之后,我们就应该说本地存在哪些分支了

二、本地

本地是我们开发人员在本地为开发各种新功能、修各种bug而建的分支,我们开发人员所有的操作可以认为都是在这些分支上,同样和远程存在多个分支一样,本地也会存在多种类型的分支:master分支、feature分支、hotfixe分支和dev分支,同样这里说的是四种类型的分支而不是四个分支,下面同样对这些分支一一说明。

1. master分支

不错,不仅只有远程有master分支,本地也有一个master分支和远程对应,其的出现也是在我们clone远程分支时而默认出现的,既然本地master是和远程master分支对应的,所以他的生命周期也是显而易见的;
在这里也可以解释一下,远程feature和hotfix为什么既可以基于远程master分支而建,也可以是基于本地的,因为本地的master分支是和远程对应的;
本地master分支上的操作:在本地master分支只允许出现四种操作:pull、push、merge、rebase,其余的一律不允许出现,记着这个要求还是非常高的,另外他pull的是远程master分支上的代码,push也是把本地master分支上的代码推送到远程master分支上,而merge和rebase当然是merge和rebase的feature分支了;
本地master的作用:1. 除非本地没有代码,否则本地就会出现该分支,但不出现又有什么意义呢,2. 合并其他已经开发完成的feature分支,然后把这些代码一并推送到远程master分支上,3. 在本地master分支上新建tag,并把这些tag推送到远程,供运维上线;
为什么存在该分支,也不用说了吧。

2. feature分支

同样本地feature分支是和远程feature分支对应,在我们开发新功能的时候,不可能只有一个远程的分支,而本地没有,因为如果本地没有的话,我们又怎么开发呢,所以这就是为什么存在本地feature分支;
看了存在本地feature分支之后,本地feature分支的生命周期也就出来了,和远程feature分支是一样的;
本地feature分支的操作:在本地feature分支上,原则上只允许存在:pull、push、merge、rebase,记着这是原则上,并没有本地master分支的要求高,在本地feature分支行如果有其他操作也是可以的,但之所以这么要求只要出现这四种操作,是为了将来和同组的小伙伴合并代码方便,如果不这么做代码也是能合并的,但如果一旦出现冲突,合并起来会稍麻烦。
需要说明的,本分支push到的是远程feature分支,pull的也是远程feature分支,而merge和rebase的是基于其建的dev分支的代码

3. hotfix分支

有了本地master分支和本地feature分支的说明,所以聪明人肯定猜出来了,本地hotfix分支也是和远程hotfix分支是对应的,那么生命周期自然相同;
相信从上面的说明中,和这些分支名字上我们就可以看出,hotfix和feature分支本质上是一样的,仅仅是feature分支是开发的一个大功能,需要多人协作多天才能完成,而hotfix大多都是一些比较紧急的、需要立马修复的一个小功能而已,所以在他上面的操作一个是和feature分支一样的,存在的原因自然是为了修复线上紧急bug而存在的。

4. dev分支

说完了以上三种类型的分支,下面就是最常见的dev分支了,他是没有一个分支和远程对应的,他也是我们开发中日常操作的一个分支;
根据上面的说明,无论是开发一个新功能还是修复一个紧急bug是,都会在本地建一个对应的分支,而在这些分支上只允许出现那四种操作,所以其他的操作就只能在这个分支上了,也就是说,我们在开发一个新功能的时候,我们应该基于本地的feature分支创建一个dev分支,在这上面开发我们的新功能,开发完成后合并到本地feature分支上,然后推送到远程feature分支上,供测试人员进行测试,测试人员对该新功能测试完成后,合并到本地master分支上,最后一并推送到远程master分支上,打tag,上线。

说完了,远程、本地应该有哪些分支,这些分支的作用、生命周期之后,下面列出一些要用到的几个重要的命令

三、分支管理用到的几个最重要的命令

1. 本地master分支推送到远程,也就是创建远程分支 feature


git push origin master:feature

注意此命令的“冒号”前后不要加空格,否则会报错。当然也可以用下面的命令,也是我习惯的命令,先在本地基于 master 分支创建 feature 分支,然后把本地 feature 分支推送到远程,也就是现在 master 分支上执行第一个命令,会创建本地并切到 feature 分支上,然后在本地 ferture 上执行第二个命令


git checkout -b feature
git push origin feature:feature

当然创建远程 feature 分支,除了用命令外,还可以是用 Gitlab 和 gerrit 的 web 界面创建

2. 和同事协作的时候,同事已经在远程创建 feature 分支,我们直接可以在本地创建自己的 feature 分支


git checkout -b feature origin/feature

3. 本地已有 feature 分支,从远程 feature 分支上拉取代码到本地分支,也就是同步远程 feature 分支代码


git pull origin feature

如果你的分支是按照老夫上面第二个命令的方式创建的分支,也可以这么做


git pull

如果不行的话,需要使用命令,git 会有提示


git branch --set-upstream feature origin/feature

4. 推送当前修改到远程 feature 分支


git push origin feature:feature

5. 删除远程 feature 分支


git push origin :feature

6. 上线的版本号


git tag -a v1.0.0 -m ‘1.0.0  time:15-08-13 11:13;'
git push --tags

洋洋洒洒一大篇,终于完成了这篇Git开发最佳实践,其实不仅仅是Git,我相信无论任何一种版本控制工具都应该这么做,但实际上老夫工作过的公司由于没有一个强有力的人去把控代码规范流程(这个人水平可以不是很高,但对开发规范一定要有一个清晰的认识),也没有达到这个标准,最后需要说明的是由于老夫工作才两年而已,经验实在是不足,本文是老夫根据自己的工作经验总结而成,也没有经过实战检验,所以很有可能不是真正的最佳实践,希望高手能留言交流,谢谢

2018-01-12 21:29 更新:

1. 在 GitHub 上创建项目之后,如果选择了生成 License 和 README.md 文件,然后在本地 git init 初始化一个仓库上传。
先pull,因为两个仓库不同,发现会报 refusing to merge unrelated histories,无法 pull,使用下面这个命令就好了


git pull origin master --allow-unrelated-histories

2. 有些公司对 master 要求比较严,那么在本地 master 上在操作就只有 pull 了,也就是把远程 master 分支的代码合并到本地,远程 master 分支代码和远程 feature 分支的代码合并就通过 gitlab 或者 gerrit 等实现。

3. 之前第三部分的命令示例,我写的都是远程 dev 分支,和文章内容有所不符,网友 glassesbamboo 认为让人有些迷惑,所以对文章内的命令做了一些修改,在此表示感谢,谢谢。

全文完,如果本文对您有所帮助,请花 1 秒钟帮忙点击一下广告,谢谢。

作 者: BridgeLi,https://www.bridgeli.cn
原文链接:http://www.bridgeli.cn/archives/200
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。
分类: SCM 标签: , , , ,
  1. 2015年8月17日17:48 | #1

    飞爷,画点分支貌似好看些啊

  2. zhaosuzhou
    2015年8月17日19:47 | #3

    不错

  3. 2015年8月18日21:03 | #5

    很详细,收藏了 thx

  4. 2015年9月26日20:33 | #6

    很详细,很有用,已收藏到 http://www.jfox.info/my , thx

  5. 2017年8月20日17:37 | #7

    真的可以将本地的master代码直接推到远程的master?

    • 2017年8月22日22:09 | #8

      可以,只要权限够,但不建议,尽量不要这么操作,容易出问题//我偶尔会偷偷的这么干

  6. glassesbamboo
    2018年1月11日14:07 | #9

    阅读了您的文章,对我使用git帮助很大,但是最后一段有一些疑问,您提到dev的管理方式与后面的命令之间有些出入:
    例如:本地master分支推送到远程,也就是创建远程分支dev
    1.不是说只有本地有dev分支吗?后面的命令多次涉及到“远程dev”
    2.本地dev不是应该先合并到本地的feature分支或者hotfix分支,然后再把本地的feature或者hotfix推送到远程的对应分支吗?
    后面的命令都是这个疑问
    请解惑,谢谢。

    • 2018年1月12日21:59 | #10

      对,你说的很对,我把示例的命令,做了修改,感谢你提出的疑问,谢谢。

  1. 本文目前尚无任何 trackbacks 和 pingbacks.

请输入正确的验证码