What to do is exactly what Git is telling you to do: either commit public/appName/js/password-change.js
, or move it out of the way.
Isn't git reset --hard HEAD
supposed to reset everything that I've done in my branch to the way it was before?
Not exactly. Or rather, exactly that, but just that is not what you want and/or mean.
Git has, at all times, three "active" versions of each tracked file. There's one copy of the file in the current commit, where it is frozen into whatever form it had when whoever made the commit, made it. Here, it's also compressed and stored in a Git-only form, to take less (maybe much less) space. There's a second copy in a place that Git calls, variously, the index, the staging area, or sometimes the cache, depending on who / which part of Git is doing the calling. The index copy is also in the Git-only form, but not quite frozen—more sort of slushy, ready-to-freeze. Finally, the third copy is the one you can use and see: the one in your work-tree, which has its normal form and hence you can work on / with it.
What git reset --hard
does is to re-set all three copies of each of these three files, so that they all match the one in the current (HEAD
) commit. Well, it can do even more, but in this case that's what it does. But that doesn't address something important.
If some files are tracked, that implies that other files are untracked. And that's what Git is complaining about here: an untracked file. So: what exactly does this mean? What exactly is a tracked file anyway?
A tracked file is a file that is, right now, in the index. That's it—it's really that simple. A file that was in the commit you checked out, got into the index from that commit, and is probably still there. So the file that was in the commit, is in the index and work-tree. Using git reset --hard
will re-set the index and work-tree copies.
An untracked file, by contrast, is one that is not in the index. (It has to be in your work-tree, otherwise it's just non-existent all around. If it's in the commit, git reset --hard
will bring it back to both index and work-tree.)
Anyway, if it's not in the index right now, then either you removed it from the index, or it was never there in the first place. The latter tends to be more common, since usually you remove files from the index using git rm file
, which removes it from both the index and the work-tree. And, we can be sure it's not in your HEAD
commit, because if it were, git reset --hard
would have brought it back into your index (and overwritten the work-tree copy with the committed copy).
So you have a file that you—or someone or something—created in the work-tree, that is for sure not in the index, nor in the current commit. And now, by running git pull
, you told Git to run git merge
. (Note that git pull
means run git fetch
, then run a second Git command, usually git merge
. The output you show indicates that you're getting not only git merge
but specifically a fast-forward merge, which isn't really a merge at all, but has a lot of similarities.)
Merge has to take your current work, whatever that is, and merge it with someone else's work, whoever that someone else is. To do that, Git has to find out what they did, and combine it with what you did. While we can't see exactly what they did from what you've posted, what they did includes adding a new file.
The new file they added is the one that you have as untracked. That is, you have:
public/appName/js/password-change.js
which is untracked—not in your index. They committee a version of that file. Git has no frozen copy of your version of this file to keep it safe. Using git merge
would simply overwrite your copy of public/appName/js/password-change.js
with theirs. So git merge
tells you that this file is in the way: you should commit it, so that you have a frozen copy that keeps it safe, or move it out of the way, so that git merge
can write their copy into place.