且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

git工作流及遇到的问题

更新时间:2021-07-30 13:51:55

git工作流及遇到的问题

在介绍Git常用命令,现在就需要在工作中合理的使用这些命令,每个公司、每个团队在工作中都会使用不同的工作流来开发,下面介绍了几种我在工作中使用的工作流及遇到的些问题。

  • 主干开发
  • git flow
  • git 多环境工作

主干开发

顾名思义,即仅仅就一个主干分支,所有人都基于此分支开发,如下图:
git工作流及遇到的问题

小百提交了C1、C3,大川提交了C2、C4,两个人只要pull下代码都会看到对方最新的提交。这里仅仅就只有一个master分支,所有人都基于此分支开发

这种分支模型主要适用于:
1、开发团队系统设计和开发能力强。有一套有效特性切换机制,保证上线无需改变代码就能改变系统运行行为(比如:简单修改一个配置即可),需要快速迭代,每个人都能立马看到任何人提交的代码。类似Google、Facebook都采用了这种主干分支开发。
2、组件开发团队,成员能力强,人员少,沟通顺畅。用户升级组件成本低的环境。

这种分支模型的缺点也很明显,当有人提交了一些有bug的代码,如果没有配套的机制很容易影响线上的环境,对于大多数公司来说都不太适合。

git flow

git flow是Vincent Driessen提出的一套代码管理规范流程,A Successful Git Branching Model
如下图:
git工作流及遇到的问题

这个图第一眼看上去,感觉比较难懂,因为它定义了太多分支(master、develop、feature、release、hotfix),如果你感觉看的很别扭,可以把这张图逆时针旋转90度,或许更容易理解些。
我把这张图拆解了下面几个步骤,从项目最开始说起:
1、最初在gitlab创建了一个项目,此时就只有一个master分支,注意这个master分支是不允许在上面修改代码的,所以立马需要拉一个develop分支,作为后面的开发分支。
2、有了develop分支,就可以进行开发了,比如:小百和大川两个人同时接到了两个需求,小百(登录模块开发)、大川(用户注册模块),这时小百和大川需要基于develop各拉取一个分支,这两个分支就是feature分支。
3、小百和大川两个人都开发完毕了,需要提交代码,一般是小百和大川把代码提交到远程,发送一个merge到develop请求,然后由专人审核没问题,再合并到develop。
4、合到develop分支上的功能,可能会有bug,无法保证它的质量,所有基于develop会创建一个release分支,比如叫:release-1.0.0,然后由测试对release-1.0.0进行测试,测试通过了,同样发送一个merge到master分支的请求。
5、上面的请求通过后,就表示1.0.0功能已完成,可以基于此打一个标签叫:1.0.0-RELEASE,然后就可以发布出去 了,看到这里应该很熟悉了,因为你从maven下载包时,经常可以看到某个jar的命名是xxx.1.0.0-RELEASE。
6、对于master上1.0.0发布的版本,可能后面又发现了bug,或者有需要优化的,这时就可以基于1.0.0-RELEASE拉取一个新分支:hotfix-1.0.0,待解决完成后直接合到master分支上,再打一个标签叫:1.0.1-RELEASE,即对于1.0.0的补丁。

如果有新的功能需求,重新按照上面步骤开发,可以看到每次迭代都会产生很多分支,所以当一个功能正常上线稳定后,可以删除对应的feature、release、hotfix分支。

这种分支模型适合有预定的发布周期,需要执行严格的发布流程的项目,现在有的公司去掉了hotfix、release分支,都是对于以上模型的变种。

git 多环境工作

多环境就是一个项目在它的开发中会部署到很多环境中,这种项目都是需要快速迭代和持续交互,其实也是git flow模型的一个变种,比如一个产品,它在每一个阶段都会有新增和修改需求,我们暂且把三个月内的需求叫做day90,6个月的需求叫做day180,其中day90和day180都要单独部署,避免测试之间干扰,如下图:
git工作流及遇到的问题

最开始是基于develop拉取feature分支进行开发,合并到day90上进行测试,到一定阶段后,需要安排day180的功能开发了,此时一般会从develop再拉取一个分支day180

上图中还有两个分支,没画出来,是day90-uat,day180-uat,是day90和day180测试通过后,合并到对应分支上,给客户演示的环境。
在day90和day180同时进行的过程中,有可能会需求变更或者会出现测试的bug,所以后期对于新功能的修复可以从day90或day180上拉取一个新的分支进行开发/修复,完成后再合并到各自分支。

注:这里开发/修复完成同样需要合并到develop环境,主要是为了开发人员自己能在开发环境上自测一遍,避免基本的流程有问题。

master分支为线上版本,只能等到uat分支上都确定没有问题,再合并上去。

工作流中一些问题

1、怎样命名自己的开发分支

比如上面多环境分支,如果小百需要基于day180开发一个新的功能(用户登录),一般可以命名:分支_作者_功能_时间,在day180上执行:

git checkout -b day180_hb_user_login_20200301

或者如果是修复bug,可以命名:分支_作者_bug说明_(bugId)_时间,如:

git checkout -b day90_hb_fix_user_register_bug_001_20200301

有个小技巧,当一段时间接到很多bug和新需求,会产生很多分支,可能到后面自己都忘记哪个分支已经合并了,所以如果你已经合并了一个分支,可以把分支后面加一个后缀,比如:

git branch -m day180_hb_user_login_20200301 day180_hb_user_login_20200301_had_merge

确认没有问题后,再删除对应的分支。

2、哪些情况文件会产生冲突

不会冲突的情况:

  • 两个人同时修改了不同的文件
  • 两个人修改了同一个文件不同的区域
  • 一个人重命名了文件名

会冲突的情况

  • 两个人同时修改了同一个文件相同的区域
  • 两个人同时重命名了同一个文件名

3、在集成分支慎用git push -f命令

在开发时,经常会遇到,有一个功能已经开发完成了,已经合到master了,准备上线,突然发现了bug,需要立即回滚,有人可能会使用下面命令:

git reset --hard 回退的版本

但如果你现在使用git push,肯定会报错,因为你本地的分支落后于远程分支,你可能会直接使用:

git push -f origin day90

这样操作后,你本地的记录会完全覆盖远程的记录,回退版本之后的记录也会完全消失,后面有人修改了一些代码也会被你全部覆盖,所以在团队协作尽量不使用这个命令,除非你清楚知道不会产生任何影响或者需要这么做。

但这样操作后,你本地的记录会完全覆盖远程的记录,回退版本之后的记录也会完全消失,后面有人修改了一些代码也会被你全部覆盖,所以在团队协作尽量不使用这个命令,除非你清楚知道不会产生任何影响或者需要这么做。

正确的方式是使用revert,revert不会删除历史记录,只会重新生成一个新的版本,如下图(回退“添加公用配置文件”这个版本):
git工作流及遇到的问题
使用:git revert 回退之后:

git revert 3c838ea

git工作流及遇到的问题

4、合并多个历史的commit

如果你在开发过程中,涉及到多个提交,,但其实这几个提交的功能都是一样的,需要想要合并成一个提交,如下,我需要合并两次新增ftl文件
git工作流及遇到的问题

可以找到第一次新增ftl的父节点提交,使用:

git rebase -i 

会出现如下界面,可以看到下面介绍了一些常用的命令
git工作流及遇到的问题

修改为
git工作流及遇到的问题

表示把ece332f提交合并到7fbc773中,wq!保存退出,会弹出:
git工作流及遇到的问题

修改两次提交的注释,然后wq!保存退出,使用:git log查看日志
git工作流及遇到的问题

如果是想要把多次不同间隔的提交合并呢,方法也同理,比如把两次修改readme合并,找到第一次修改readme的父节点9f1dbb1

git rebase -i 9f1dbb1

git工作流及遇到的问题

5、多人开发的分支需要一起联调

在开发中大多数情况虽然每个人都负责不同的模块,在开发中大多数情况虽然每个人都负责不同的模块,但是经常会出现两个人一起联调的情况,比如小百和大川分别开发用户登录和用户注册模块
小百在自己的分支上添加了一个公用的文件,而大川需要这个公用文件才能继续开发,如下图:
git工作流及遇到的问题
如果对于这个公用文件,有提交记录,大川可以直接在自己的分支上cherry-pick这个提交

git fetch #获取远程仓库的所有更新的分支
git cherry-pick 

如果这个公用文件,没有提交记录,大川可以在自己的分支上只checkout这个文件到自己的分支

git checkout xiaobai_user_login_20200303 common.js

当然大川也可以直接使用merge命令把小白的代码都合并过去

git merge xiaobai_user_login_20200303

注意使用merge命令的时候不要把一些不同周期上线的代码也合并过去了
比如小百开发了注册模块,还开发了一个角色模块,小百把这两个功能都放到xiaobai_user_login_20200303分支上开发了
现在需要用户登录模块和用户注册模块先提交测试,角色模块放后面处理

这种情况,如果大川需要合并小百分支上登录模块,可以使用上面的cherry-pick所有提交或chekout一个个文件的来合并。

在开发中如果确定几个功能会放在不同的时间点上线,或者一个模块开发周期比较长,或者别人要用到,***单独搞一个分支。