Picture of the situation: you fetch from remote repository and you run a git merge with remote origin having some unstaged files.
How does git merge behave towards unstaged files?
Assuming you have example.md
as an unstaged file in your working directory and try to merge origin/remote1
which already tracks example.md
:
When trying to merge you will get the following error:
error: The following untracked working tree files would be overwritten by merge:
example.md
Please move or remove them before you merge.
Aborting
That happens even if the content of the files is identical.
TLDR: git merge
prevents you from merging if currently untracked files in your working directory could be overwritten by a merge.
git
will only prevent the merge if local changes would be overridden, if the remote did no changes to files you modified locally the merge will finish without any problems.
This is all an aside; AnimiVulpis' answer is fine. This should be a comment, in other words, but it's much too big to fit as a comment. :-)
You need to define a bit more carefully what you mean by "unstaged file".
In Git, there are three important things to keep in your head at all times:
Which commit is the current commit, i.e., what is in HEAD
right now? Usually HEAD
contains the name of a branch, and the branch-name itself contains the hash ID of a commit. Then that hash ID is the current commit.
What is in the index right now? The index, also called the staging area or sometimes the cache, contains what will go into the next commit you make. If you make a new commit right now, whatever is in the index right now becomes the content of that new commit.
What is in the work-tree right now? The work-tree is the easiest thing to see because it contains all your files, in the normal form your computer has them. All you have to do is look, and there they are.
The index is a little hard to see, because Git mostly shows it to you by comparing it to the current commit and to the work-tree. But normally, initially, it contains all the same files as the current commit, in the special Git-oriented format that makes Git fast. Once you git add
a file, though, the index version of that file gets copied from the work-tree version. Now it matches the work-tree file and not the HEAD
file. That's what most documents and people call staging the file: copying it from the work-tree into the index.
Some files that are in your work-tree may not be in your index and/or your current commit at all. In some cases, this is what you want: you want the work-tree to hold the compiled code, or the PDF output from a document, or whatever, but you don't want that code to get committed.
A file that is in your work-tree, but not in your index, is untracked. Since it is untracked, it won't be in the next commit. But git status
will complain about it: "Hey, this file is untracked! Did you forget about this file? Better add this file, right? Huh? Track this file now, right? Pester! Pester! Pester!" To get Git to shut up about this untracked file, you can list it in a .gitignore
file. Then Git knows that the untracked file is not meant to be complained-about. That's most of what .gitignore
does. In particular, if a file is tracked, adding it to .gitignore
has no effect at all. It's only applied to untracked files. Once the file is in the index, you are stuck with it: you have to explicitly remove it to take it away.
Since an untracked file is not in the index, some people call this "unstaged" as well. That's why you have to be careful when talking about "unstaged files": some people consider untracked files "unstaged" too.
In any case, git merge
itself is a bit complicated. Sometimes it actually merges, and sometimes it does what Git calls a fast-forward, which is not really a merge at all. When Git does a fast-forward instead of a merge, many more things are allowed in terms of what's different in HEAD
, index, and work-tree. When Git does a real merge, Git needs to use the index to do it, and fewer special cases are allowed.