Re: Git: Unexpected behaviour?

3 messages, 3 authors, 2016-06-15 · open the first message on its own page

Re: Git: Unexpected behaviour?

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:52:28

"J.V." [off-list ref] writes:
OK so "work tree" is a new term for me.  I thought we were in isolated
sandboxes called "branches" and changes made in a branch would stay in
that branch regardless.
Do not think of "branches" as isolated _sandboxes_.

Rather, "branches" are where the independent states are to be _recorded_.

The recorded states only exist in the git repository, and to use its
contents (e.g. view in the pager or browser, edit in the editor, run the
compiler on,...), you need to materialize the contents of the branch
somewhere on the filesystem. Such a set of files on the filesystem form
the working tree. The act of doing so is called "checking out a branch".

After you check out a branch, your working tree can be used to record an
updated state to the branch, but notice the "can be" part. Changes you
make to the working tree are _not_ associated to the branch until you make
them so by committing. They are floating on top of the branch you have
currently checked out in your working tree, and "floating" was the key
part lacking in your understanding that started this thread. You are
allowed to check out another branch while you have a local change in the
working tree, and this is deliberately so. People often start working on a
branch (that is, they want to make a change and check out a branch, or
they happen to have a check-out of a branch and then the find something
they want to change), and then realize that the change logically does not
belong to the currently checked-out branch but some other branch. They
need to be able to check out another branch without losing the change they
already made in their working tree, and for such usage, the workflow
should look like:

    $ git checkout master ;# on master branch
    $ edit hello.c ;# some feature being added
    ... realize that this change does not belong to the master
    ... branch but is part of the "hello" branch you have been
    ... working on for the past few days
    $ git checkout hello ;# check out the correct branch
    ... this keeps the local modification in hello.c (as long as
    ... the file you modified are the same between master and hello
    ... branches). Keep working on it and then finally...
    $ git commit ;# on hello branch.

There is another unrelated use case in which people have local changes in
their working tree, but need to check out a different branch. The most
common is while you are working on a large feature that is not finished
yet on your "feature" branch, you hear from your boss that one trivial fix
for an urgent bug must be committed and pushed out on the "master" branch.
The feature you have in your working tree does not have anything to do
with the bug or the fix you are going to make for your boss. In such a
case, you would want to save away the changes for the feature, check out
the "master" branch and commit the fix, i.e.

    $ git checkout feature ;# on feature
    $ edit foo bar baz ;# some complicated change
    ... boss comes

    $ git stash ;# stash away the current change
    or
    $ git commit -a -m 'wip'

    $ git checkout master ;# emergency
    $ edit ... ;# quickfix
    $ git commit -m 'urgent fix...'
    ... emergency dealt with

    $ git checkout feature
    ... back to what was being worked on

    $ git stash pop
    or
    $ git reset HEAD^

Re: Git: Unexpected behaviour?

From: Martin von Zweigbergk <hidden>
Date: 2016-06-15 22:52:28

On Sat, Nov 12, 2011 at 11:37 AM, Junio C Hamano [off-list ref] wrote:
"J.V." [off-list ref] writes:
quoted
OK so "work tree" is a new term for me.  I thought we were in isolated
sandboxes called "branches" and changes made in a branch would stay in
that branch regardless.
Do not think of "branches" as isolated _sandboxes_.

Rather, "branches" are where the independent states are to be _recorded_.
I think I was confused about this when learning Git too. I friend of
mine made the following argument, which I agree with and which I haven
seen on the list before:

Either you want the modifications to stay on the branch, or you want
them to carry over to the branch you are checking out. In the former
case, you would want Git to fail if there are modifications (that you
might have forgotten you made). In the latter case, you would want
"git checkout -m". The current behavior is somewhere in between. It is
not clear to me if there is a use case where the current behavior is
better (from the user's point of view) than either failing or
"checkout -m".

It is obviously too late to change this now, though.

Martin

Re: Git: Unexpected behaviour?

From: Jakub Narebski <hidden>
Date: 2016-06-15 22:52:28

Martin von Zweigbergk [off-list ref] writes:
On Sat, Nov 12, 2011 at 11:37 AM, Junio C Hamano [off-list ref] wrote:
quoted
"J.V." [off-list ref] writes:
quoted
OK so "work tree" is a new term for me.  I thought we were in isolated
sandboxes called "branches" and changes made in a branch would stay in
that branch regardless.
That would be the default and only solution if each branch was checked
out to a separate working directory.

You can do that in git using git-new-worktree script from contrib.
quoted
Do not think of "branches" as isolated _sandboxes_.

Rather, "branches" are where the independent states are to be _recorded_.
Branches are lines of development, and are about _comitted_ changes.
This means that when switching branches "in place", un-committed
changes are not on any branch.
I think I was confused about this when learning Git too. I friend of
mine made the following argument, which I agree with and which I haven
seen on the list before:

Either you want the modifications to stay on the branch, or you want
them to carry over to the branch you are checking out. In the former
case, you would want Git to fail if there are modifications (that you
might have forgotten you made). In the latter case, you would want
"git checkout -m". The current behavior is somewhere in between. It is
not clear to me if there is a use case where the current behavior is
better (from the user's point of view) than either failing or
"checkout -m".
The "checkout -m" behavior is unsafe; you can land in a state where it
would be difficult to revert, and could lose your changes.  The
default behavior of switching branches is to carry over changes if it
is safe to do so.
 
It is obviously too late to change this now, though.
Well, we could in theory add knob that would stash changes when
switching to branch, and unstash when switching to branch.

-- 
Jakub Narębski
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help