Git工作流之功能分支工作流

Git 功能分支工作流(Feature Branch Workflow)背后的核心思想是所有功能开发应在专用分支而不是master分支中进行。这种封装使多个开发人员可以轻松地使用特定功能,而又不会干扰主代码库。这也意味着master分支将永远不会包含残破的代码,这对于持续集成环境是一个巨大的优势。

功能分支开发还可以利用合并请求(pull request),这是围绕分支发起讨论的一种方式。这为其他开发人员提供了在功能集成到正式项目中之前对其进行审查的机会。甚至,如果您在开发功能过程中卡住了,则可以开启一个合并请求(pull request),以征询同事的建议。更关键是,合并请求操作使您的团队可以非常轻松地就彼此的工作发表讨论。

Git 功能分支工作流是可组合的工作流程,其他高级 Git 工作流程也可以利用。Git 功能分支工作流是针对分支模型的,这意味着它是用于管理和创建分支的指导框架,其他工作流则更以仓库为中心。 Git 功能分支工作流可以合并到其他工作流程中。实际上,GitFlow 工作流(GitFlow Workflow)Git 派生工作流(Forking Workflow)在其分支模型方面使用了Git 功能分支工作流(Feature Branch Workflow)

运作原理

Git 功能分支工作流(Feature Branch Workflow)假设有一个中央仓库,而master则代表正式的项目历史记录,开发人员在每次开始使用新功能时都创建一个新分支,而不是直接在其本地master分支上提交。功能分支应具有描述性名称,例如animated-menu-itemsissue-#1061feature_xxxx,这样命名的目的是明确每一个分支的功能和作用。 Git 在主分支和功能分支之间没有技术上的区别,因此开发人员可以编辑、暂存和提交对功能分支的更改。

另外,可以(并且应该)将功能分支推送到中央仓库,这样就可以与其他开发人员共享功能,而无需更改任何正式代码。由于master是唯一的“特殊”分支,因此在中央仓库中存储多个功能分支不会造成任何问题。当然,这也是备份每个人的本地提交的便捷方法。以下是功能分支的生命周期。

从主(master)分支开始

所有功能分支都是根据项目的最新代码状态创建的。这里假设 master 分支即为我们项目的主分支。

1
2
3
git checkout master # 切换到 master 分支
git fetch origin # 提取最新的提交
git reset --hard origin/master # 重置仓库的master本地副本

这会将仓库切换到 master 分支,提取最新的提交,并重置仓库的master本地副本以匹配最新版本。

创建新分支

针对每一个新功能(或新 bug )创建一个单独的分支。创建分支后,请在本地将其检出(checkout),以便您所做的任何更改都将在该分支上。

1
git checkout -b new-feature

这会检出一个基于master的名为new-feature的分支,并且-b标志告诉 Git 创建该分支(如果该分支不存在)。

更新

在该分支上,以正常的方式编辑、暂存和提交更改,并根据需要构建多次提交。

1
2
3
git status  # 查看状态
git add <some-file> # 暂存文件
git commit # 提交更改

将功能分支推送到远程(中央仓库)

最好将功能分支推送到中央仓库。与其他开发人员协作时,这既可以用作备份,也能使其他人查看到新分支的提交。

1
git push -u origin new-feature

这样便将新功能推送到中央仓库(origin),并且加上-u标志将其添加为(上游)远程跟踪分支。设置跟踪分支后,后面提交代码时,无需任何其他参数即可通过git push命令来自动将更新操作推送到远程中央仓库。

接着,到 git 仓库管理平台(如 Bitbucket、Gitlab)去创建合并请求,将功能分支合并到master主分支。可以在提合并请求时指定审批人以确保顺利合并。(其间,如果有冲突,需要先解决冲突再提交)

合并请求

除了隔离功能开发之外,Git 分支还可以通过合并请求来讨论更改。某人完成一项功能后,不会立即将其合并到主功能中,相反,他们将功能分支推送到中央仓库,并提出合并请求,要求将其更改合并到主分支中。这使其他开发人员有机会在其更改成为主代码的一部分之前对其进行代码审查(code review)

代码审查是合并请求的主要好处,但实际上,它们是被设计用来讨论代码的通用方法。您可以将合并请求视为用于专门讨论特定分支的讨论地。这意味着它们也可以在开发过程中更早地被使用。例如,如果开发人员需要特定功能的帮助,则他们要做的就是提交合并请求。感兴趣的各方将被自动通知,他们将能够在相关提交旁边看到问题。

一旦合并请求被接受后,发布一个功能的实际操作与《Git工作流之集中式工作流》中的操作几乎相同。(关于合并请求,首先,您需要确保本地主机与上游主机同步。然后,将功能分支合并到 master 中,并将更新后的 master 推回中央仓库。仓库管理平台<如 Bitbucket、Gitlab>可以更好的简化该操作)。

示例

以下是使用功能分支工作流的示例,该场景是一个团队围绕新功能合并请求(pull request)进行代码审查(code review)的场景:

小丽开始一个新功能开发

model

在开始开发功能之前,小丽需要一个新的分支来进行工作,她可以使用下面命令创建一个新功能分支:

1
git checkout -b xl-feature master

这样便基于master分支创建了一个叫xl-feature的分支,-b标记是告诉 git 如果分支不存在就创建分支。

小丽为了完成新功能,在分支上进行开发、修改以及提交操作(可能重复多次):

1
2
3
git status
git add <some-file>
git commit

小丽中途吃午饭

到了午饭时间,当小丽有事要停下功能开发时,在她离开前最好将代码提交到中央仓库,一是方便代码备份;二是有利于其他开发人员看到她的初始提交。

1
git push -u origin xl-feature

此命令将xl-feature推送到中央仓库,并且使用参数-u标志将其添加为远程跟踪分支。设置跟踪分支后,小丽后面可以调用git push而无需添加任何其他参数来推送其功能。

小丽完成新功能

finish_xl

小丽吃完午饭回来,完成了剩余功能开发。在将其合并为 master 之前,她需要提交合并请求,以让团队的其他成员知道她已经完成了。但是首先,她应该确保中央仓库中有她的最新提交:

1
git push

然后,她通过仓库管理平台(如 Bitbucket、Gitlab)发起合并请求将xl-feature合并到master,团队其他人便可自动收到通知。合并请求的好处在于,它们在相关的提交旁边会显示注释,因此很容易提出有关特定变更的问题。

小王收到合并请求

pr_xw

小王收到合并请求,然后查看一下xl-feature,他决定在将其集成到正式项目之前要进行一些更改,并且他和小丽通过合并请求来回进行了一些操作。

小丽做出更改

change_xl

为了进行更改,小丽使用了该功能的第一次迭代完全相同的过程,她编辑、暂存、提交并将更新推送到中央仓库。她的所有操作行为都显示在合并请求中,并且小王在此过程中仍然可以发表评论。

如果他愿意,小王可以将xl-feature添加到他的本地仓库中,然后自己进行处理。他添加的所有提交也将显示在合并请求中。

小丽发布(已完成)功能

pf_xl

一旦小王准备好接受合并请求,就需要有人将功能合并到稳定的项目中(这可以由小王小丽来完成):

1
2
3
4
git checkout master
git pull
git pull origin xl-feature
git push

某些 GUI (仓库管理平台,如 Bitbucket、Gitlab)只需单击“接受”按钮,即可通过运行所有这些命令来自动执行合并请求接受过程。

同时,小明也在做完全相同的事情(进行新功能开发)。

小王小丽正在研究小丽开发的功能,并在其合并请求中对其进行讨论时,小明则在自己的功能分支中做着完全相同的事情。我们可以看到,通过将功能隔离到单独的分支中,每个人都可以独立工作,在必要时再与其他开发人员共享更改。

总结

在本文中,我们讨论了Git 功能分支工作流(Feature Branch Workflow)。此工作流有助于组织和跟踪专注于业务域功能集的分支。其他 Git 工作流(如派生工作流(Forking Workflow)GitFlow 工作流(GitFlow Workflow))是针对仓库的,可以利用 Git 功能分支工作流(Feature Branch Workflow)来管理其分支模型。本文档演示了用于实现Git 功能分支工作流(Feature Branch Workflow)的高级代码示例和虚构示例。与功能分支工作流相关的一些关键:

  • 专注于分支模式
  • 可以被其他面向仓库的工作流程所利用
  • 通过合并请求和合并审查促进与团队成员的协作

在功能分支的审阅和合并阶段使用 git rebase 将强制创建功能合并的 Git 历史记录。功能分支模型是在团队环境中促进协作的出色工具。

接下来,我们看看《Git工作流之GitFlow工作流》来更深入的了解 Git 工作流。

英文原文

Cleam Lee wechat
欢迎扫一扫订阅!