图文详解如何利用Git+Github进行团队协作开发

论坛 期权论坛 爱问     
moneyhtv   2022-6-3 09:50   6340   17
团队协作开发中,大部分都会用到版本控制软件,比如Git、Svn等。本文将通过一个实例,详细讲解在真实的工作环境中,一个团队应该如何利用Git+Github进行协作开发,即详解Git工作流程。并就其中比较棘手的问题作出解答,比如如何解决冲突比较合适,如何建立各种类型的分支等。关于Git工作流,建议参考文章:Git Workflows and Tutorials。
本文不会讲解Git简介、Git原理、Git基本用法等,有不了解的可以参考“Git 参考手册”。我们举例演示的是GitFlow工作流的功能,这里先放一张经典的GitFlow工作流图示:



其中涉及到的主要分支类型有:

  • master分支,即主分支。任何项目都必须有个这个分支。对项目进行tag或发布版本等操作,都必须在该分支上进行。
  • develop分支,即开发分支,从master分支上检出。团队成员一般不会直接更改该分支,而是分别从该分支检出自己的feature分支,开发完成后将feature分支上的改动merge回develop分支。同时release分支由此分支检出。
  • release分支,即发布分支,从develop分支上检出。该分支用作发版前的测试,可进行简单的bug修复。如果bug修复比较复杂,可merge回develop分支后由其他分支进行bug修复。此分支测试完成后,需要同时merge到master和develop分支上。
  • feature分支,即功能分支,从develop分支上检出。团队成员中每个人都维护一个自己的feature分支,并进行开发工作,开发完成后将此分支merge回develop分支。此分支一般用来开发新功能或进行项目维护等。
  • fix分支,即补丁分支,由develop分支检出,用作bug修复,bug修复完成需merge回develop分支,并将其删除。所以该分支属于临时性分支。
  • hotfix分支,即热补丁分支。和fix分支的区别在于,该分支由master分支检出,进行线上版本的bug修复,修复完成后merge回master分支,并merge到develop分支上,merge完成后也可以将其删除,也属于临时性分支。
下边我们一步步拆分讲解各种类型分支的用法。
(1)假设团队就一个人“xianhu”,做一个叫TestGit的项目,并将其代码托管在Github上。首先需要在Github上新建一个项目TestGit:


按照Github上的提示,在本地新建一个项目,并关联到Github上的orgin/master。此时开发一个很小的demo功能,并提交到线上,并在master分支上进行打tag操作,并命名为v0.1。此时的GitFlow工作流为:


(2)如果此时master分支的代码正在线上运行,而且又需要开发新功能,则不能在master分支上直接修改。一个比较好的策略是在master分支上新建并检出develop分支,新功能的开发在develop分支上进行,此时记得将develop分支提交到远端:
git branch develop master    # 从master分支上新建develop分支
git checkout develop    # 检出develop分支
# 此处可进行功能开发,并add和commit到develop分支
git push origin develop    # 推送develop分支到远端的origin/develop即Github上保持两个分支:master和develop。目的是为以后团队协作更新develop分支做准备。此时Github上为:


此时会出现两种情况:

  • 线上版本的代码(master分支)出现了紧急bug,需要修复。这里用到了hotfix分支。
git checkout master    # 切换回master分支
git checkout -b hotfix master    # 新建hotfix分支,并切换到该分支
......                 # 做一些bug修复工作
git checkout master    # 切换回master分支
git merge --no-ff hotfix    # 合并hotfix分支,此时bug已被修复(无冲突)
git tag v0.2    # 新建tag v0.2
git push origin master    # 推送master分支代码到远端
git push origin --tags    # 推送tag到远端

  • develop分支上的功能开发完成了,需要进行测试和提交。这里用到了release分支。
git checkout develop    # 切换回develop分支
git checkout -b release01 develop    # 新建release分支,并切换到该分支
.......                 # 做一些测试、bug修复等工作
git checkout develop    # 切换回develop分支
git merge --no-ff release01  # 合并release01分支到develop分支(无冲突)
git push origin develop    # 推送develop分支到远端
git checkout master    # 切换回master分支
git merge --no-ff release01   # 合并release01分支到master分支(无冲突)
git tag v0.3    # 新建tag v0.3
git push origin master    # 推送master分支代码到远端
git push origin --tags    # 推送tag到远端此时GitFlow工作流为:


(3)这里可以继续develop分支,并不断push到远端。此时如果团队成员增加,多人需要开发不同的功能,这里就会用到feature分支。团队中的每个人都从Github克隆一个项目,然后新建自己的feature分支。
git clone xxxx.git
git checkout develop
git checkout -b feature-xx develop    # 从develop分支新建并检出feature分支此时“xianhu”做如下操作,并首先第一个提交到了Github远端:
git checkout -b feature-hu develop    # 从develop分支新建并检出feature分支
# 这里可以进行一些功能开发,并不断的add和commit
git checkout develop    # 切换回develop分支
git pull origin develop    # 更新远端代码,看develop分支是否有更新(无更新)
git checkout feature-hu    # 切换回feature分支
git rebase develop    # 合并develop分支到feature分支,并解决冲突(无冲突)
git checkout develop    # 切换回develop分支
git merge --no-ff feature-hu    # 合并feature分支到develop分支
git push origin develop   # 推送develop分支到远端 此时的GitFlow工作流为:


对于团队其他成员,比如zz,操作如下,并打算在“xianhu”提交后进行push操作:
git checkout -b feature-zz develop    # 从develop分支新建并检出feature分支
# 这里可以进行一些功能开发,并不断的add和commit
git checkout develop    # 切换回develop分支
git pull origin develop    # 更新远端代码,看develop分支是否有更新(有更新)
git checkout feature-zz    # 切换回feature分支
git rebase develop    # 合并develop分支到feature分支,并解决冲突(有冲突)
# 这里需要进行冲突解决
git add .    # 解决完冲突之后执行add操作
git rebase --continue    # 继续刚才的rebase操作
git checkout develop    # 切换回develop分支
git merge --no-ff feature-zz    # 合并feature分支到develop分支(无冲突)
git push origin develop   # 推送develop分支到远端如果团队成员在合并feature分支到develop分支后还需要继续开发,则检出自己的feature分支继续操作,并重复上述过程即可。这里需要注意--no-ff参数,其目的是让commit的流程更加清晰,具体为什么可自行百度。
xianhu这边进行pull操作,即可看到zz进行的操作。此时的GitFlow工作流为:


(4)如果此时需要进行测试、发版操作,则需要再次新建并检出release分支,重复(2)的步骤。完成之后的GitFlow工作流为:


这里就完成了从版本v0.1到v1.0的迭代开发,并详细解释了如何利用Git+Github进行团队协作开发。文章中没有用到fix分支,这种分支的用法和feature分支类似,大家可以自己体会。
最后详细解释一下上张图:

  • xianhu在master分支上完成v0.1版本开发,“done demo in master”
  • 发现master分支上有bug,需紧急修复。新建并检出hotfix分支进行bug修复,并merge回master分支,发布版本v0.2。
  • xianhu新建并检出develop分支进行迭代开发,然后在develop分支上检出release01分支,进行发版前测试和bug修复。“fix bugs in release01”,完成后将release01分支merge回develop和master分支,并在master分支上发布版本v0.3。
  • xianhu继续开发develop分支。此时团队成员增加,团队中的每个人都在develop的基础上新建并检出自己的feature分支,开发完成后merge回develop分支。这里利用到了rebase操作和冲突解决等,需要特别注意一点步骤。
  • xianhu在develop分支上检出release02分支,再次进行发版前测试和bug修复,“fix bugs in release02”,完成后将release02分支merge回develop和master分支,并在master分支上发布版本v1.0。
这里只用到和解释了GitFlow工作流,团队协作开发也可以用Pull Requests或者其他方式,找一个合适自己团队和具体业务的协作方式即可。另外,Git博大精深,想要完全精通也绝非易事,只能是一边学一边用。
---------------------------------------------------------------------------------------------
更新1:git merge和git rebase的区别
(1)使用git merge合并分支,解决完冲突,执行add和commit操作,此时会产生一个额外的commit。如下图:


(2)使用git rebase合并分支,解决完冲突,执行add和git rebase --continue,不会产生额外的commit。这样master分支上不会有无意义的commit。如下图:


所以可以这么说:merge是显性合并,rebase是隐性合并。
同理,当你执行git pull时,是同时执行了git fetch 和 git merge两个操作。如果你不想进行merge操作,即不想留下合并的记录,可以使用 git pull --rebase操作。
更新2:如何在Github上创建、删除分支
1、在本地创建新分支:git branch newbranch
2、在本地切换到新分支:git checkout newbranch
3、将新分支推送到github:git push origin newbranch
4、在本地删除一个分支:git branch -d newbranch
5、在Github远端删除一个分支:git push origin :newbranch
=============================================================
作者主页:笑虎(Python爱好者,关注爬虫、数据分析、数据挖掘、数据可视化等)
作者专栏主页:撸代码,学知识 - 知乎专栏
作者GitHub主页:撸代码,学知识 - GitHub
欢迎大家拍砖、提意见。相互交流,共同进步!
==============================================================
分享到 :
0 人收藏

17 个回复

倒序浏览
2#
1o9x0j  1级新秀 | 2022-6-3 09:51:18 发帖IP地址来自 北京
git workflow和github有啥关系...
3#
e7i  1级新秀 | 2022-6-3 09:52:07 发帖IP地址来自 北京
满满的都是干货
4#
u2e7h  1级新秀 | 2022-6-3 09:52:54 发帖IP地址来自 北京
刚学玩git,感谢分享!
5#
wlar  1级新秀 | 2022-6-3 09:53:16 发帖IP地址来自 重庆合川区
感谢,这个是真干货啊!
6#
pvxq7  1级新秀 | 2022-6-3 09:53:52 发帖IP地址来自 北京
多人开发基于 develop 分支 创建各自 feature,开发完成再创建各自feature的 release 分支进行测试么?为什么不直接在 feature 上测试?
7#
26y  1级新秀 | 2022-6-3 09:54:33 发帖IP地址来自 北京
release分支是准备上线的下一个版本,也就是说release分支包含了所以需要上线的feature。并不需要每个feature都拉一个分支出来。举例说一下,三个同学开发了feature1/feature2/feature3,这三个feature都需要在release 1.0版本上线。每个人都在自己的feature分支上测试通过,这时全部merge到release 1.0分支上,虽然各自的测试都通过了,但是feature1/feature3有可能因为逻辑冲突导致功能失效。我们需要在release分支上把所有功能都测试通过,然后再将修改后的代码合并到master和dev并上线。
8#
d58sj  1级新秀 | 2022-6-3 09:54:56 发帖IP地址来自 北京
感谢分享,虽然是一年前的文章的,但是我也是刚刚才看到,在hotfix合并的例子那,是不是忘记把hotfix也合并到dev开发分支呢,毕竟你上面一开始是用有说到同时合并到master跟dev上的
9#
v0iqrd  1级新秀 | 2022-6-3 09:55:31 发帖IP地址来自 北京
你好,这里的有一处注释不清晰:
git checkout feature-zz    # 切换回feature分支
git rebase develop    # 合并develop分支到feature分支,并解决冲突(有冲突)--- 这里是将feature分支的修改移到develop分支
# 这里需要进行冲突解决
git add .    # 解决完冲突之后执行add操作
10#
h900l  1级新秀 | 2022-6-3 09:56:02 发帖IP地址来自 广东阳江
作者这里没有错啊,以feature为基将develop合并到feature形成新的提交,而develop此时指向该提交。
11#
1_bv  1级新秀 | 2022-6-3 09:56:31 发帖IP地址来自 中国
你好~我做了一个实验,具体 范海强:git rebase
12#
yzls  1级新秀 | 2022-6-3 09:57:15 发帖IP地址来自 北京
我觉得你说的没错
13#
吴宇  管理员  伦敦金丝雀码头交易员 | 2022-6-3 09:58:09 发帖IP地址来自 北京
赞!思路清晰,例子和注释都很丰富,对我这种GitHub新手非常有用。谢谢楼主!
14#
x_b9  1级新秀 | 2022-6-3 09:58:51 发帖IP地址来自 北京
突然啥都明白了
15#
2243c  1级新秀 | 2022-6-3 09:59:15 发帖IP地址来自 北京
冒昧问题系, 为什么不直接在develop上进行测试,完了之后再合并到master 上呢? 而是要拉取测试分之呢? 这样做是为了保证develop的稳定性吗?
既然要维持develop的稳定性的话, 那开发功能不是也应该从develop上拉取分支进行开发吗?
望看到的人能解答一下, 谢谢
[爱心]
16#
4hiu4  1级新秀 | 2022-6-3 09:59:27 发帖IP地址来自 广东广州
feature分支就是你说的从dev拉下来的新功能分支
17#
mc2ab  1级新秀 | 2022-6-3 10:00:10 发帖IP地址来自 中国
楼主想法挺好,讲的也负责人,但是少了一步,导致很多人和你最终结构图不一样,你的HOTFIX一定也要推到本地DEV然后推到远端DEV的
18#
wbunle  2级吧友 | 2022-6-3 10:01:09 发帖IP地址来自 北京
牛逼
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:
帖子:
精华:
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP