Reputation: 772
I am just learning Git, going through a tutorial. I am in branch seo_title and I have uncommitted changes to file mission.html. I did git checkout master
expecting to get the warning about Changes not staged for commit, no changes added, etc, however instead it went ahead and switched branches with the message:
M mission.html
Switched to branch 'master'
Then when I did git diff mission.html
it showed me that the working directory still contains the changes I made while I had the other branch checked out.
What am I missing?
For what it's worth, I am using Git Bash on Windows.
EDIT: the changes to mission.html have not been added to staging index either.
EDIT 2: I thought the top voted answer was correct, but upon further investigation it doesn't match the behavior I am seeing. Here is a fuller description of what I am doing:
top_directory(master) > git branch new_branch_1
top_directory(master) > git branch new_branch_2
top_directory(master) > git checkout new_branch_1
(open notepad++ and modify resources.html, save)
top_directory(master) > git status
# On branch new_branch_1
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed
# (use "git checkout -- <file>..." to discard changes in wo
#
# modified: resources.html
#
no changes added to commit (use "git add" and/or "git commit
top_directory(new_branch_1) > git checkout new_branch_2
This is where I expect git to object and tell me to stash or commit since new_branch_1 and new_branch_2 have different versions of resources.html, but it just switches to the new branch without a warning and it brings the uncommitted changes along:
M resources.html
Switched to branch 'new_branch_2'
top_directory(new_branch_2) > git status
# On branch new_branch_2
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: resources.html
#
no changes added to commit (use "git add" and/or "git commit -a")
Is there a mode or a setting that would make it behave this way instead of warning? Or am I still misunderstanding the scenario?
EDIT 3: I get it now. The top rated answer was right, see my last comment on that answer.
Upvotes: 27
Views: 26971
Reputation: 41
this is obvious, if you change a file which is not changed in the branch you want to checkout into, because the syntactic of checkout is to bring all the index and working directory to your new branch, you will have them appeared in your new branch. While if there r conflicts, chances r u need to merge those files, which means once after merge, if you checkout back to your old branch then it is already the merged version not your previous one, you lose it. As a result, to make sure you keep the old change it won't let you do that.
Upvotes: 0
Reputation: 539
The different behaviour you saw from the last time you tried to switch branches with local changes and now is due to different file changes.
So, let's say we have a branch called 'readme' where you have committed some changes to a file, let's say README.md.
Now, you have switched back to master. You do some work on other files (not README.md). Now you have local changes. If you try to switch back to the 'readme' branch without committing your changes, it will let you. Why? Because switching to the 'readme' branch won't override any of your local changes.
If, however you make a modification to the README.md file on the master branch, then when you try to do a
git checkout readme
you will encounter
error: Your local changes to the following files would be overwritten by checkout: README.md
Please, commit your changes or stash them before you can switch branches.
because you have changes to README.md that would require a merge.
Upvotes: 36
Reputation: 70145
This is the normal behavior. If you don't want the modified files on your newly checked out branch, then stash them. Like this.
# on branch dev
$ git stash
$ git checkout master
# do stuff on master
# back to dev
$ git checkout dev
$ git stash pop
Upvotes: 16
Reputation: 28951
Git - the stupid content tracker. It just operates with working tree snapshots. The main requirement - you should be able to reconstruct working tree. It does update of course. But if the modified file is the same in both branches - why not to allow switch? If you done it by mistake, you could switch back reconstructing previous state, no big deal. But if the file is differ in the branches, you need merge content, that's why it insists to commit changes, otherwise it will be impossible to go back.
Upvotes: 0
Reputation: 49473
Git will let you checkout other branches (or tags or SHA1 hashes) as long as the commit you're changing your work-tree to does NOT clobber your local uncommitted changes.
In your case the branch master
's work-tree would have had the same version of missing.html
as that currently exists in the tip of your current branch you were switching from. Git does not need to touch the working copy (for missing.html
at least) when changing branches here, and hence lets you keep your local modifications.
If you indeed tried to checkout
a commit where there was a different version of missing.html
in the work-tree (than the one committed in your current branch), git would show an error message similar to this:
$ git checkout some-other-branch
error: Your local changes to the following files would be overwritten by checkout:
missing.html
Please, commit your changes or stash them before you can switch branches.
Aborting
Upvotes: 2