如何让 git 正确合并移动的内容(不仅仅是文件)
我目前正在研究 git 的很多内容跟踪功能。很高兴知道 git 允许我找出已从一个文件移动到另一个文件的代码,但我想知道在合并中进行冲突解决时如何使用此功能。
场景如下:
我创建了两个文件 hello.cc
和 bye.cc
。我启动一个分支 topic
并将一些代码从 hello.cc
移动到 bye.cc
。如果我现在执行 git Blame -C bye.cc
,我可以看到该代码最初来自 hello.cc
,很高兴知道这一点。但是现在我切换到没有移动内容的原始分支,并更改了 hello.cc
中已在其他提交中移动的部分中的一些代码。如果我现在执行 git merge topic
,我会遇到 hello.cc
冲突。但是,除非我使用 diff3 样式(尽管我通常这样做),否则我只能看到此方法已从另一个分支的 hello.cc
中删除,但不能看到它之后已更改。最好是在 bye.cc
上也出现冲突,因为有必要检查来自其他分支的更改是否必须重新应用到代码中。这有可能吗?
我知道我可以手动找出代码已通过执行 gitblame --reverse -C topic...
移动。然而,对于一个人来说,我花了很长时间才弄清楚这种可能性,而大多数其他人可能不知道这一点。其次,我很懒,可能会忘记代码可能已被移动。另外,我不确定当代码被移动到多个文件时这是否有效。
您会采取什么方法来尽可能保证这种情况的安全?
编辑:
我刚刚发现 gitblame --reverse -C hello.cc $(git merge-base HEAD topic)..topic
也可以找出内容已移动。如果我正确理解 git,这可能会更快,因为它不会对完整存储库中的内容进行完整搜索。
编辑:
我将用于玩耍的存储库上传到github,以便您可以自己尝试一下合并。我移动该函数的提交位于主题分支中。在 master 分支 merge_here
的 HEAD 处更改相同函数的提交。 master 中有一个额外的提交,其中我正在尝试一些其他合并技术,对于这个问题你应该忽略它。
I am currently looking at a lot of the content tracking features of git. It is very nice to know that git allows me to figure out code which has been moved from one file to another, but I am wondering how this feature is usable when doing conflict resolution in merges.
Here is the scenario:
I have two files hello.cc
and bye.cc
created. I start a branch topic
and move some code from hello.cc
to bye.cc
. If I now do a git blame -C bye.cc
I can see that this code originally came from hello.cc
which is nice to know. However now I switch to the original branch without the moved content and change some code within the section in hello.cc
that has been moved in the other commit. If I now do a git merge topic
I get a conflict for hello.cc
. However unless I use a diff3 style (which I usally do though), I can only see that this method has been removed from hello.cc
in the other branch, but not that it has been changed afterwards. What would be nice would be to also get a conflict on bye.cc
because it would be necessary to check if those changes from the other branch will have to be reapplied to the code. Is this somehow possible?
I know I can manually figure out, that the code has been moved by doing a git blame --reverse -C topic...
. However for one it took me quite a while to figure out this possibility and most other will probably not know about it. For second I am lazy and will probably just forget that the code might have been moved. Also I am not sure that this works when the code has been moved to more than one file.
What would be your way to keep this situation as safe as possible?
Edit:
I just found out that git blame --reverse -C hello.cc $(git merge-base HEAD topic)..topic
also works to find out where the content moved. And if I do understand git correctly, this is probably faster, because it will not do a full search of the content in the full repository.
Edit:
I uploaded the repository I am using for playing around to github so you can try out the merge for yourself. The commit where I moved the function is in the topic branch. The commit where the same function get's changed in master at HEAD of branch merge_here
. There is one additional commit in master in which I was playing around with some other merging techniques, which you should ignore for this question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我担心 git 不可能自动识别合并中移动的代码并产生冲突等,除非这些文件被重命名。
这里已经有一些关于这个主题的讨论,例如 git 如何处理合并移动到不同文件的代码? 和 git合并:将更改应用于移动到的代码一个不同的文件。
I am afraid it is not possible for git to automatically recognize moved code in merge and produce conflicts etc, unless those are whole files renamed.
There were already some discussions on this topic here, like how does git handle merging code that was moved to a different file? and git merge: apply changes to code that moved to a different file.
不幸的是,我的代码遇到了同样的陷阱,在 git 中移动文件后,它无法识别分支合并期间的更改。
看来,指导移动工作的黄金法则是:
GIT 目前无法跟踪此类情况。似乎没有快速/自动化的解决方案来找出文件移动然后合并后的潜在问题。
即使您知道问题发生的两个提交,并尝试应用补丁或恢复移动+合并后丢失的更改,您仍然会受到 git 的拒绝:
Unfortunately, got to the same trap with my code, after move of file in git, it doesn't recognize the change during branch merge.
It seems, the golden rule one have to guide working with move is:
GIT can't track such the cases, as for now. And it seems there's no quick/automated solution to figure out potential problems after file move and then merge.
Even if you'll know both commits where the problem happened, and will try to apply patch or revert changes lost after move + merge, you'll still get reject from git alike:
你可以使用 git 将任何内容放入你的提交中,它会正常工作。
You can use git to put whatever into your commit it will work fine.