前言
我们实际工作中难免会遇到需要回滚的情况,我想写这篇文章的原因也是因为最近我公司的项目出现了两次将 test 分支合并到了功能分支上的事情。我就想写篇如何处理的文章。
示例
这里展示如何使用 reset 还原自己分支的代码
master 代码如下
public class GitTest {
public static void main(String[] args) {
int a = 1 + 1;
int b = a * 2;
System.out.println(b);
}
}
现在我有三个分支:feature_1、feature_2、test,它们代码如下
feature_1
public class GitTest {
public static void main(String[] args) {
int a = 1 + 1;
int b = a * 2;
int c = b << 1;
System.out.println(c);
}
}
feature_2
public class GitTest {
public static void main(String[] args) {
int a = 1 + 1;
int b = a * 2 + 3;
System.out.println(b);
int d = b * b;
System.out.println(d);
}
}
假设现在我将 feature_1 feature_2 都合并到了 test,test代码如下
public class GitTest {
public static void main(String[] args) {
int a = 1 + 1;
int b = a * 2 + 3;
int c = b << 1;
System.out.println(c);
int d = b * b;
System.out.println(d);
}
}
feature_1 代码被修改了,如下
feature_2 代码被修改了,如下
然后不小心将test合到了 feature_2
随后其他人还改动了feature_1 feature_2并提交推送
feature_2 如下
feature_1 如下
test 如下
3 feature_2 要去掉 feature_1 的代码,即去掉 merge test 的错误操作
1、 先找到 merge test 的操作,如下
2 reset 错误操作的前一次 commit
这个 commit 的唯一编码 : ed03a75a30b7b72b36b9db488aa273a1853dbf54
可以看到有几种 reset 的方案,根据自己需要选择,我这里使用 Keep
得到之前的代码
3 切分支保存当前代码
push feature_2_new
4 使用 cherry-picking
我这里由于修改是同个地方,所以代码冲突,如下
5 所有需要的 commit 都 cherry-picking 之后,这个 feature_2_new 就会是我们期望的功能分支了
这里可能需要 feature_2 的同事停下先不要 commit,当如如果实在不能等,也可以继续开发提交合并 test。不过这样 feature_2_new 和 feature_2 就会存在追赶问题。
6 feature_2_new 再次合并到 test
解决冲突即可
如果要沿用过去的分支名,在解决后,需要将原分支删掉,然后再修改处理好的分支名重新 push。用上面的例子来说就是我要删掉本地和远程的 feature_2,然后再从 feature_2_new 切出分支 feature_2 重新 push。
建议
这里需要用到 cherry-pick,实际工作中会有很多 commit,很杂乱,不太好操作。因此,建议大家每个功能分支的每次提交都应该结合自己的需求版本作为 commit 信息的一部分,方便后面遇到需要 cherry-pick 时容易识别、操作。