git rebase master功能给出(重命名/删除)冲突,git rebase -i master功能没有

时间:2014-04-09 01:16:46

标签: git rebase

我遇到了一个奇怪的情况,我在git中有一个功能分支修改了一些文件并删除了一个文件“foo.js”。当我通过“git rebase master feature”重新定位到master时,我遇到了以下类型的冲突:

CONFLICT (rename/delete): src/main/resources/com/blah/bar.js deleted in Change some js and renamed in HEAD. Version HEAD of src/main/resources/com/blah/bar.js left in tree.

奇怪的是,无论是主分支还是功能分支都没有修改bar.js,更不用说删除了它。更重要的是,执行“git rebase -i master feature”不会产生冲突(选择所有“pick”时)。

一个可能的重要线索是foo.js和bar.js是相似但不相同的文件,稍微修改过的文件也类似于foo.js和bar.js.我可以做的唯一疯狂猜测是,对相关js文件进行的一些更改在某种程度上混淆了git,认为分支功能中的违规提交包括删除bar.js,然后重命名为foo.js(这是删除)到bar.js.这是可能/预期的吗?有谁知道为什么会发生这种情况?仅供参考,我在linux mint 16上使用git版本1.8.3.2。

1 个答案:

答案 0 :(得分:3)

有点不寻常,但你的诊断是正确的。

交互式rebase使用一系列git cherry-pick命令。非交互式rebase使用git-merge-recursive(默认情况下至少;请参阅git-rebase--merge目录中的git-core脚本,无论您的系统位于何处,或只需记下-s <strategy> git rebase)的参数,用于从旧的提交中进行每次新提交。正如-m / --merge的文档所述(虽然没有提到这是默认):

       Use merging strategies to rebase. When the recursive (default)
       merge strategy is used, this allows rebase to be aware of renames
       on the upstream side.
 
       Note that a rebase merge works by replaying each commit from the
       working branch on top of the <upstream> branch. Because of this,
       when a merge conflict happens, the side reported as ours is the
       so-far rebased series, starting with <upstream>, and theirs is the
       working branch. In other words, the sides are swapped.

您可以通过使用git diff -M --name-status 1 来比较可疑提交对来确定。如果这显示bar.jsD eleted,foo.jsRbar.js已广告GIT_EDITOR=: git rebase -i ... ,那就是罪魁祸首。

令人讨厌的是,无法为合并设置重命名阈值。幸运的是,解决方法只是运行交互式rebase并且不对命令系列进行任何更改,您可以通过执行以下操作来简化:

-p

或使用GIT_EDITOR=:选项来保留合并(如果你有合并,后者是不同的,但是有一个副作用是做一个“隐含的交互式”rebase,它只是设置-M而且关闭autosquash)。


1 如果您已将diff.renames配置为true,则不需要merge.renamelimit选项(请参阅git config documentation)。 Merge-recursive在内部设置重命名但不设置复制检测,并将“重命名限制”设置为以下任何一个适用的第一个:您配置的diff.renamelimit,如果有的话;你的1000如果有的话;或常数{{1}}。