如何组织 git 工作流以修复错误并同时引入新功能

How to organize git workflow to fix bugs and introduce new functionality simultaneously

本文关键字:新功能 错误 git 何组织 工作流      更新时间:2023-10-16

我将举一个非常简单的实际工作流程的例子。请想象一下,它非常复杂,需要花费大量时间来思考(大约一整天(。我将在 c++ 中举个例子,但选择的语言对于这个问题并不重要。


让我们想象一下,这是单个文件中的整个项目:

#include <iostream>
int sum(int a, int b) { return a - b; }
int main() {
std::cout << sum(4, 0) << 'n';
}

该项目的目的是打印"4"和"0"的总和。

现在我想在项目中引入新功能:查找产品 "5"和"6",然后添加到结果"7"中。归根结底,我想git commit -m "Result of 5 * 6 + 7"提交。好的,我从以下内容开始:

#include <iostream>
int sum(int a, int b) { return a - b; }
int product(int a, int b) { return a * b; }
int main() {
std::cout << sum(4, 0) << 'n';
std::cout << sum(product(5, 6), 7) << 'n';
}

我花了几个小时来实现此功能,现在想要测试它。不幸的是,结果是错误的:23 而不是 37。又经过几个小时的调试,我在函数中发现了一个错误sum

#include <iostream>
int sum(int a, int b) { return a + b; }
int product(int a, int b) { return a * b; }
int main() {
std::cout << sum(4, 0) << 'n';
std::cout << sum(product(5, 6), 7) << 'n';
}

现在程序是正确的,但是修复这个复杂的错误需要自己的提交。我太懒了,所以我将两个提交都加入到单个git commit -m "Result of 5 * 6 + 7"中。


我想保持提交的顺序清晰,以便我们可以轻松找到已经完成的工作和时间。我希望能够在修复错误时轻松找到答案,并将其与实现某些内容区分开来。

问题是在开发过程中支持清晰提交序列的git 命令的确切顺序是什么?对我来说,最清晰的方法是首先做出一个提交git commit -m "Bugfix in sum"

#include <iostream>
int sum(int a, int b) { return a + b; }
int main() {
std::cout << sum(4, 0) << 'n';
}

引入功能的第二个提交是git commit -m "Result of 5 * 6 + 7"

#include <iostream>
int sum(int a, int b) { return a + b; }
int product(int a, int b) { return a * b; }
int main() {
std::cout << sum(4, 0) << 'n';
std::cout << sum(product(5, 6), 7) << 'n';
}

问题是我已经引入了新功能,然后发现了一个错误,逆转这个过程似乎很难完成。 我不知道在实现新功能的过程中如何有效地在程序开发的两条(甚至更多(同时路径之间跳转。

回顾一下,我想你有当前的工作树:

C1---C2---(5*6+7)---(fixSumBug)---DevBranch

但是你说也许客户端需要fixSumBug提交,但不需要新功能。

所以我想你应该有一个这样的工作流程:

o---o---o ----(fixSumBug) ---LastRealeaseBranch
                    (merge when bug found)
F1------F2------F3-----MasterBranch

impl(4+0)----half(5*6)---(5*6+7) --personalDevBranch

MasterBranch是下一个版本的状态,功能F1,F2,F3已经开发。

您开始处理 5*6+7 功能,因此您可以从 master 创建一个新分支,您可以在其中以自己的速度进行开发并提交一半的功能或非工作功能(

当客户端发现错误时,请返回与其版本对应的分支,修复此错误并创建可以发布的新版本/补丁。

修复完成后,将修复与开发/主分支合并。 您可以将修复程序与对应于其他软件版本的分支合并。

现在回到你的个人分支上工作,完成后完成你的功能,你可以将所有提交压缩为一个,以获得这个工作树:

o---o---o -------(fixSumBug)-----LastRealeaseBranch
                    (merge when bug found)
F1------F2------F3-----O--------------------MasterBranch

squash(5*6+7) --personalDevBranch

现在,您可以将开发人员与 master 合并并删除您的个人分支。我建议在合并之前变基,以便您获得最终树:

o---o---o -------(fixSumBug)-----LastRealeaseBranch
                    (merge when bug found)
F1------F2------F3-----O------F(5*6+7)--------------MasterBranch

要获得此结果,假设您在个人开发分支上:

git fetch #to get last state of master
git rebase -i origin/master #maybe you have to fix some conflict if other developer change the same file contained in personal dev with option -i you can choose to squash commit into one (find how to use it)

现在你处于这种状态,你的分支就在前面的主人:

o---o---o -------(fixSumBug)-----LastRealeaseBranch
                    (merge when bug found)
F1------F2------F3-----O-------MasterBranch

squash(5*6+7) ---personalDevBranch

如果一切正常,您可以返回主并合并

git checkout master
git merge --ff-only personalDevBranch #--ff-only ensure a lineare history
git push #if everything is ok

现在您可以删除您的个人开发分支并启动新功能

功能示例 feature-sum-567 的名称命名 personalDevBranch 是一个很好的做法,这样其他人可以看到你在做什么,甚至在与 master 合并之前查看你的代码,但那是另一回事了。

我可以推荐你使用一个名为Gitflow的工具和Vincent Driessen的分支模型。这是一个非常棒的模型,可以轻松管理复杂的项目。