简体   繁体   English

为什么`git checkout -m`没有合并成功?

[英]Why does `git checkout -m` succeed without merge?

Git Pocket Guide says Git Pocket Guide

Git ignores untracked files while switching branches, unless the file exists in the target branch ; 在切换分支时,Git会忽略未跟踪的文件, 除非该文件存在于目标分支中 then it aborts, even if the versions in the working tree and destination branch are the same. 然后,即使工作树和目标分支中的版本相同,它也会中止。 You can use the --merge option to get around this without having to delete the untracked file , only to have Git restore it a moment later. 您可以使用--merge选项来解决此问题,而不必删除未跟踪的文件 ,而只是让Git过一会儿将其还原。 The merge operation results in the same file, in this case. 在这种情况下,合并操作将产生相同的文件。

On branch master , I have a tracked file hellofile 在分支master ,我有一个跟踪文件hellofile

$ git branch 
  feature2
* master
$ cat hellofile 
hello
$ git status
On branch master
nothing to commit, working tree clean

On branch feature2 , it has no file hellofile , and I create it but leave it untracked 在分支feature2 ,它没有文件hellofile ,我创建了它,但未对其进行跟踪

$ git checkout feature2
$ ls
common  reader  README  writer
$ echo "world" > hellofile

I then try to checkout master . 然后,我尝试结帐master It is understandable that git checkout will fail, but with -m succeed. 可以理解, git checkout将失败,但是-m成功。 But why does git checkout -m succeed without merge? 但是为什么git checkout -m不合并就成功了? (I am expecting a file hellofile with marked conflict) (我期望文件hellofile带有明显的冲突)

$ git checkout master
error: The following untracked working tree files would be overwritten by checkout:
    hellofile
Please move or remove them before you switch branches.
Aborting
$ git branch
* feature2
  master

$ git checkout -m master
error: Dirty index: cannot merge (dirty: f2f hellofile)
Switched to branch 'master'
$ cat hellofile 
hello

The problem here is that hellofile is not tracked in feature2 , yet exists in master . 这里的问题是hellofilefeature2未跟踪,但在master存在。 -m is designed for both branches having some change on a tracked file. -m是为两个分支设计的,它们对跟踪的文件进行了一些更改。 Now, this change may or may not be staged, but is tracked in our working tree. 现在,此更改可能会也可能不会进行,但会在我们的工作树中进行跟踪。 Contrarily, I hope it makes sense that if both branches has added and committed some version of the file, we would have standard conflict. 相反,我希望如果两个分支都添加并提交了该文件的某个版本是有意义的,那么我们将发生标准冲突。

If the file is not at least tracked in both branches, then the 3-Way merge seems to resolve the conflict as a git checkout --ours ... more on this in the discussion section. 如果至少不在两个分支中都跟踪该文件,则3-way合并似乎可以通过git checkout --ours解决冲突- git checkout --ours ...更多内容请参见讨论部分。

That is, in doing this in your example, 也就是说,在您的示例中,

$ echo "world" > hellofile
$ git checkout -m master

you are effectively (not actually) saying to disregard changes in the current working directories' un-tracked file. 您实际上(不是实际上)说要忽略当前工作目录的未跟踪文件中的更改。 If however, you had been tracking hellofile on both branches and did your modification, 但是,如果您一直在两个分支上跟踪hellofile并进行了修改,

$ `echo "world" > hellofile"
$ `git add hellofile`

you would have gotten a conflict which looked more like this: 您会发现看起来更像这样的冲突:

<<<<<<< master
hello
=======
world
>>>>>>> local

I am going to assume that is what you were going for; 我要假设这就是你要的。 it was correctly marked as a merge conflict. 它已正确标记为合并冲突。 Yet, your change was brought across both branches without being committed. 但是,您所做的更改未提交到两个分支机构。


Discussion 讨论

The documentation doesn't say this is intended, but that your problem is clearly the behavior. 文档没有说这是故意的,但是您的问题显然是行为。 I think this is probably an oversight/bug on their part. 我认为这可能是他们的疏忽/错误。 What they seem to mean, is 他们似乎的意思是

"However, with this option, a three-way merge between the current branch, your indexed files , and the new branch is done, and you will be on the new branch." “但是,使用此选项,将完成当前分支, 索引文件和新分支之间的三向合并,并且您将位于新分支上。”

After reading this post: Can I use git diff on untracked files? 看完这篇文章后: 我可以在未跟踪的文件上使用git diff吗? , I am going to assume that what is actually happening in the merge scheme is that the working directory file doesn't actually have a valid blob in the index to be considered something to merge, and so is for all intents and purposes, "disregarded". ,我将假设合并方案中实际发生的事情是工作目录文件实际上在索引中没有有效的Blob,因此无法将其视为要合并的东西,因此无论出于何种目的和目的,“ ”。

Edit: Here is a question that was just asked, with a similar sort of conundrum: Why does git checkout <<file>> not work when the same file is in index? 编辑:这是一个刚刚提出的问题,具有类似的难题: 为什么当同一文件在索引中时git checkout << file >>不起作用?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM