These steps have been followed to generate the scenario:
mkdir testrepo
cd testrepo
git init
touch readme
git add readme
git commit -m "add readme"
git switch -c newbranch
touch 1
git switch -
Now on master
branch I can see 1
.
Moreover whatever changes are done in 1
will be overwritten in another branch when we switch with git switch -
TL;DR
Untracked files are ignored: Git only tracks files that have been committed.
1
has not been committed; if1
was tracked in the other branch, that would cause a conflict.Unstaged changes: unstaged changes to files that are the same in both branches are kept; unstaged changes to files that are different between the branches cause a conflict.
Details
Untracked files
With the scenario you give, nothing unusual is happening.
1
is visible on the file system as an Untracked file before and after the switch, it's not in either branch. It won't get tracked until you commit it.Files tracked in one branch but not the other
Once committed, then Git will mind the differences in that file between different branches.
Extending your scenario, let's commit
1
, then go back tonewbranch
:now
1
is gone, because it's not innewbranch
.And let's create a conflict by touching 1 again:
which generates this error message:
In summary, when you have a file that's not been committed*, if you change it and then switch branch, Git just ignores it and leaves it alone.
*By "not committed", I mean not committed in either the branch you're switching from or the branch you're switching to.
Unstaged changes in files that are identical in both branches
Now, in the title of the question, you also ask about unstaged changes.
Let's create unstaged changes:
Here the switch happens without error and a
git diff
before and after would show the same output. When a file is identical in two branches, unstaged changes to that file are simply kept as is when you switch branch. The file is not modified by that operation, so it's safe.Unstaged changes in files that are different in the two branches
Let's commit that change to
readme
, add more unstaged changes, and see what happens:All was fine until the last command, which gave me this error:
As the message says, we now have an unsafe operation, since Git needs to checkout the version of
readme
in the other branch, and that would destroy our unstaged changes, so it just won't do it.If the changes you want to merge those changes into the other branch, you need to invoke a tool that does merging, like stash:
git stash; git switch; git stash pop
, which would give you a chance to fix any conflicts in the merging process.