68

Git is allowing me to change branches when I have changes not staged for commit (modified files).

Is there a configuration for this somewhere?

Edit: At first I thought this was a configuration that I needed to set to disallow changing between branches if there are modified unstaged files. But by Emily's comment, it appears that you're prompted if the files differ between branches, and not prompted otherwise.

Will Vousden
  • 32,488
  • 9
  • 84
  • 95
Dave
  • 2,735
  • 8
  • 40
  • 44
  • 6
    This is a feature-- so if you make changes and find they belong on a new branch or a different branch than the one you are on, you just change branches and then commit. – antlersoft Dec 15 '11 at 20:42
  • This is a feature, since you might notice that you actually wanted to commit these unstaged changes into a different branch. – jørgensen Dec 15 '11 at 20:43
  • 18
    Additionally, if the files that you've made changes to are different between the branches, it won't let you switch. So there's some protection built in as well. – Emily Dec 15 '11 at 20:45
  • 1
    You're not *prompted*; it flat-out refuses to switch branches if you've modified files which differ between the two branches. It switches if and only if it's safe to do so - that is, you could immediately switch back, and be exactly where you were. – Cascabel Dec 15 '11 at 22:12

2 Answers2

149

How it decides

A quick experiment shows the following.

Suppose you're on branch dev and you've modified foo.txt. Without committing, you try to check out master. One of two things will happen.

  1. If foo.txt was modified in master in a commit that dev doesn't have, you won't be allowed to switch without committing, because master has a "new" version of the file that conflicts with the unstaged changes.

    To "check out" master, therefore, would require Git to update foo.txt to the newer version that master has, destroying your unstaged changes. To prevent your losing work, it won't change branches.

  2. Otherwise, the modification has been done "since" the version master knows about, and you'll be able to change branches. Git doesn't have to update the file because master has no new information about the file.

For the "whoops" changes

Because of the above, if you have unstaged changes in files on one branch and realize you actually want to commit the changes on another, you may or may not be able to check out the other branch.

You can, however, do the following:

  • git stash save "here's a summary of my changes" (summary will show up in git stash list)
  • git checkout otherbranch
  • git stash pop (which is a combination of git stash apply and git stash drop)
Community
  • 1
  • 1
Nathan Long
  • 122,748
  • 97
  • 336
  • 451
  • 32
    I have to say that one of my favorite things about Git is how easy it is to experiment. I would never have set up a Subversion server to test something out, but starting a Git experiment is as easy as `mkdir throwaway; cd throwaway; git init`. A few Git operations later, I've learned something and can remove that directory. – Nathan Long Dec 15 '11 at 21:14
  • This is a great solution _but_ it only appears to work for modified files, not _added_ files. I just lost some :( Admittedly I forced the change of branch, I've complicated things by working with git in Visual Studio, so doing a combination of VS and command line. – Ian May 30 '17 at 23:37
  • 2
    @Ian If `foo.txt` is a new, untracked (never committed) file on your current branch and you `git checkout other_branch`, git doesn't do anything to `foo.txt`; it doesn't have any conflicting version of it on the other branch, and it treats the file as none of its business. Maybe the tools you're using also did a `git clean`? https://git-scm.com/docs/git-clean – Nathan Long Feb 27 '19 at 16:31
11

As Emily pointed out, this is a feature. Git will only disallow the branch change if performing the change would require modifying any of the files that have unstaged changes. If all of the modified files will be untouched by the branch checkout, git will not complain at all. This means that regardless of what branch you check out, you can always check out the previous branch and your working tree will be identical to how you left it.

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347