1

After making a few changes to branch master I decided to work from a new branch. I did git checkout -b new_branch_name and a new branch was created and checked out. git status showed the changes I had made to master.

I was curious if my changes were now on both branches (master and new_branch_name) or just new_branch_name. So I checked out master and noticed my changes were there as well. So I reverted those changes with git checkout -- fileThatChanged. The changes were indeed gone from master.

Unfortunately checking out new_branch_name and running git status showed my changes were reverted from that branch as well.

I'd like to understand what happened and how can I avoid this in the future.

One solution is to just create/checkout a new branch before starting work.

user229044
  • 232,980
  • 40
  • 330
  • 338
SundayMonday
  • 19,147
  • 29
  • 100
  • 154
  • 1
    The thing you need to remember is that branches point to commits, and commits represent snapshots of the whole work tree. A checked-out branch is just the one where the next commit will go. (The work tree is completely separate from commits, and the index is a staging area between the two.) If you'd like a wordy explanation of the core ideas of Git, you could try [The Git Parable](http://tom.preston-werner.com/2009/05/19/the-git-parable.html). – Cascabel Nov 30 '11 at 01:52

4 Answers4

5

You had never committed your changes to either branch. That is, if you did this:

$ git status

And saw something like this:

# On branch master
# 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:   myfile.txt
#

The changes to "myfile.txt" do not "exist" on any branch -- they are only in your local working copy. They don't end up on a branch until you have comitted them to a repository.

If at this point I were to type:

$ git checkout myfile.txt

This would obliterate my changes (and return the file to whatever it looked like in the last commit on my current branch).

If I wanted to commit these changes on a new branch, I might do something like this:

$ git checkout -b new_branch_name
$ git add myfile.txt
$ git commit -m "made some changes"
larsks
  • 277,717
  • 41
  • 399
  • 399
3

The index is shared amongst all branches. As it the local working tree. It represents what will be committed, without assuming in what branch it will be committed.
But that means it you revert a change (ie remove it from the index or from the local workspace), it will be reverted no matter what branch you are in.

See also:

git file transition

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 1
    The index doesn't come into play here. Files end up in the index after a `git add` operation. Changes to files that have been neither added nor committed are not in the index. – larsks Nov 29 '11 at 18:32
  • @larsks: you are right regarding the checkout -F (only the working tree is affected). But I was editing my answer as you were commenting ;) – VonC Nov 29 '11 at 18:34
1

Modified changes in your working directory / index ( what you see in git status ) are not linked to a branch but are common. So when you switch branches, the changes will still be in the new branch. If you undo the changes, that will be seen when you switch branches. You should either commit or stash before changing branch.

manojlds
  • 290,304
  • 63
  • 469
  • 417
1

As larsks says, you did not have these changes committed.

If you are looking to switch branches while remembering your working copy, you must use git stash.

When you are done, you can use git stash pop to restore your in-process working directory.

Nate
  • 12,499
  • 5
  • 45
  • 60