Thread (27 messages) flat view 27 messages, 10 authors, 2016-06-15

Re: [BUG] git checkout <branch> allowed with uncommitted changes

From: Michael J Gruber <hidden>
Date: 2016-06-15 22:52:15

arQon venit, vidit, dixit 13.10.2011 10:40:
Which, as you'd expect, results in both the on-disk copies and other branches
becoming corrupted.

Tested on git versions 1.7.6 and 1.7.7 (msysgit)

http://benno.id.au/blog/2011/10/01/git-recursive-merge-broken describes
something that sounds similar, but that's supposedly fixed on 1.7.7,
whereas this happens on that as well.

master is a tracking branch, "ttfcon" is the branch I was using to develop
a change. Got to a good point on the branch, merged it in:

$ git co master
$ git merge ttfcon
Updating b9f0c75..6280b7a
Fast-forward
 .gitignore                |    2 ++
 code/renderer/tr_font.cpp |   27 ++++++++-------------------
 2 files changed, 10 insertions(+), 19 deletions(-)

$ git st
# On branch master
# Your branch is ahead of 'origin/master' by 3 commits.

back to the branch to mess around with a couple of things to be sure this
is what i want to push
$ git co ttfcon
do stuff

$ git st
# On branch ttfcon
# 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:   code/freetype-2.3.11/builds/win32/visualc/freetype.vcproj
#       modified:   code/renderer/tr_font.cpp

so far so good...

$ git ci -m "blah" code/freetype-2.3.11/builds/win32/visualc/freetype.vcproj
 1 files changed, 4 insertions(+), 0 deletions(-)

note that tr_font is locally modified and still *not committed* at this point.
and neither staged for commit, exactly.
$ git co master
M       code/renderer/tr_font.cpp
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 3 commits.

boom. instead of rejecting the branch change, git switches branches anyway,
and doesn't do anything about the uncommitted changes in the file itself -
Exactly. git leaves them as they are, without changing what you have in
your work tree.

(This is possible because the switch ttfcon to master involves no
changes which conflict with the chnage that you have in your work tree).
meaning they're now effectively "in" master because they're still on disk,
so now the master is poisoned.
Not at all. They are on "disk" (work tree). Full stop. Not staged, not
committed, not at all "in master".
"git st" does show the change:

# On branch master
# Changes not staged for commit:
#       modified:   code/renderer/tr_font.cpp

but it's a change I never MADE on this branch (ie master), only on the
other branch.
You never made it on the other branch either. You made it in the work
tree. And "git status" clearly says so: modified, not staged.
quoted hunk ↗ jump to hunk
"git diff" is just as confused as I am:

$ git diff ttfcon
--- a/code/renderer/tr_font.cpp
+++ b/code/renderer/tr_font.cpp
+		// git branch bug
"git diff" shows you the change you have in your work tree, i.e. the
difference between index (which coincides with master since nothing is
staged) and work tree. The fact that there is a difference is equivalent
to saying "there are unstaged changes".
So it's picking up the difference between the two branches, but as far as
No. The difference between the branches is the change to freetype.vcproj
because you committed that to ttfcon, not master.
the *actual file* goes, master now has a line in it that shouldn't be there.
It's in the work tree, not master....
I'm just trying out git as a possible replacement for SVN, so maybe I'm
mistaken about what "should" happen, but AIUI git switching branches with
uncommitted changes is a bug (and given that it poisoned a branch that I
wasn't on, it certainly looks like one). A couple of days ago it DID complain
when I tried to switch with uncommitted files still present, so it was working
properly then. I have no idea what's made it happy to ignore them now:
nothing's changed that I know of.
When switching branches, git tries to preserves the changes that you
have in your work tree. If it is possible (because there is no overlap,
as written above), it hapilly does just that. If not it barks.

I think you have to wrap your head around the Git model after unwinding
it from the svn model, which is normal ;)

Cheers,
Michael
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help