阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Git的分支工作流与Pull Request

138次阅读
没有评论

共计 6500 个字符,预计需要花费 17 分钟才能阅读完成。

上一篇文章介绍了常用的版本控制工具以及 git 的基本用法,从基本用法来看 git 与其它的版本控制工具好像区别不大,都是对代码新增、提交进行管理,可以查看提交历史、代码差异等功能。但实际上 git 有一个重量级的功能“分支”,git 的分支与其它工具的分支不同,git 分支的操作完全在本地进行,所以可以快速的创建和切换。

版本控制工具除了对代码进行管理外,实际上它还影响了整个软件编码的工作流程,git 因为其分支特性使得开发流程发生了变化,本文将从以下几点来介绍分支和 git 的工作流程:

  • 版本控制管理分支简介
  • Git 的分支
    • 分支的基本操作
    • 远程分支
  • Git 基于分支的工作流程
    • 集中式工作流
    • 功能开发工作流
    • Git Flow 工作流
  • Git 的分布式工作流
    • 再谈集中式工作流
    • 集成管理者工作流
    • 司令官与副官工作流
  • Pull Request
  • Git 常用的 GUI 工具
  • 小结

版本控制管理分支简介

在使用集中式的版本管理工具时,一般会在项目的仓库中创建 Trunk(主干)、Branches(分支)、Tag(标记)几个目录,分别用于放置开发代码、代码分支以及代码里程碑,分支的目的是 为了开发一些测试性功能或者修复 Bug 时从 开发主线上分开避免互相影响 ,但是要注意的是集中式的工具创建分支的过程是由服务器完成的,当服务器完成分支的创建后,使用者还需要将分支代码 checkout 到本地,如果项目较大或者网络较慢,那么 checkout 将是一个漫长的过程,所以使用集中式工具时分支的创建是相对谨慎的。
对于 Git 来说分支就是整个仓库的基础( 注:当使用 git init 命令创建一个仓库时,默认会创建一个名为 master 的分支 ),由于 Git 的本地处理特性,分支的创建基本是一瞬间完成的,正因为这一特性,使用 git 来进行代码开发的工作流程就有了巨大的变化,如开发功能时创建对应的分支、修复 bug(不仅仅是生产 bug,任何测试产生的 bug 都可以创建分支) 以及开源项目任何人都可以创建自己的分支进行开发。

Git 的分支

分支的基本操作

  • 查看分支:(git branch)

Git 的分支工作流与 Pull Request

  • 分支的创建:(git branch TranslateMainPage)

Git 的分支工作流与 Pull Request

  • 分支的切换:(git checkout TranslateMainPage)

Git 的分支工作流与 Pull Request

注:git checkout -b TranslateMainPage 相当于执行了创建和切换两个命令。

  • 分支的合并:(git merge TranslateMainPage)

Git 的分支工作流与 Pull Request

  • 分支的删除:(git branch -d TranslateMainPage)

Git 的分支工作流与 Pull Request

  • 将本地分支上传到远程服务器:(git push -u origin version0 注:- u 是 –set-upstream 的缩写)

Git 的分支工作流与 Pull Request

Git 的分支工作流与 Pull Request

远程分支以其基本操作

Git 的操作都是基于分支的,同时 Git 作为一个分布式的版本控制工具可以使用远程托管平台来进行代码库托管,那 Git 的分支是如何在远程平台上体现的呢?
Git 中有一个 remote 命令,它可以用来管理一系列被跟踪或者说被关联的远程仓库(注:remote 管理的是仓库),如下图通过 git remote 以及 git remote show origin 来查看远程仓库的信息:

  Git 的分支工作流与 Pull Request

这里要注意的是“origin”,它实际上是远程仓库的一个名称,通过容易记忆名称来代替仓库的 URL 地址更加容易使用,另外如果使用 git clone 命令来克隆一个远程仓库,那么远程仓库名称会默认为 origin。
对于远程分支常用的操作有:

  • 添加新的远程仓库:(git remote add Myblog https://github.com/yqszt/Myblog.git,Myblog 是本地用来代替后面 Url 的名称)

Git 的分支工作流与 Pull Request

  • 克隆一个远程仓库:(git clone https://github.com/yqszt/MyBlog.git)

Git 的分支工作流与 Pull Request

默认创建一个名称为 origin 的远程仓库:

Git 的分支工作流与 Pull Request

  • 将数据 (commit) 提交到远程仓库:(git push origin)

Git 的分支工作流与 Pull Request

  • 从远程仓库拉取更新:(git fetch)

注:使用 git fetch 后,并不会将新的内容更新到工作区域的文件中,所以可以通过 git diff master origin/master 命令来比较差异

Git 的分支工作流与 Pull Request

同时也可以使用 git merge 命令来将更新合并到工作区域:

Git 的分支工作流与 Pull Request

注:git pull 命令相当于执行了 git fetch 和 git merge 两个命令。

Git 基于分支的工作流程

之前提到过集中式版本工具中分支的作用是开发一些测试性功能或者修复一些稳定版本的 Bug,使用分支可以与开发主线隔离,当完成后再合并到主线中,这种开发流程被称为“集中式工作流”,它的工作流程可看成:

  Git 的分支工作流与 Pull Request

1. 以主分支 Trunk 为核心进行开发,换句话就是开发人员把开发代码都提交到 Trunk 上,提交之前获取所有代码,并且保证代码能编译成功。
2. 如果有测试性功能,为了与主干代码分离,通过开启分支的形式完成功能开发。(注:这里写测试性功能的原因是,集中式的版本控制工具开启分支代价相对较大,所以在创建分支的时候是谨慎的)。
3. 当开发达到一个里程碑时,通过创建 Tag 分支来保存里程碑状态,同时 Tag 出现问题时,可以通过创建 Bug 修复分支或者直接在 Tag 分支上修复问题,最终将修复代码合并到 Trunk 上。
对于分布式的 Git 来说,由于它创建和切换分支的代价很小,所以可以频繁的创建和切换分支,而分支的功能就是与主干代码隔离,以至于在开发过程中不会因为不完善的功能代码导致主干代码被污染,从而导致无法编译通过,它主要有以下几种开发工作流:

集中式工作流

集中式工作流就是上面提到集中式版本控制工具中常用的开发流程,以主分支为核心,所有开发人员通过更新主分支代码完成代码的开发工作,同时也会创建一些分支和标签(Git 的默认分支是 Master):

Git 的分支工作流与 Pull Request

功能开发工作流

功能开发工作流程是以功能为单位进行分支创建,其过程如下:

Git 的分支工作流与 Pull Request

通过 创建对应的功能或问题修复分支,完成功能的开发和 Bug 的修复。这样的好处就是功能与功能之间的代码是隔离的互不影响,利用 Git 的快速切换分支特性,可以在同一工作目录下同时开发多个功能,且各个功能之间的代码不会互相影响。另外所有新代码均通过合并的方式合并到 Master 分支,这样代码更容易控制管理。

Gitflow 工作流

Gitflow 可以看作是 功能开发工作流的完善版本,它除了 Master 分支、特性分支、Bug 修复分支外,还引入了 release、develop 两个分支来管理发布和开发,而 Master 只保存稳定版本的代码。

Git 的分支工作流与 Pull Request

(图片来自 https://www.cnblogs.com/cnblogsfans/p/5075073.html)
总的来说 Git 就是使用它快速创建和切换分支的特性,在开发过程中通过分支来完成功能的开发、Bug 修复以及代码发布。
更多信息可参考:http://nvie.com/posts/a-successful-git-branching-model/
https://blog.csdn.net/wwj_748/article/details/55226044

Git 的分布式工作流

前面介绍了 Git 的特性之一“分支”的工作流,那么 Git 的特性之二“分布式”又会对开发模式带来什么样的变化?

再谈集中式工作流

为什么又是集中式工作流?文章前面介绍的集中式工作流主要偏重于“分支”,所有工作的内容提交到一个 Trunk 或者 Master 的分支上。
而这里的集中式工作流是针对与代码仓库来说的,所有开发人员使用同一个代码仓库进行协同工作 ,Git 中使用集中式工作流时还可以采用特性分支或者 Git Flow 工作流来体现 Git 分支带来的便利( 注:如果一个项目的贡献者只有一个人的话,实际上集中式工作流联合特性或 Git flow 来进行开发是最适合的):

Git 的分支工作流与 Pull Request

在使用集中式版本控制工具时,使用的就是集中式工作流,所有的开发人员共享一个代码仓库,当其中一人提交代码时需要先更新其它人的提交,可能会出现代码冲突需要合并,还有可能会将其它人的提交覆盖掉,同时由于无法保证代码质量,甚至会出现引入了其它开发人员的代码导致编译不通过、测试不通过等等问题,所以在使用集中式工作流程的时候最不能缺少的就是“沟通”。
对于开源项目来说开发人员来自全世界,其沟通成本远远大于本地团队,那么作为开源项目使用最广泛的版本控制工具,它是如何解决协同开发问题?

集成管理者工作流

Git 中可以创建多个仓库,集成管理者工作流的核心就是项目的 主仓库由“集成者”负责 ,其它 开发人员拥有自己的仓库 ,开发者把 完成的工作提交到自己的公开库 中,然后 “集成者”从这些公开库中拉取代码 最终合并到主仓库中,如下图:

Git 的分支工作流与 Pull Request

这样做有以下几个好处:

  • 开发人员有自己的代码库,减少了更新、合并等操作 ( 注:更新、合并的根源在于不同开发任务之间的依赖,如果依赖严重,那么更新、合并是不可避免的,最理想的情况是没有依赖,那么开发人员只需完成自己的工作提交即可)。
  • 所有代码合并由“集成者”完成合并,而一般“集成者”由经验丰富的程序员担任,代码合并的过程强制进行了代码复审,对于代码的质量是可控的,有效保证主项目代码的干净整洁。
  • 由于代码的复审,开发人员在提交代码时也不会太随意,变相提高了代码质量。

但是相对于集中式的工作流来说由于需要等待合并,提交工作也比较复杂,所以开发效率会相对降低。

司令官与副官工作流

司令官与副官工作流是集成管理者工作流的拓展,引入了多级“集成者”来完成多级的代码合并操作,该模式适用于复杂的多级管理的项目开发:

Git 的分支工作流与 Pull Request

更多关于 Git 分布式工作流的内容可参考:https://git-scm.com/book/en/v2/Distributed-Git-Distributed-Workflows

Pull Request

在 Git 中无论是集中式工作流还是集成管理者工作流,它都有一个核心的操作就是合并代码,对于集中式工作流来说,当分支完成开发后,需要将代码进行合并,一般是将分支代码合并到远程的如 Master 或 Develop 之类的长期分支上,其流程如下:
1. 创建一个功能分支 feature1(git checkout -b feature1)。
2. 在分支上完成功能并提交(git add & git commit)。
3. 切换到 master 分支执行合并操作,并将更新推到远程仓库(git checkout master, git merge feature1, git push)。
4. 删除特性分支(git branch -d feature1)。

过程如下图所示:

Git 的分支工作流与 Pull Request

但是对于集成管理者工作流来说,集成管理者要如何知道有代码需要合并?要如何合并代码?Git 中引入了 pull request 这一功能彻底的改变了代码的合并方式,这一特性也让其成为开源专用的版本控制工具。
pull request 是什么?用中文翻译过来是“拉请求”,假设以下场景:
1. Selim 开发了一个应用程序 My Blog,并通过某一 Git 远程托管平台对代码进行了托管。
2. 7m 鱼复制了 Selim 托管的库,然后在 App 上添加了一个新功能 feature1。
3. 现在 7m 鱼想要将新功能合并到 Selim 的分支上应该如何操作?如下图所示:

  Git 的分支工作流与 Pull Request

首先可以想到的就是使用上面提到的方法切换到 Selim 的 master 分支,然后执行 git merge Feature1 命令,但是如果 7m 鱼没有 Selim/Master 的修改权限呢?Selim/Master 是属于 Selim 的,7m 鱼无法修改 (典型的集成管理者模式,这里“Selim”就是集成管理者),为了解决这个问题 Git 实现了“Pull Request(拉请求)”,注意是“拉(pull)”不是“推(push)”,这个请求的 目的是让仓库所有者来“拉”取变化,由所有者来决定合并还是拒绝,所有者可以根据功能是否合理、代码是否正确、易读等信息进行判断 ,这实际上就是 CodeRview 的过程。
下面创建一个新的代码仓库来演示 Git 的 Pull Request,Pull Request 的要求就是需要两个远程分支(仓库) 进行合并(代码拥有者的分支和代码贡献者的分支):
1. 克隆 My Blog 代码,创建一个新的远程仓库(本例使用 GitHub 作为托管平台,可以直接 fork):
git clone https://github.com/yqszt/MyBlog.git
git remote add other https://github.com/SelimTeam/MyBlog.git
git push -u other
新建的远程仓库:

Git 的分支工作流与 Pull Request

2. 在克隆的代码中修改内容并提交:

Git 的分支工作流与 Pull Request

3. 要将这两次提交生成“pull request”:
使用 git request-pull 命令生成拉请求信息:
git request-pull -p 5bf2e35 https://github.com/SelimTeam/MyBlog.git master

Git 的分支工作流与 Pull Request

其中 p 代表输出详细内容 (代码的差异),5bf2e35 对应的是提交的 hash,代表更新的内容是从哪一个提交开始,url 代表的是贡献者的仓库地址,最后的 master 代表更新内容结束的提交,默认是分支的最新提交
4. 将 pull request 信息告知作者,作者将会知道 贡献者的仓库地址 分支 从哪一个提交开始 哪一个提交结束 ,并且带有 详细的变更信息
注:这里的告知是通过邮件等方式将上面 request-pull 命令生成的信息发送给作者,github 等平台上提供的 pull request 功能是由平台自己实现的通知方式,关于 github 上的 pull request 后续介绍。
5. 作者添加贡献者的远程仓库,获取并将更新合并到主分支:
git remote add selimteam https://github.com/SelimTeam/MyBlog.git
git fetch selimteam master
git diff master selimteam/master

Git 的分支工作流与 Pull Request

git merge selimteam/master

Git 的分支工作流与 Pull Request

git push
以上就完成了一次通过 pull request 像作者贡献代码的流程。

Git 常用的 GUI 工具

从上一篇文章开始都是介绍如何通过命令行的方式使用 Git 进行代码管理,但在前面的文章中就提到过 Git 除了原生的命令模式还有 GUI 模式,GUI 主要是针对 Git 的命令进行封装然后提供了一些更便利的功能来简化使用、提高开发效率。
Git 中常用的 GUI 工具有以下几种:

  • SourceTree: 一个开源的 Git GUI 工具,有一个重要的点是它 提供了对 git flow 的支持

Git 的分支工作流与 Pull Request

https://www.sourcetreeapp.com/
安装参考:https://www.cnblogs.com/cheese320/p/8876782.html

  • GitHub For Desktop:GitHub 的 GUI 客户端,可以通过它 直接提交 pull request(GitHub 的 PullRequest)

Git 的分支工作流与 Pull Request

  • Visual Studio:VS 在团队资源管理器中集成了 Git 的支持,可以在 修改完成代码后便捷的进行代码的提交、push 等操作

Git 的分支工作流与 Pull Request

Git 的 GUI 工具有很多,可以通过该链接查找:https://git-scm.com/download/gui/win

小结

本文主要介绍了 Git 分支和 Git 的工作流,Git 的工作流分为两个方面“分支工作流”和“分布式工作流”,两种工作流是混合在一起使用的,前者是用分支对代码进行隔离,后者使用多个远程库以及 Pull Request 解决了分布式开发、合并的问题。
文章的最后介绍了常用的 Git GUI 工具,在实际开发中选择适合的 GUI 工具可以大大的提高开发效率。

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计6500字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中