为什么git rebase在我没有修改的文件中显示冲突?

时间:2016-11-10 10:00:26

标签: git git-rebase

让我们说我在当地的回购中,它的分支是my_name/branch_A

当我git rebase <branch_B>时,我有时会在我未修改的文件中出现很多冲突。

为什么会这样? 我想从branch_B中获取所有文件的HEAD,除了我在my_name/branch_A中修改过的文件。如果不手动解决我自己没有介绍过的这些冲突,怎么办呢?

1 个答案:

答案 0 :(得分:7)

Rebase 副本提交(然后放弃原件)。这是问题的根源。

让我们看一个例子。首先,请注意我正在绘制提交图表,其中较旧的提交向左,较新的提交向右。提交在这里有单字母名称,而不是Git的真正的40个字符的哈希名称,如f1c93ab7...。分支名称显示在右侧,箭头指向该分支的 tip commit ,因为这就是Git实际存储这些内容的方式。

您当前的分支名称为my_name/branch_A,并且您还有一个名为branch_B的分支。每个分支上有一些提交不在另一个分支上,而一些提交在两个分支上。与此同时,您的分支my_name/branch_A从第三点开始分叉 - 因此您的分支上的提交不在branch_B上,但不是“您的提交”:

...--A--B--C--D--E         <-- branch_uhoh
         \        \
          \        I--J    <-- my_name/branch_A
           \
            F--G--H        <-- branch_B

您提交了IJ,现在您希望在提交H之后提交这两个提交,即将您的提交重新修改为“在”提示之后branch_B

换句话说,没有进行提交C--D--E。尽管如此,这些提交都在你的分支上。实际上,提交AB也在您的分支上:这两个提交位于 all 分支上。

如果您现在运行git rebase branch_B(当您还在分支机构时),Git必须弄清楚两件事:

  • 要复制的内容,
  • 从哪里开始复制。

名称branch_B告诉Git 这两件事。要复制的提交是“my_name/branch_A但不在branch_B上的提交。那是C-D-E-I-J。放置它们的地方是”在branch_B的提示提交之后,即,在提交H之后。

如果这一切都成功,Git会将您的分支名称设置为指向新副本:

...--A--B--C--D--E         <-- branch_uhoh
         \        \
          \        I--J    [abandoned]
           \
            F--G--H        <-- branch_B
                   \
                    C'-D'-E'-I'-J'  <-- my_name/branch_A

带有“prime”标记的名称(C'等)是副本。

(您可以查看git rebase将/将与git log <upstream>..HEAD一起复制的提交,在这种情况下为git log branch_B..HEAD。在大多数情况下,我会在此处添加--oneline每次提交获得一行日志消息。)

好吧,如果这是问题,你该怎么办?显而易见的答案是:告诉Git不要复制C-D-E。您想要这个结果:

...--A--B--C--D--E         <-- branch_uhoh
         \        \
          \        I--J    [abandoned]
           \
            F--G--H        <-- branch_B
                   \
                    I'-J'  <-- my_name/branch_A

也就是说,Git应该只复制branch_uhoh和你的分支之间“之间”(之后,之后)的提交,以便提交IJ;但它应该将它们复制到(再次,之后,真的)branch_B的提示。这样做的方法是写:

git rebase --onto branch_B branch_uhoh

换句话说,告诉rebase 两个事情,而不是告诉它一个事情并让它从中找出两个。

(但是你如何找到branch_uhoh?嗯,“正确”的方式通常是记住它,但你可以运行git log --graph --decorate --oneline并找到截止提交通过它的ID或显示的任何名称。而不是branch_uhoh你可以剪切并粘贴实际截止提交的哈希ID。大多数情况下,你可以让 Git本身记住你的“上游”名称,你只在内部和上游进行重新定义,你需要没有参数:你只需运行git rebase并完成所有工作。但是有特殊情况你需要移植提交,但这还不够;那么你需要git rebase --onto。)