Git Pocket Guide says
Git ignores untracked files while switching branches, unless the file exists in the target branch ; 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. The merge operation results in the same file, in this case.
On branch master
, I have a tracked file 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
$ git checkout feature2
$ ls
common reader README writer
$ echo "world" > hellofile
I then try to checkout master
. It is understandable that git checkout
will fail, but with -m
succeed. But why does git checkout -m
succeed without merge? (I am expecting a file hellofile
with marked conflict)
$ 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
. -m
is designed for both branches having some change on a tracked file. 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.
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,
$ `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.
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? , 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".
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?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.