使用git rebase删除提交时发生冲突

时间:2019-05-11 12:07:27

标签: git git-rebase

我有一个本地git存储库,其中包含一些我想删除的提交。更准确地说,我想重写整个存储库历史记录,就好像从未发生过给定的提交一样。例如,herehere讨论了删除旧提交,但由于某些原因,它对我不起作用。

要有一个具体可行的示例,请考虑如下构建的git存储库

git init .
echo hello >foo.txt
git add foo.txt
git commit -a -m first
echo hello2 >>foo.txt
git commit -a -m second
sed -i 's/hello2/hello2 bis/' foo.txt
git commit -a -m second_bis
echo hello3 >>foo.txt
git commit -a -m third

git库现在包含一个文件foo.txt,其中包含

hello
hello2 bis
hello3

由``git log -p --all``获得的完整git历史记录是(作者/日期已删除)

commit 7bd2f440ef5a0cbfd0fd252671d1651a6c282db5
Author: ---
Date: ---

    third

diff --git a/foo.txt b/foo.txt
index 83d1cb0..ce5a249 100644
--- a/foo.txt
+++ b/foo.txt
@@ -1,2 +1,3 @@
 hello
 hello2 bis
+hello3

commit c2c7f8c66ddb40fc6196350ea5e4f4c54293cf54
Author: ---
Date: ---

    second_bis

diff --git a/foo.txt b/foo.txt
index 97531f3..83d1cb0 100644
--- a/foo.txt
+++ b/foo.txt
@@ -1,2 +1,2 @@
 hello
-hello2
+hello2 bis

commit 853dca5b3c9152ab50cdf9de260f1a3b4bba4100
Author: ---
Date: ---

    second

diff --git a/foo.txt b/foo.txt
index ce01362..97531f3 100644
--- a/foo.txt
+++ b/foo.txt
@@ -1 +1,2 @@
 hello
+hello2

commit 921efb9472e14333804dff575a71050213a770be
Author: ---
Date: ---

    first

diff --git a/foo.txt b/foo.txt
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/foo.txt
@@ -0,0 +1 @@
+hello

在这一点上,假设我想删除带有注释“ second_bis”的提交,以便拥有如下所示的历史记录

commit 7bd2f440ef5a0cbfd0fd252671d1651a6c282db5
Author: ---
Date: ---

    third

diff --git a/foo.txt b/foo.txt
index 83d1cb0..ce5a249 100644
--- a/foo.txt
+++ b/foo.txt
@@ -1,2 +1,3 @@
 hello
 hello2
+hello3

commit 853dca5b3c9152ab50cdf9de260f1a3b4bba4100
Author: ---
Date: ---

    second

diff --git a/foo.txt b/foo.txt
index ce01362..97531f3 100644
--- a/foo.txt
+++ b/foo.txt
@@ -1 +1,2 @@
 hello
+hello2

commit 921efb9472e14333804dff575a71050213a770be
Author: ---
Date: ---

    first

diff --git a/foo.txt b/foo.txt
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/foo.txt
@@ -0,0 +1 @@
+hello

我尝试的方法是使用git rebase来消除提交“ second_bis”

git rebase -i 853dca5b

这会打开我的编辑器,其中包含一个文件

pick c2c7f8c second_bis
pick 7bd2f44 third
# Rebase 853dca5..7bd2f44 onto 853dca5 (2 commands)
#
#...

这时,在与“ second_bis”有关的行上,用“ drop”替换“ pick”。 令我惊讶的是,git无法管理该操作并且抱怨有冲突

Auto-merging foo.txt
CONFLICT (content): Merge conflict in foo.txt

当然,在这个简单的示例中,我可以手动解决冲突,但这违背了自动删除提交的想法。甚至更糟的是,在具有“第三”之后的进一步提交的存储库中,解决冲突后git rebase再次抱怨“第三”之后的提交发生冲突,依此类推。

为什么git rebase无法自动解决冲突?

是否有一种自动方式来删除“ second_bis”提交?

或者,是否有可能对历史记录中的每个提交应用补丁“ second_bis-> second”,然后最终删除并非没有的提交?

2 个答案:

答案 0 :(得分:1)

问题是,完成对文件添加hello3的修订的更改后,上一行是“ hello2 bis”,而不仅仅是“ hello 2”,并且原始修订中受影响的行之后没有任何内容,因此git可以真的不知道发生了什么事。通过在sed之前添加hello3来给git带来更多上下文,它的工作原理就像一个魅力:

git init .
echo hello >foo.txt
git add foo.txt
git commit -m first foo.txt
echo hello2 >>foo.txt
git commit -m second foo.txt
echo hello3 >>foo.txt
git commit -m third foo.txt
sed -i 's/hello2/hello2 bis/' foo.txt
git commit -m second_bis foo.txt
echo hello4 >> foo.txt
git commit -m hello4 foo.txt

作为旁注,如果您尝试在文件中包含至少两行之前和之后至少两行的文件中,而不是使用具有1、2、3行的文件,说明也将起作用。突然的EOF确实使git难以完成其工作(显然,我通过在sed之前添加hello3来避免这种情况。)

答案 1 :(得分:0)

似乎您的second_bis是最后一次提交,您可以执行以下操作,

修改最后提交消息

git commit --amend
#change second_bis into third

重置上一次提交

git reset HEAD~
git add *
git commit -a -m "third"
#now 3rd commit shows third

还原上一次提交

如果您已经将更改推送到服务器,则可以还原

git revert HEAD
#revert done change for third commit
git add *
git commit -a -m "third"
#now 3rd commit shows third