在使用rebase -ir处理不相关的提交之后,如何重做合并冲突解决方案?

时间:2019-03-08 21:03:09

标签: git git-rebase git-merge-conflict

举个简单的例子,假设我们有一个回购协议,其中错误的行被添加到文件a

$ git init 
Initialized empty Git repository in /someplace/.git/
$ echo "a1\nb2" > a
$ echo b1 > b    
$ git add .
$ git commit -m init  
[master (root-commit) 917f3b9] init
 2 files changed, 3 insertions(+)
 create mode 100644 a
 create mode 100644 b

分支master然后派生出新分支f

$ git branch f

然后在master中,将另一行添加到不正确的文件中。

$ echo b3 >> a
$ git commit -am 'added b3 to a' 
[master e44bc9f] added b3 to a
 1 file changed, 1 insertion(+)

在分支f中,我们做一些无关的事情,提交它,

$ git checkout f
$ echo c1 > c 
$ git add .
$ git commit -m "added c"
  1 label onto
[f 7cb63b2] added c
 1 file changed, 1 insertion(+)
 create mode 100644 c

然后我们将错误地放置在文件a中的行移动到文件b。

$ echo b2 >> b
$ sed -i '/b2/d' a
$ git commit -am "moved b2 to where it really belongs"
[f 32cee76] moved b2 to where it really belongs
 2 files changed, 1 insertion(+), 1 deletion(-)

然后,我们尝试将master合并到f,但是遇到这样的冲突:master添加了另一行错误,而f删除了第一行。

$ git merge master 
Auto-merging a
CONFLICT (content): Merge conflict in a
Automatic merge failed; fix conflicts and then commit the result.
$ cat a
a1
<<<<<<< HEAD
=======
b2
b3
>>>>>>> master

为解决冲突,我们将第二行错误的行移至正确的文件,然后提交合并。

$ echo b3 >> b
$ sed -i '/HEAD/,$d' a
$ git commit -a --no-edit 
[f 28d8543] Merge branch 'master' into f

然后,我们意识到有关c的提交不应在此分支中,因此我们用rebase -ir“删除”了它,并且遇到了与先前相同的冲突。

$ git rebase -ir $(git merge-base master @) # remove the commit about c
Auto-merging a
CONFLICT (content): Merge conflict in a
Could not apply 28d8543... onto # Merge branch 'master' into f
$ cat a
a1
<<<<<<< HEAD
=======
b2
b3
>>>>>>> refs/rewritten/onto

那么,考虑到冲突中没有出现的b添加的内容,重做以前的分辨率的最简单,最有效和通用的解决方案是什么?

3 个答案:

答案 0 :(得分:1)

有一个git实用程序,用于记录如何解决冲突,以便您以后可以重播。它称为git rerere

这实际上是针对特定用例的,并且由于该用例是基于我不同意的假设而进行的,因此我几乎从不使用git rerere

我还要说的是,在良好的工作流程中,您所描述的场景应该很少见,即使不存在,因此我个人不会立即使用rerere来记录每个冲突的解决方案,以后再需要。

但是...因为这是您提出的问题,git rerere可能是“答案”。

答案 1 :(得分:0)

到目前为止,想到的最好的解决方案(实际上并不是那么好)是放弃git并修补了合并冲突解决方案:

$ cp -a . ../$(basename $PWD)~
$ echo b3 >> b
$ sed -i '/HEAD/,$d' a
$ diff -ru ../$(basename $PWD)~ .
diff -ru ../t~/a ./a
--- ../t~/a 2019-03-08 12:54:34.701197573 -0800
+++ ./a 2019-03-08 12:54:56.761197321 -0800
@@ -1,6 +1 @@
 a1
-<<<<<<< HEAD
-=======
-b2
-b3
->>>>>>> refs/rewritten/onto
diff -ru ../t~/b ./b
--- ../t~/b 2019-03-08 12:54:34.701197573 -0800
+++ ./b 2019-03-08 12:54:54.044530686 -0800
@@ -1,2 +1,3 @@
 b1
 b2
+b3

我可以将该补丁保存在某个地方,并在需要再次解决该问题时应用它。问题是管理这些补丁程序,并根据纪律来预测何时需要重做冲突解决方案,或者总是对每个冲突解决方案都打补丁。

不过,我更喜欢使用git来管理此问题的解决方案。

答案 2 :(得分:0)

# List of all dataframes df_list = [df1,df2,....,df30] # List of Columns names for all dataframes colum_names =[['M1Pmax'],['M2Pmax'],...., ['M30Pmax']] for i in range(len(df_list)): df_list[i].columns = [colum_names[i]] 或制作git rerere的补丁是必要的,因为在Git 2.23中,refs/rewritten/onto将在refs/rewritten/onto被中止的特殊情况下被删除。 /> 结论“ git rebase -r”结束后,“ git rebase -ir”离开了git rebase --abort

请参见commit d559f50commit 37e9ee5commit d3fce47commit 7372eaePhillip Wood (phillipwood)(2019年5月14日)。
(由Junio C Hamano -- gitster --commit 88f95e4中合并,2019年7月9日)

  

refs/rewritten/:清理rebase --abort/--quit

     

refs/rewritten完成后,它将删除在其创建的rebase -r下的所有引用。
  但是,如果用户中止或退出,则不会删除基准查询。这可能会为将来的重新定位带来问题。

     

例如,我最近想将主题分支的更新版本合并到   集成分支因此运行refs/rewritten并删除了选择和标签   从待办事项列表中找到主题分支,这样

rebase -ir
     

将选择新的主题。
  不幸的是,merge -C <old-merge> topic 在先前的重新存储中已经存在   被中止,因此重新设置只是使用了旧主题,而不是新主题。

     

更改了非交互式退出案例的逻辑,以确保始终释放refs/rewritten/topic