我将给出一个非常简单的实际工作流程示例。请想象一下,它非常复杂并且要花费很多时间(大约整天)进行思考。我将用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';
}
问题是我已经引入了新功能,然后发现了一个错误,逆转此过程似乎很难完成。 我不知道在实现新功能的过程中如何有效地在程序开发的两个(或更多)同时路径之间跳转。
答案 0 :(得分:2)
回顾一下,我想您拥有当前的工作树:
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创建一个新分支,您可以按照自己的速度进行开发,并提交一半的功能或不起作用的功能
当客户端发现一个错误时,请回溯到与其发布相对应的分支中,修复该错误并创建一个可以发布的新版本/补丁。
修复完成后,将修复与您的Dev / Master分支合并。 您可以将修复程序与该软件的其他版本对应的分支合并。
现在回到个人分支上工作,并完成功能,完成后,您可以将所有提交压缩为一个,以使该工作树生效:
o---o---o -------(fixSumBug)-----LastRealeaseBranch
\ \(merge when bug found)
F1------F2------F3-----O--------------------MasterBranch
\
squash(5*6+7) --personalDevBranch
现在,您可以将开发人员与管理员合并,并删除个人分支。我建议在合并之前重新设置基准,以便获得最后一棵树:
o---o---o -------(fixSumBug)-----LastRealeaseBranch
\ \(merge when bug found)
F1------F2------F3-----O------F(5*6+7)--------------MasterBranch
要达到此结果,前提是您位于personalDevBranch上:
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)
现在您处于这种状态,您在master之前就分支了:
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
现在您可以删除personalDevBranch并启动新功能
最好使用功能示例feature-sum-567的名称来命名personalDevBranch,以便其他人可以看到您在做什么,甚至可以在与master合并之前查看代码,但这是另外一回事了。 / em>
答案 1 :(得分:1)
我建议您使用名为Gitflow的工具和Vincent Driessen的分支模型。这是一种非常出色的模型,可以轻松管理复杂的项目。