git 重命名/删除混淆
我对特定的 git 行为有一个困惑:
以下是步骤和情况(稍后还会给出命令列表):
- 我有两个分支: master 和 XBranch
- 它们都有一个文件 src/a.txt 。它的内容是“旧内容”
- 在 XBranch 中我将 src/a.txt 重命名为 src/b.txt,使用:
mv
、git rm
、git add< /代码>。
-
在 master 中将文件重命名为 a.txt。在提交期间,我执行了
git rm src/a.txt
但忘记执行git add src/b.txt
在 master 中,我执行以下操作:git rm src/a.txt
和git commit
-
在 master 中,我将文件 b.txt 的内容编辑为“
新内容
- 在master中我执行
git add src/b.txt 和 git commit
- 在 master 中我这样做:
git merge XBranch
文件 src/b.txt 冲突,这是完全可以理解的。
但内容是“旧内容
”。为什么?
为什么不是这样的:
<<<<<<< HEAD
New Content
=======
Old content
>>>>>>> XBranch
命令列表:
sabya@SABYA-PC d:/merge_temp/test/case2
$ mkdir source
sabya@SABYA-PC d:/merge_temp/test/case2
$ git init
Initialized empty Git repository in d:/merge_temp/test/case2/.git/
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ mkdir src
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ vi src/a.txt
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ cat src/a.txt
Old Content
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git add src/
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git commit
[master (root-commit) 148500e] added src/a.txt
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 src/a.txt
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git branch XBranch
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git checkout XBranch
Switched to branch 'XBranch'
sabya@SABYA-PC d:/merge_temp/test/case2 (XBranch)
$ mv src/a.txt src/b.txt
sabya@SABYA-PC d:/merge_temp/test/case2 (XBranch)
$ git rm src/a.txt
rm 'src/a.txt'
sabya@SABYA-PC d:/merge_temp/test/case2 (XBranch)
$ git add src/b.txt
sabya@SABYA-PC d:/merge_temp/test/case2 (XBranch)
$ git commit
[XBranch b3ff8fa] changed a.txt to b.txt in XBranch
1 files changed, 0 insertions(+), 0 deletions(-)
rename src/{a.txt => b.txt} (100%)
sabya@SABYA-PC d:/merge_temp/test/case2 (XBranch)
$ git checkout master
Switched to branch 'master'
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ mv src/a.txt src/b.txt
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git rm src/a.txt
rm 'src/a.txt'
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git commit
[master bfeaecb] removed src/a.txt
1 files changed, 0 insertions(+), 1 deletions(-)
delete mode 100644 src/a.txt
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ vi src/b.txt
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ cat src/b.txt
New Content
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git add src/b.txt
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git commit
[master 2361d5e] changed content of b.txt
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 src/b.txt
sabya@SABYA-PC d:/merge_temp/test/case2 (master)
$ git merge XBranch
CONFLICT (rename/delete): Rename src/a.txt->src/b.txt in XBranch and deleted in HEAD
Automatic merge failed; fix conflicts and then commit the result.
sabya@SABYA-PC d:/merge_temp/test/case2 (master|MERGING)
$ cat src/b.txt
Old Content
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
存在冲突,但与文件内容无关。这是关于
树内容。
b.txt
,case2
目录(在 master 中),同一目录(在 XBranch 中)中 有一个重命名文件a.txt => b.txt
当您解决冲突时,您实际上选择了一个文件或
其他(文件中没有一行)。因此,结果中的“旧内容”
文件。
OP 在评论中添加:
这次,两棵树(分支
master
和XBranch
中的 case2 目录)引用新文件
a.txt
:其内容被合并,但存在冲突解决。之前,
a.txt
之间存在冲突(重命名为
b.txt
)和新 b.txt:这两个文件不能存在于同一分支,必须做出选择(文件,而不是文件内容)。
这意味着:
XBranch
(a.txt
重命名为b.txt
)合并到master
提交使用步骤 6 中的新
b.txt
(树冲突),XBranch
(a.txt
重命名为b .txt
)与新的master步骤 4(
a.txt
也重命名为b.txt
):相同的树内容,但不同blob内容:行冲突。
话虽这么说,OP仍然认为一定有一个错误:
注意:Git 2.18(2018 年第 2 季度)更改了合并递归的冲突检测报告。
请参阅 提交 6e7e027(2018 年 4 月 19 日),作者:伊利亚·纽伦 (
newren
)。当二进制文件在历史记录两侧被修改并重命名到不同位置时,两个文件都将写入工作树,但都将具有“
ours
”中的内容。Git 2.27(2020 年第 2 季度)已更正此问题,以便各方的路径都能获取其原始内容。
请参阅 提交 95983da(2020 年 5 月 13 日),作者:伊利亚·纽伦 (
newren
)。(由 Junio C Hamano --
gitster
-- 合并于 提交 abbd1d9,2020 年 5 月 20 日)There is a conflict, but not about the file content. It is about the
tree content.
case2
directory (in master), there is a new fileb.txt
a.txt => b.txt
When you are resolving the conflict, you are in effect choosing one file or the
other (not one line within the file). Hence the "Old Content" in the resulting
file.
The OP adds in the comments:
This time, both trees (the case2 directory in branches
master
andXBranch
)reference a new file
a.txt
: its content get merged, with conflictresolution. Before, there was a conflict between a
a.txt
(renamed as
b.txt
) and a new b.txt: both files cannot exist in thesame branch, a choice (of file, not of file content) had to be made.
That means that:
XBranch
(a.txt
renamed asb.txt
) tomaster
commitwith a new
b.txt
from step 6 (conflict of tree),XBranch
(a.txt
renamed asb.txt
) with master from newstep 4 (
a.txt
also renamed asb.txt
): same tree content, but differentblob content: conflict of lines.
That being said, the OP still thinks there must be a bug:
Note: Git 2.18 (Q2 2018) changes that conflict detection report with a merge recursive.
See commit 6e7e027 (19 Apr 2018) by Elijah Newren (
newren
).When a binary file gets modified and renamed on both sides of history to different locations, both files would be written to the working tree but both would have the contents from "
ours
".This has been corrected with Git 2.27 (Q2 2020), so that the path from each side gets their original content.
See commit 95983da (13 May 2020) by Elijah Newren (
newren
).(Merged by Junio C Hamano --
gitster
-- in commit abbd1d9, 20 May 2020)