Subject: Re: Git branches - confusing behavior

From: Jakub Narebski <[email-masked]>
Date: Sun, 11 May 2008 15:40:04 +0200

Dima Kagan wrote:
> Jakub Narebski wrote:
>> Dima Kagan <[email-masked]> writes:

[...]
> So if I am working on more than one branch at a time I need to commit
> my changes every time before I do 'git checkout <branch>'?
[...]
Not necessary, see below (and it is not necessary bad).

>>> Basically I see that the same file I edited on the 'test_branch'
>>> branch appears to be modified on the 'master' branch as well. This
>>> behavior is unwanted, of course.
>>>
>>> Can someone please tell me, what am doing wrong? Or is this git's
>>> normal behavior?
>> 
>> This is normal, and wanted, behavior.
 
> That's a subjective point of view :) I'm coming from the SVN world and
> uncommitted changes on one branch don't affect other branches. Is
> there a way I can achieve this behavior with git?  

How would you want git to behave, with "git checkout <branch>" changing 
branches _in place_, in single working area?  Besides, current 
behavior, together with "git checkout -m" option, allows to change 
branches when you have realized (after making some changes) that you 
are on wrong branch...

There are few possible solutions:

1. Save state before switching branches

1.1. You can simply commit changes before switching branch, perhaps with
"(WIP)" (work in progress) in the commit message.  Then, when you go 
back to the branch, you can continue your work, and simply --amend (as 
in "git commit --amend" a commit.

1.2. You can use git-stash to save state of your working area (working 
directory) _and_ index, change branches, and when going back to branch 
restore state using "git stash apply". I think you can save state even 
during not resolved merge.

1.3. If you use patch management interface on top of Git, like StGit
(or Guilt), you can simply "stg refresh" a patch, then change branches.  
When returning to branch, use refresh and/or edit, then create new 
patch if you think current is finished (you can always go back...).

2. Use separate working for differen branches: this is what Bazaar does, 
what Mercurial does by default without 'localbranch' extension, and I 
think also what Subversion does.   Take a look at contrib/workdir
on how to manage multiple working areas with single repository; the 
core.workdir and --working-dir could also be of help.

Note that in this case you have to take care to not have the same branch 
checked out to two (or more) different working areas, to not stomp on 
your changes, and to avoid confusion.

Final note: you would work better learning SCM "the git way", and not to 
rely on Subversion bad habits (yes, I know that bad CVS habits are 
worse...) ;-)

-- 
Jakub Narebski
Poland