Git分支
Git工作流
"工作流"在英语里,叫做"workflow",原意是水流,比喻项目像水流那样,顺畅地向前流动,不会发生冲击、对撞、甚至漩涡。

# 工作流
项目开发中,多人协作,分支很多,虽然各自在分支上互不干扰,但是我们总归需要把分支合并到一起,而且真实项目中涉及到很多问题,例如版本迭代,版本发布,bug 修复等,为了更好的管理代码,需要制定一个工作流程,这就是我们说的工作流,也有人叫它分支管理策略。
工作流不涉及任何命令,因为它就是一个规则,完全由开发者定义并遵守,正所谓无规矩不成方圆,就是这个道理。
目前使用度最高的工作流有如下几种:
Git Flow 出现的最早,GitHub Flow 在 Git Flow 的基础上,做了一些优化,适用于持续版本的发布,而 GitLab Flow 出现的时间比较晚,所以综合前面两种工作流的优点,制定而成的一个工作流。TBD则是谷歌现行的工作流。
# Git Flow
Git Flow 是什么
Git Flow 是一个基于 Git 的开发流程管理的模型, 因极其适合多人协作有效地进行并行开发而被广泛用于项目流程的源代码管理.
在版本回退里,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。
- 截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。
- HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。
Gitflow 工作流是目前非常成熟的一个方案,它打破单支模型工作流,定义了一个围绕项目发布的严格分支模型,通过为代码研发、项目发布以及维护分配独立的分支来让项目的迭代过程更加地顺畅
不同于之前的集中式工作流以及功能分支工作流,gitflow 工作流常驻的分支有两个:主干分支 master、开发分支 dev,此外针对项目研发的各个阶段,设定了特定的分支。
阶段分支常驻 master、dev 研发 feature 热修复 hotfix 发布 release等,见下图
# 分支模型优势
场景设定:基于master分支的代码,开发一个新的特性
- 📔 如果你直接在master分支上开发这个新特性,是不好的
- 万一你在开发
特性1
的时候,领导突然又要叫你去开发特性2
,就不好处理了。 - 难道开发的两个特性都提交到master?一会儿提交特性1的commit,一会儿提交特性2的commit?这会导致commit记录很混乱。
- 万一你在开发
- 所以,建议的做法是:给每个特性都单独建一个的新的分支。
# Git Flow的分支结构

从上图可以看到,Git Flow 的分支结构很清晰:
按功能来说,可以分支为5种分支,从5 种分支的生命周期上,又可以分别归类为长期分支和暂时分支,在表现上,其实就是主分支和协助分支。
# 主分支
- 主分支包括
master
分支和develop
分支。master
分支用来发布,HEAD
就是当前线上的运行代码。develop
分支就是我们的日常开发。使用这两个分支就具有了最简单的开发模式:develop
分支用来开发功能,开发完成并且测试没有问题则将develop
分支的代码合并到master
分支并发布。 master
: 主分支,创建完仓库自动生成master分支, 主要用来版本发布,正式上线,用户使用的版本。develop
:日常开发分支,该分支正常保存了开发的最新代码,更新功能A、B、C。测试工程师主要在该分支工作。- 当 develop 上的代码达到一个稳定的状态,可以发布版本的时候,develop上这些修改会被合并到 master 分支上,然后标记上对应的版本标签(Tag)。
- 这引入了几个问题:
develop
分支只有发布完了才能进行下一个版本开发,开发会比较缓慢。- 线上代码出现 bug 如何进行 bug 修复。
- 带着这两个问题往下看。
- 主分支包括
# 协助分支
- 主要介绍的辅助分支如下:
feature
分支、release
分支、hotfix
分支, 通过这些分支,我们可以做到:团队成员之间并行开发,feature track
更加容易,开发和发布并行以及线上问题修复。 feature
:特性分支,用来做新特性新功能的开发。只与 develop 分支交互,**feature
分支用来开发具体的功能,一般 fork 自develop
分支,最终可能会合并到develop
分支。比如我们要在下一个版本增加功能1
、功能2
、功能3
。那么我们就可以起三个feature
分支:feature1
,feature2
,feature3
。**分别产生功能A,功能B,功能C不同的feature。新特性开发完成之后,会合并到 develop 分支,然后删除。随着我们开发,功能1
和功能2
都被完成了,而功能3
因为某些原因完成不了,那么最终feature1
和feature2
分支将被合并到develop
分支,而feature3
分支将被干掉。开发工程师往往在该分支上工作。release
:发布分支,用来做版本(预)发布。release
分支可以认为是master
分支的未测试版。比如说某一期的功能全部开发完成,那么就将develop
分支合并到release
分支,该分支只修bug,不再合入新特性。 并且修改bug的提交,会合并回 develop,保证 develop 为最新进度。测试没有问题并且到了发布日期就合并到master
分支,进行发布。hotfix
:热修复分支,用来做线上的紧急 bug 修复的分支。当线上某个版本出现了问题,做补丁。将检出对应版本的代码,创建 Hotfix 分支,问题修复后,合并回 master 和 develop ,然后删除。这里注意,合并到 master 的时候,也要打上修复后的版本标签。- 除此之后还可以有
fast-track
等分支。
- 主要介绍的辅助分支如下:
# Github Flow分支
Github Flow 是Git Flow的简化版,专门配合**"持续发布"**。它是 Github.com使用的工作流程 。
第一步:从master拉出新分支。 第二步:新分支开发完成后,或者需要讨论的时候,就向master发起一个pull request(简称PR)。 第三步:Pull Request既是一个通知,让别人注意到你的请求,又是一种对话机制,大家一起评审和讨论你的代码。对话过程中,你还可以不断提交代码。 第四步:当Pull Request被接受,合并进master,重新部署后,原来你拉出来的那个分支就被删除。(先部署再合并也可。)
# 分支操作与应用
# 一、查看分支
# 列出所有本地分支
$ git branch
# 列出所有远程分支
$ git branch -r
# 列出所有本地分支和远程分支
$ git branch -a
2
3
4
5
6
7
8
# 二、创建分支
首先,我们来创建dev分支,然后切换到dev分支上。如下操作:
$ git branch dev //创建dev分支 $ git checkout dev //切换到dev分支 $ git branch * dev master $ git checkout –b dev //创建指定分支+切换当前分支到指定分支上 $ git merge name //合并某分支到当前分支(一般会先切换到master分支上,再合并其他分支) $ git branch –d name //删除分支
1
2
3
4
5
6
7
8
9
10
11
# 三、合并分支
- 快速合并
- 非快速合并(不同分支对同一内容进行了不同的修改后,进行合并时候,会发生冲突)
# 案例应用
比如说,我专门建立一个特性1
,为其建一个分支feature_item_recommend
。具体做法如下:
- (1)基于master分支,创建一个新的分支,起名为
feature_item_recommend
:
$ git checkout -b feature_item_recommend
Switched to a new branch 'feature_item_recommend'
2
3
上面这行命令,相当于:
$ git branch feature_item_recommend // 创建新的分支
$ git checkout feature_item_recommend //切换到新的分支
2
3
(2)在新的分支
feature_item_recommend
上,完成开发工作,并 commit 、push。(3)将分支
feature_item_recommend
上的开发进度合并到master分支:
$ git checkout master //切换到master分支
$ git merge feature_item_recommend //将分支 feature_item_recommend 的开发进度合并到 master 分支
2
3
4
合并之后,master
分支和feature_item_recommend
分支会指向同一个位置。
(3)删除分支feature_item_recommend
:
既然 特性1 开发完了,也放心地提交到master了,那我们就可以将这个分支删除了。
git branch -d feature_item_recommend
注意,我们当前是处于master
分支的位置,来删除feature_item_recommend
分支。如果当前是处于feature_item_recommend
分支,是没办法删除它自己的。
同理,当我转身去开发特性2
的时候,也是采用同样的步骤。
# 合并分支时,如果存在分叉
比如说上面这张图中,最早的时候,master分支是位于C2
节点。我基于C2
节点,new出一个新的分支iss53
,我在iss53
上提交了好几个commit。
现在,我准备把iss53
上的几个commit合并到master上,此时发现,master分支已经前进到C4了。那该怎么合并呢?
合并的命令仍然是:
$ git checkout master
$ git merge iss53
2
3
解释:
这次合并的实现,并不同于简单的并入方式。这一次,我的开发历史是从更早的地方开始分叉的。
由于当前 master 分支所指向的commit (C4)并非想要并入分支(iss53)的直接祖先,Git 不得不进行一些处理。就此例而言,Git 会用两个分支的末端(C4 和C5)和它们的共同祖先(C2)进行一次简单的三方合并计算。
Git 没有简单地把分支指针右移,而是对三方合并的结果作一新的快照,并自动创建一个指向它的commit(C6)(如下图所示)。我们把这个特殊的commit 称作合并提交(mergecommit),因为它的祖先不止一个。
值得一提的是Git 可以自己裁决哪个共同祖先才是最佳合并基础;这和CVS 或Subversion(1.5 以后的版本)不同,它们需要开发者手工指定合并基础。所以此特性让Git 的合并操作比其他系统都要简单不少。
# 解决合并时发生的冲突
如果 feature1和feature2修改的是同一个文件中代码的同一个位置,那么,把feature1合并到feature2时,就会产生冲突。这个冲突需要人工解决。步骤如下:
(1)手动修改文件:手动修改冲突的那个文件,决定到底要用哪个分支的代码。
(2)git add:解决好冲突后,输入git status
,会提示Unmerged paths
。这个时候,输入git add
即可,表示:修改冲突成功,加入暂存区。
(3)git commit 提交。
然后,我们可以继续把 feature1 分支合并到 master分支,最后删除feature1、feature2。
注意:两个分支的同一个文件的不同地方合并时,git会自动合并,不会产生冲突。
比如分支feture1对index.html原来的第二行之前加入了一段代码。 分支feature2对index.html在原来的最后一行的后面加入了一段代码。 这个时候在对两个分支合并,git不会产生冲突,因为两个分支是修改同一文件的不同位置。 git自动合并成功。不管是git自动合并成功,还是在人工解决冲突下合并成功,提交之前,都要对代码进行测试。
本地自动化
bash文件
#!/usr/bin/env sh echo 开始更新资源 # 提交到暂存区 git add -A # 提交到本地仓库 git commit -m ':bento: 更新资源文件' # git添加远程仓库地址到origin名称,建立关联 git remote add origin-GitUserBook https://github.com/weihuohuayi/GithubUserbook.git # push将本地master分支推送到github仓库——origin-GitUserBook 的主要分支——master分支 git push origin-GitUserBook master # push将本地新建dev分支推送到github仓库 并同时新建远程dev分支进行对应 git push origin-GitUserBook dev:dev # push将本地新建dev分支再次推送到github仓库dev分支 git push origin-GitUserBook dev echo 更新资源推送完毕
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 日常bug操作积累
# 一、修改密码(曲线救国)
网上查了很久,没找到答案。最终,在cld童鞋的提示下,采取如下方式进行曲线救国。
# 设置当前仓库的用户名为空
git config user.name ""
2
然后,当我们再输入git pull
等命令行时,就会被要求重新输入新的账号密码。此时,密码就可以修改成功了。最后,我们还要输入如下命令,还原当前仓库的用户名:
git config user.name "smyhvae"
# 二、修改已经push的某次commit的作者信息
已经push的记录,如果要修改作者信息的话,只能 通过--force命令。我反正是查了很久,但最终还是不敢用公司的仓库尝试。
参考链接:
看最后一条答案。
# 三、将 branch1
的某个commit1
合并到branch2
当中
切换到branch2中,然后执行如下命令:
git cherry-pick commit1
# 推荐书籍
- 《pro.git中文版》
# 推荐连接
