优秀的编程知识分享平台

网站首页 > 技术文章 正文

Git工作流基础——Git功能分支工作流

nanyue 2024-11-07 11:26:54 技术文章 2 ℃

功能分支工作流的核心思想就是所有功能的开发都应隔离在专有分支之内,而不应该在主分支内进行任何功能开发。进行如此封装可以避免多个开发者在开发特定功能的同时对主代码库产生负面影响。这也同时意味着主分支内永远没有未开发完成的代码,对于持续集成来说非常具有优势。

将功能开发封装在单独的功能分支中同时也使得pull request产生更多价值。在Git工作流程中,开发者之间可以通过pull request开展一系列对于开发内容的讨论。在pull request的过程中,开发者们可以在新代码被集成进主分支之前,有机会对具体代码进行审核。或者在另外一种场景中,当你开发受阻时,可以新开一个pull request,请求其他团队成员对具体代码提出建议和启发。重点在于,由于pull request流程的存在,让团队成员之间互相审视对方的代码变得简单到不可思议。

工作方式

功能分支工作流基于一个中心化的仓库,其中的主分支代表正式项目代码。开发者们每次开启一个新功能的开发时,需要新建一个分支,而不是直接向主分支提交开发代码。功能分支应该以有具体含义的名称命名,比如 animated-menu 或者issue-#1061这样的名字。这么做的目的是为了让分支承载的开发任务足够明确,足够聚焦。Git本身并不会对功能分支和主分支区别对待,为其提供不同的特性支持,所以开发者可以在功能分支上执行同样的操作:编辑,暂存,然后提交变更。

此外,功能分支可以(也应该)推送到中心仓库。推送到中心仓库的代码可以共享给其他开发者。另外,由于只有主分支是一个比较特别的分支,所以在中心仓库中存储若干个功能分支并不会产生什么问题。当然这也是一种用来备份本地提交的方法。下面我们就来演示一个功能分支的使用流程。

从主分支开发

所有的功能分支都应该创建自最新的主分支代码。在接下来的演示中,我们假设主分支名为main

git checkout main
git fetch origin 
git reset --hard origin/main

以上命令先将本地分支切换到main分支,然后更新最新的提交记录,并且最后使用reset命令把本地的main分支指向origin/main远程分支的最新提交。当然如果你对于reset不太熟悉,也可以使用如下更加常见的命令

git checkout main
git fetch origin
git pull origin main

创建新分支

基于本文最开始所说的关于功能分支的核心思想,当开发一个新功能时,需要为其专门创建一个独有分支。创建完成之后,别忘了切换到新创建的分支上。

git checkout -b new-feature

以上命令通过-b选项基于当前所在分支(也就是main分支),创建一个之前并未存在的new-feature分支。

更新,添加,提交以及推送

在功能分支上,编辑、暂存并且提交的方式与其他任何分支完全一样。所以就像你正常使用Git一样,在该分支上进行任何你认为需要进行的操作。最后在新功能开发完成时提交变更。

git status
git add <some-file>
git commit

向远程仓库推送分支

时不时地把本地分支推送到远程仓库是个好习惯。这一方面可以随时将本地变更备份在远程仓库中,另外在与其他开发者合作方面,允许他人查看你分支上的最新代码。

git push -u origin new-feature

以上命令会把new-feature分支推送到中心仓库(origin),添加的 -u 选项将其添加为远程追踪分支,以便未来执行git push操作时git自动判断需要推送到哪个远程仓库,就不再需要每次都添加origin之类的参数了。推送之后,就可以通过仓库托管软件新建pull request / merge request (github / gitlab / bitbucket etc.)。在这里可以指定其他开发者作为代码评审人,在合并之前对新提交的代码进行评审。

关于反馈

如果在pull request或者merge request页面,团队成员进行了代码评审并且通过了这次提交,那么就可以进行代码合并。但还有另外一种情况,也就是审查人员可能会提出一些修改建议,此时开发者可以在本地针对这些建议进行修改,然后再次执行一系列编辑,暂存,提交,推送的操作。此时针对这些建议的新修改会自动在pull request/merge request中呈现出来。

合并pull request

如果其他成员提交了同样段落的修改,pull request页面会告诉你此次提交有冲突发生,此时你需要先解决这些冲突。如果没有冲突或者冲突已经解决,并且通过了代码评审,那么就可以将分支合并进main分支。

Pull requests

除了可以隔离功能分支与主分支,分支还通过pull request提供了在合并之前针对开发内容进行讨论的能力。一旦有人完成了某个功能的开发,不要直接马上合并进main分支,请提交一个pull request并请求其他人帮忙,然后再合并进main分支。这样在新开发的代码融入主代码库之前,其他开发者有机会对其进行审查。

进行代码评审是pull request过程所提供的一个重要收益。虽然在pull request中进行的代码评审通常是针对一次合并所涉及到的新增代码,但代码评审本身毕竟是一种通用的关于代码本身的讨论。这也就意味着你可以在开发过程中的任何节点进行代码评审。比如在开发过程中需要其他人对正在开发的功能提供一些具体的帮助,直接发起一个pull request,让其他合作者深入到具体代码中来提供帮助吧。

一旦一个pull request被接受,接下来的发布流程就与我们在其他文章中讨论到的中心化工作流一致了。首先你需要确保本地的main分支与远程仓库的main分支同步,然后合并功能分支到main分支内,再推送回中心仓库即可。

示例

接下来的示例展示了使用功能分支工作流的一种场景。该场景描述了在团队内部,针对一个新功能的pull request进行代码评审的场景。

韩梅梅开始开发一个新的功能

在进行任何代码开发之前,先创建一个独立的分支。使用如下命令:

 git checkout -b hanmeimeis-feature main

通过上面的命令,韩梅梅基于main分支创建了一个新分支,名叫hanmeimeis-feature,-b 选项意味如果该分支不存在就创建它。在此分支上韩梅梅进行开发:

git status
git add <some-file>
git commit

韩梅梅开发告一段落,去吃午饭

韩梅梅在早上进行了几次提交。在中午吃饭之前,是个好时间点推送本地修改到远程仓库。这可以备份韩梅梅早上的工作,也可以让其他团队成员获取到韩梅梅早上提交的代码。

git push -u origin hanmeimeis-feature

上面的命令把hanmeimeis-feature分支推送到远程仓库。-u 选项会自动把这个分支添加为远程追踪分支,这样以后再进行git push操作时就不需要通过参数指定推送的具体远程仓库了。

韩梅梅开发完成

午饭归来,韩梅梅又做了几次提交,新功能终于开发完了。但是在合并到main分支之前,她需要先发起一个pull request让其他人知道她已经开发完成。首先,她需要推送本地代码,保证远程仓库的分支是最新的。

git push

接下来,韩梅梅在仓库托管软件的UI界面上发起一个pull request,请求将hanmeimeis-feature分支合并到main分支,此时团队其他成员就会自动收到托管软件发出的通知。在pull request的页面上,对于指定代码段落的评论会直接显示在这段代码旁边,所以可以很方便的就具体代码提出问题。

李雷收到pull request通知

李雷收到了通知,然后打算看看hanmeimeis-feature里都有些啥内容。看了之后,李雷认为在合并之前应该再做一点点修改,于是他俩在pull request中进行了一番讨论。

韩梅梅进行了修改

韩梅梅又一次进入了经典流程:编辑,暂存,提交,推送。之后她所有的更新就出现在了pull request页面上,于是李雷又开启了评论模式。

其实如果李雷愿意的话,他完全可以自己把hanmeimeis-feature分支拉到本地,然后自行修改。李雷进入经典流程之后作出的修改也同样会自动出现在pull request页面。但他没有这么做,可能因为他觉得自己是领导吧。

韩梅梅发布新功能

当李雷觉得韩梅梅的代码可以进行合并了,就需要有人去执行这个合并操作,然后新的代码就进入主分支里(这个操作谁都可以做,韩梅梅可以,李雷也可以,甚至是Jim或者Lily和Lucy)

git checkout main
git pull
git pull origin hanmeimeis-feature
git push

以上流程会在提交历史上留下一个合并提交的节点。有些人喜欢这样,因为这种合并提交历史可以明确的显示出何时何地进行了两个分支的合并。也有一些人更喜欢线性的提交历史,如果你是这样的人可以在功能分支执行rebase main分支的操作,这样功能分支的所有提交就会位于main分支的顶端,这样就可以进行一次快进合并。

与此同时,Tom也在经历着韩梅梅同样的事情:

当韩梅梅和李雷一直在讨论和合并hanmeimeis-feature时,Tom也在对自己的功能分支进行同样的操作。所以可以看到通过隔离功能分支的开发,每个人都可以独立进行开发工作,而且当确实需要与其他人共享代码时,也很容易办到。

总结

在本文档中我们讨论了git功能分支工作流。这个工作流聚焦于处理那些针对不同业务功能进行独立开发的分支。我们还以一个具体的例子展示了功能分支工作流是如何一步一步进行的。关于功能分支工作流我们得到以下结论:

  • 专注于分支模型
  • 同样可以被用于其他面向仓库的工作流程
  • 通过pull request和合并评审提升协作效果

在合并功能分支操作中使用git rebase可以避免让过多不相关的提交记录出现在git历史中。在团队中使用功能分支模型可以提升团队的协作表现。

最近发表
标签列表