The files that you see and edit in your working tree (ordinary files) are not actually in Git. They were copied out of Git when you ran git checkout
(or the new git switch
; both of these do the same thing for this particular purpose; git switch
was added in Git 2.23 as a safer way to do checkouts).
When you run git add
and then git commit
, you make a new snapshot, archiving all your files in Git. Each commit holds a full snapshot of every file (well, of every file that it holds, but that sounds kind of redundant, doesn't it?). These files are stored inside Git, in a special, read-only, Git-only, compressed and de-duplicated form, as part of each commit.
The de-duplication takes care of the fact that most commits mostly just re-use existing files from some previous commit. It keeps the repository proper smaller than it would be, if the files weren't de-duplicated. But this also means that it's literally impossible to use the files that are stored in Git. So when you run git checkout
or git switch
, Git will—as you move from one commit to another—remove the old checked out files and replace them with new ones from the new chosen commit.
In order to avoid losing unsaved work, both git checkout
and git switch
do some safety checking first.1 If you have modified some file, but not committed that modification yet, Git will try to take that modified file with you, into the new branch. This is not always possible, but when it is, you see exactly what you saw:
Switched to branch 'master'
M test.txt
This M
is Git's way of saying: Hey, I noticed that you'd modified test.txt
. Rather than just destroying the change you made, I was able to switch branches to master
and leave your modified copy of the file in your working tree. I didn't take the copy out of master
. If this isn't what you meant to do, you should probably switch back to the other branch, add the file, and commit it.
There is actually a great deal more to this—including when and whether Git can switch branches at all—and a more complete story is in my answer to Checkout another branch when there are uncommitted changes on the current branch. That's an answer to a question about why you sometimes can, and sometimes can't, git checkout
another branch without committing your work. It does not address the fact that git checkout
is less safe than git switch
—the question itself, and my answer, predates the new git switch
—and is not about whether any of this is a good idea. It's just about the underlying mechanism.
For now, just remember that the files you see and work on are not in Git. They are in your working tree, for you to see and work on, but as far as Git is concerned, they are just temporary files, for you to play with and for Git to overwrite with git checkout
.
1The safety checking in git checkout
can be disabled, sometimes without you realizing it. This is why git switch
now exists and why it's a good idea to convert to it, but the old git checkout
still works. Since you mentioned it in your question, I'm mostly using git checkout
in examples here. Also, I've been using Git for about 15 years and have bad habits from the bad old days. :-)