为什么对文件的更改不被合并保留? [英] Changes to a file are not retained by merge, why?

查看:107
本文介绍了为什么对文件的更改不被合并保留?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个 merge 默默地忽略了合并分支的一些改变,我期望( rebase

以下是这种情况:

 
*把奴隶合并到主人:行不回
| \
| *哎呀,是坏的,把线回(奴隶分支)
| |
| *从属分支,也删除同一行
* | master分支,删除一行
| /
* initial

合并 slave 转换为 master ,该行保持被删除,所以放回的提交没有合并。 rebase会。



如果该行没有被删除但被修改,这将是一个冲突,这对我来说很好。一个rebase会接受这条线,也可以。但是,根本没有任何警告地跳过提交...我想知道它是如此设计的。注意:在网上搜索类似的问题发现很多......但所有涉及在合并之前被删除的整个文件。我可以承认这个原因,即使我更喜欢冲突(而不是失败)。但是,对于文件内部的更改,我发现这更令人不安,并且没有提及。



注意:我在Mercurial上检查过,结果相同,这不是特定于Git。

解决方案

原因是(文件级别)合并没有看到更改的路径;它看到了三个版本的文件: base 我们他们的 $ b 在分支删除一行并将其放回的情况下,他们的 base 是相同的(至少在有问题的线上)。事实上,在他们的历史中的某处,行不会是相同的,这是合并工具不知道的。



因此,对于他们的这一行不是被改变的大块的一部分;但是对于我们它是,所以我们接受我们中的更改。



我会同意,这不是你想从这个特定的合并,但我看不到任何合理有效的方法来做得更好。此外,在18年以上的编程中,我从未遇到这种情况 - 所以令人不安可能会有点强大。

(我还要注意,你的将这种特征描述为丢失提交并不是真正的准确,合并结果中包含了 ,仅仅是适得其反的方式。底线是自动合并算法永远不会是完美的;但是我们使用的大多数时间都是非常好的。)



我想如果你真的想记住分支考虑了什么的事实要做到这一点,并决定保留它,你可以对恢复后的行做一些无意义的改变。然后,如你所注意的那样,一个变化的行,它会出现冲突。



但是,真的,你运行单元测试,不是吗?如果这条线足够重要,可以在两条更换线中删除并重新添加其中一条,那么肯定会有一个测试用例在错误处理时会失败?你知道要测试你的合并结果吗?



要指出的是,这对于工具来说并不是很好的行为......但它很罕见无论如何,应该在成熟的开发过程中发现和纠正不良行为。我不会读得太多。


I have hit a case in which merge silently ignores some changes from the merged branch, which I would expect (rebase would take them).

Here is the case:

*    merge slave into master: line not back
|\
| *  oops, was bad, put the line back (slave branch)
| |
| *  slave branch, also delete the same line
* |  master branch, delete a line
|/
*  initial

When merging slave into master, the line remains removed, so the commit that put it back was not merged. A rebase would.

If the line was not removed but modified, this would be a conflict, which would be fine for me. A rebase would accept the line back, fine too. But skipping the commit with no warning at all... I would like to know for which cases it was designed so.

NB: Searching the web for similar questions found many... but all concerning whole files that were removed before being merged. I can admit reasons for this, even if I would prefer a conflict (rather than losing a commit). However, for changes inside a file, I find this more disturbing, and found no mention.

NB: I checked it on Mercurial, same result, this is not specific to Git.

解决方案

The reason is that a (file-level) merge doesn't see the path of changes; it sees three versions of the file: base, ours, and theirs.

In the case where the branch removed a line and then put it back, theirs and base are identical (at least on the line in question). The fact that, somewhere in the history of theirs, the lines would not have been identical is not known to the merge tool.

So for theirs the line is not part of a changed hunk; but for ours it is, so the change in ours is accepted.

I'll agree that it's not what you'd want from this particular merge, but I can't see any reasonably efficient way to do better. Also, in 18+ years of programming I've never run into this scenario - so "disturbing" might be a little strong.

(I'd additionally note, your characterization of this as "losing a commit" is not really accurate. The commit was included in the merge result, just in a counterproductive way. The bottom line is, automatic merge algorithms can never be perfect; but the ones we use are really good most of the time.)

I suppose if you really want to memorialize the fact that the branch considered what to do with the line and decided to keep it, you could make some "meaningless" change to the restored line. Then, as you note for the case of a changed line, it will come up as a conflict.

But really, you run unit tests, don't you? If this line is important enough to have been removed in two change lines and re-added in one of them, surely you have a test case that will fail if it's handled wrongly? And you know to test your merge results, right?

Point being, it's not good behavior for the tool... but it's a rare bad behavior that should be caught and corrected in a mature development process anyway. I wouldn't read too much into it.

这篇关于为什么对文件的更改不被合并保留?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆