为什么合并不会导致冲突 [英] why merge does not cause conflict

查看:185
本文介绍了为什么合并不会导致冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题遵循这个话题。我试图了解 merge 做的过程,以避免发生不必要的错误。



我有两个分支: b 。我看到了做一个奇怪的结果 git merge 。您可以在合并之前看到输出git log ,在这里:

  * 148c970(HEAD,master)将master中的1重命名为1_master 
| * ad18d9b(b)将b中的1重命名为1_b
| /
* 15cd89b在主
中添加1


因此,我在 master b中有一个名为 1 的文件。然后在 master 中将其重命名为 1_master ,并将其重命名为 1_b in b 。然后我做了 git merge

  git merge b 

我猜这会导致冲突,因为合并基数必须是 15cd89b 并且两个分支都对 1 进行了更改,它们不匹配。 但是合并不会导致任何错误冲突,合并后我看到 1_b 1_master in工作目录。



注意:



我认为 torek twalberg 在上述情况下的链接回复预测冲突。如果我试图重现你的问题,我会得到一个重命名/重命名冲突,正如我所期望的那样。首先,我创建了一个存储库和一些文件(包含独特的内容):

  $ mkdir rename -ex 
$ cd rename-exp /
$ git init
在/home/torek/tmp/rename-exp/.git/
$ cat>中初始化的空Git存储库。 1
这是初始状态下的文件1。
使用
文件测试
发生了什么,在Git中重命名冲突

文件需要一些内容
,以便git可以检测
重命名,当我们实际上
做重命名时。
$ cat> 2
这是文件2。
我们给它一些内容
,以便它具有唯一的SHA-1。
$ git add。
$ git commit -m初始
[master(root-commit)a4b6f52] initial
2个文件已更改,12个插入(+)
创建模式100644 1
create模式100644 2

接下来,我创建分支 b 并重命名。请注意,我是否使用 git mv mv 进行重命名,然后是 git rm --cached git add (但 git mv 更容易,所以我用它)。但是,重要的是git能够检测到重命名。这要求文件完全匹配100%(简单情况)或匹配至少50%(该阈值可以调整,但50%是默认值),当diff-ed git merge 时,旧名称( 1 )在两棵树中不再存在。

  $ git checkout -bb 
转换到新分支'b'
$ git mv 1 1_b
$ git commit -m'在分支b'中重命名1到1_b
[b cc104b1]在分支中重命名1到1_b b
1个文件已更改,0个插入(+),0个删除( - )
重命名1 => 1_b(100%)

然后,我使用不同的名称目标在 master

  $ git checkout master 
切换到分支' master'
$ git mv 1 1_master
$ git commit -m'将master 1'重命名为1_master'
[master b891757]将master 1中的1重命名为1_master
更改了1个文件, 0个插入(+),0个删除( - )
重命名1 =>> 1_master(100%)

最后,我运行 git merge $ b $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ CONFLICT(重命名):重命名1 - > HEAD分支中的1_master在b中重命名1 - >1_b
自动合并失败;修复冲突,然后提交结果。
$

您需要显示您的步骤(也可能是您的git版本)为了让我明白为什么你的合并认为每一个改变都是删除和创建(与非冲突创建),而不是重命名。



影响这个的其他变量:


  • 合并期间 -X重命名阈值的任何参数如何调整50%的默认值);
  • 来自的值
  • 如果没有 merge.renameLimit 来自 git config --get diff.renameLimit 的值c>。

This question follows this topic. I am trying to understand what merge do to avoid unwanted mistakes during it.

I have two branches:master,b. I saw an strange result of doing git merge. You can see output of git log before merging, here:

* 148c970 (HEAD, master) rename 1 in master to 1_master
| * ad18d9b (b) rename 1 in b to 1_b
|/  
* 15cd89b add 1 in master

So I had a file with name 1 in master and b. Then rename it in master to 1_master and to 1_b in b. Then I did git merge:

git merge b

I guess it causes a conflict, because merge base must be 15cd89b and both branches introduce changes on 1, which they don't match.

But merging did not cause any conflict and after merging I saw both 1_b and 1_master in working directory.

Note:

I think both torek and twalberg in linked answers forecast conflict in above situation.

解决方案

If I attempt to reproduce your issue I get a rename/rename conflict, as I would expect. First, I created a repository and some files (with unique contents):

$ mkdir rename-exp
$ cd rename-exp/
$ git init
Initialized empty Git repository in /home/torek/tmp/rename-exp/.git/
$ cat > 1
This is file "1" in its initial state.
The file is being used
for a test of what happens with
a rename vs rename conflict
in Git.
The file needs some contents
so that git can detect the
rename when we actually
do the rename.
$ cat > 2
This is file "2".         
We give it some contents
so that it has a unique SHA-1.
$ git add .
$ git commit -m initial
[master (root-commit) a4b6f52] initial
 2 files changed, 12 insertions(+)
 create mode 100644 1
 create mode 100644 2

Next, I create branch b and rename. Note that it will not matter whether I do the rename with git mv or with mv followed by git rm --cached and git add (but git mv is easier, so I use it). It is, however, important that git be able to detect the rename. This requires that either the files match 100% exactly (the easy case) or that they match "at least 50%" (this threshold can be adjusted, but 50% is the default) when diff-ed and that the old name (1) is no longer present in both trees at the time of the git merge.

$ git checkout -b b
Switched to a new branch 'b'
$ git mv 1 1_b
$ git commit -m 'rename 1 to 1_b in branch b'
[b cc104b1] rename 1 to 1_b in branch b
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename 1 => 1_b (100%)

Then I do the same rename, with a different name-target, in master:

$ git checkout master
Switched to branch 'master'
$ git mv 1 1_master
$ git commit -m 'rename 1 to 1_master in master'
[master b891757] rename 1 to 1_master in master
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename 1 => 1_master (100%)

Finally, I run git merge:

$ git merge b
CONFLICT (rename/rename): Rename "1"->"1_master" in branch "HEAD" rename "1"->"1_b" in "b"
Automatic merge failed; fix conflicts and then commit the result.
$ 

You'll need to show your steps (and perhaps your git version as well) in order for me to see why your merge thought each change was delete-and-create (with non-conflicting creates) rather than rename.

Other variables that affect this:

  • any argument to -X rename-threshold during the merge (this is how you tune the 50% default);
  • the value from git config --get merge.renameLimit
  • the value from git config --get diff.renameLimit, if there is no setting for merge.renameLimit.

这篇关于为什么合并不会导致冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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