我有一个我一直在研究的分支。git status表明它是最新的。
我检查了 master,它“落后于 43 个提交并且可以快进”。
git merge --ff-only
Run Code Online (Sandbox Code Playgroud)
现在 master 是最新的,我再次检查了我的分支。git status显示它仍然是最新的。
我现在想变基来掌握:
git pull --rebase
Run Code Online (Sandbox Code Playgroud)
但是我最终在一个只有我更改的文件上遇到了一系列合并冲突。我尝试修复合并冲突,但每个人git rebase --continue都提出了另一个冲突,似乎回应了我对它所做的每一个更改。
事实上,有问题的文件被重命名,我得到的合并冲突是旧文件名。在过去的几天里,我执行了多次提交,对文件进行了更新并重命名了几次。一切都在我的分公司完成。每次我进行更新时,我都会提交并将其推送到我的分支。
我不明白合并冲突的原因。该文件在我的分支中看起来是最新的。什么可能导致这种情况发生?
我不明白合并冲突的原因。
问题似乎是 Git 将重命名的文件错误配对。
事实上,有问题的文件被重命名,我得到的合并冲突是旧文件名。在过去的几天里,我执行了多次提交,对文件进行了更新并重命名了几次。一切都在我的分公司完成。每次我进行更新时,我都会提交并将其推送到我的分支。
git merge的,但它适用于git rebase以及当 Git 被要求合并两个分支提示——或者实际上是任何一对提交(HEAD,当前分支,和其他一些分支提示提交或任何其他提交),Git 将首先使用git merge-base --all来识别这些之间的合并基础两个提示提交:
...--o--B--o--o--...--H <-- branchA (HEAD)
\
o--o--...--T <-- branchB
Run Code Online (Sandbox Code Playgroud)
文件被重命名多少次,或者在哪个分支上都无关紧要。重要的是 Git 在运行时看到的内容:
git diff --find-renames B H
git diff --find-renames B T
Run Code Online (Sandbox Code Playgroud)
任何文件的Git标识在提交“相同”B和H,或犯“相同”B和T,被下旨是“同一个文件”,无论其实际路径名的提交B,H和T。
无论改变Git把之间B和H是“我们的”改变(--ours)。无论改变Git把之间B和T是“自己”的变化(--theirs)。Git 现在尝试结合这些更改。在它们重叠的地方,Git 会抱怨合并冲突。
如果Git是误识别了一些路径B具有相同或不同的路径H或T,即(GIT认为)的文件版本之间的差异是在BVS同一文件(可能不同的路径名)的版本是H或者T不会是“好的差异”,并且会与其他差异发生严重冲突。这将产生您看到的合并冲突。
可能的解决方案是:
H和/或T这样的新提交中再次重命名文件,以便 Git 不会错误识别文件。-X find-renames=<value>扩展选项来git merge更改相似性索引,以影响 Git 认为“相同”的文件。请注意,如果在某些文件B与存在同名的H或T,Git会(目前)总是配对这两个文件了,即使他们没有关系。例如,假设 commitB有一个名为 的文件polish,指的是波兰国家,并且都提交H并将其T重命名为,polish-as-in-the-country而一个提交,或者H或T创建一个新文件,该文件polish指的是鞋油。Git 会用新的(鞋子)来标识B's polish(国家),polish因为它们是相同的名称。git diff可以告诉平原打破这种联系,但git merge不能。
重命名鞋抛光文件以polish-as-in-the-shoes将导致不GIT中看到一个polish在两者B和所述一个尖端提交。现在,Git 将搜索“最佳匹配”,然后polish-as-in-the-country每次都找到,并且知道在两个分支中都执行了相同的重命名。
运行git rebase <upstream>或git rebase --onto <target> <upstream>告诉 Git 复制一系列提交。对复制的提交(基本上)正如文档所说的那样git log <upstream>..HEAD。1 复制后的提交是由 给出的提交<target>,或者<upstream>如果您未指定<target>.
在任何情况下,一旦 Git 有了要复制的提交列表,它就会像git cherry-pick在每个提交上运行一样复制它们。(根据您的特定git rebase命令,这可能实际运行git cherry-pick,也可能通过 模拟它git format-patch ... | git am -3。我还没有构建一个很好的例子来说明这些何时产生不同的结果——但如果你确实遇到了合并冲突,那是因为git am -3回退到三个-way 合并,与使用 的效果相同git cherry-pick。)
令人讨厌的是,虽然您可以通过git merge(通过添加新提交或提供-X选项)控制合并结果,但在变基期间您几乎无法控制每个樱桃选择。任何cherry-pick 的合并基础是被选择的提交的父提交。该--theirs承诺是在提交被精挑细选,且--ours或HEAD提交在提交被内置在。如果 rebase 刚刚开始,那就是<target>你给的,否则就是最近成功复制的提交。
无论如何,此时您只能选择一个选项:手动正确合并文件。(嗯,或完全终止底垫的尝试,有git rebase --abort。然后,您可以使用git cherry-pick自己,反反复复,并添加-X如果适当的参数。)
1文档在这里有一个善意的谎言。这几乎是这些提交了Git副本; 它实际上是由 列出的那些git rev-list --cherry-pick --right-only --no-merges <upstream>...HEAD。这是同一个列表,除了它:
git patch-id在上游目标中具有相同内容的任何提交。此外,正如实际记录的那样,在某些情况下会--fork-point更改给定<upstream>参数的起点,以便省略更多提交。请参阅Git rebase - 在 fork-point 模式下提交选择。
| 归档时间: |
|
| 查看次数: |
532 次 |
| 最近记录: |