On Tue, 13 Sep 2016 07:26:02 -0700 (PDT)
Pierre Dutronc <pierre.pas...@gmail.com> wrote:

> I found it very useful to be able to create a new test branch, alter a
> few lines of code and see how it worked out. If it worked well, I
> would switch back to master and merge the test branch into master.
> - I left master, created a new branch, and checked out that branch. 
> - I altered a few lines of code and saved the file.
> I did not even commit.

^^^ This.
You fell victim with a very common misconception about how Git branches

Before we begin, I'll tell you that nothing at all changed when you
swiched OSes and Git versions: just on Windows you always happened to
commit your changes before switching branches.

OK, back to the topic.

When you check out a branch in Git, there are three trees:
* The tip commit of the branch you have checked out.
* The index / the staging area.
* The work tree.
The latter is the directory where your actual files are located on the
filesystem, and where you edit them, and from where you `git add` these

The crucial bit of the Git's model you're missing is that the work tree,
while _being based_ on the tip commit of a branch, _do not belong_ to
that branch.

At any time, you might decide to `git checkout` another branch while
having uncommitted changes.  Let's cite the manual:

| git checkout <branch>
|         To prepare for working on <branch>, switch to it by updating
| the index and the files in the working tree, and by pointing HEAD at
| the branch. Local modifications to the files in the working tree are
| kept, so that they can be committed to the <branch>.

See the last bit there?

There's even a special command-line option, "-m" (or "--merge") which
enables you to do even smarted things:

| -m, --merge
|         When switching branches, if you have local modifications to
| one or more files that are different between the current branch and
| the branch to which you are switching, the command refuses to switch
| branches in order to preserve your modifications in context. However,
| with this option, a three-way merge between the current branch, your
| working tree contents, and the new branch is done, and you will be on
| the new branch.

To recap, the work tree is based on the branch being checked out but is
not inherently tied to it.  You can switch branches at will while
having uncommitted changes.  These changes only start to belong to a
branch when you commit them.  That is, the only sort of thing which can
be said to be "on a branch" is commit.

As to what you can do about this, there are two approaches:

* The stash.  You can run `git stash` (or `git stash save`) before
  switching and have your uncommitted changes properly saved in a
  special stack-like area from which you can later apply them back.

  It worth mentioning that the entries in a stash do not belong to any
  branch, too, and are truly local to your repository (you can't push

  Any stash entry can be applied to any state of the work tree -- that
  is, you can stash while being on a branch, switch to another branch
  and apply the stashed entry there.

* Do a temporary commit on the current branch.

  No, really.  To newcomers this may look somewhat counter-intuitive
  but it's not: until you pushed something to a public repository, the
  history is truly yours and you're free to do whatever you want with
  it including refining or just deleting outright.

  In cases like this, you can just `git commit` all your changes
  write an explanatory message (typically starting with the prefix
  "WIP: " denoting "work in progress") and switch to another branch.

  When you swich back, you call `git reset HEAD~` meaning "chop the tip
  commit of the current branch off but leave its changes in the work
  tree" and hence continue from where you left off.
  The full form of this command is

    git reset --mixed HEAD~1

  with "--mixed" being implied if not specified and HEAD~1 meaning
  "the first parent of the commit at HEAD".

> - I did not like how it turned out so I switched back to master and
> to my surprise the new lines of code were present in the file I had
> edited while being in the other branch. Master had been polluted by
> the other branch.
> I certainly expected my edit not to be in the file once I had
> switched back to master.

This was certainly wrong due to incorrect model you had in your head
about how Git branches work.  Hope now you maintain a correct one ;-)

To make yourself more accustomed with the concepts, I invite you to
read [1, 2, 3].

1. The relevant bits of git-checkout and git-reset manual pages.
2. https://git-scm.com/blog/2011/07/11/reset.html
3. The gitrevisions manual page.

You received this message because you are subscribed to the Google Groups "Git 
for human beings" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to git-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to