8

I tried following commands on the shell

git init

echo "test1" > test1.txt
git add test1.txt
git commit -a -m "test1"

echo "test2" >> test1.txt

git branch test
git checkout test

text.txt now contains:

test1
test2

After checkout to branch test all local modifications from master get merged.

Why?

I expected that git refuses checkout to test because of the local changes. I expected that git asks for a commit or stash the local changes.

Edit: I used a bash script to execute this commands. I get following output:

r@r:/tmp/test$ ./createrepo 
Initialized empty Git repository in /tmp/test/.git/
[master (root-commit) 0407f5b] test1
 1 file changed, 1 insertion(+)
 create mode 100644 test1.txt
M       test1.txt
Switched to branch 'test'
Zoe
  • 27,060
  • 21
  • 118
  • 148
Razer
  • 7,843
  • 16
  • 55
  • 103
  • I have the same issue, the odd thing is, for some repositories, I cannot checkout without committing, others merge. I've looked in the config and can't see any difference. – joedborg Feb 04 '14 at 18:36

3 Answers3

18

git tries hard to not lose possibly valuable data. In this case, it's not actually merging branches, as the changes in question have not been committed. Rather, when you do a git checkout, it attempts to preserve newly made but not committed yet modifications, so it checks out the commit you are requesting, and adds your uncommitted changes. If you really want to discard the uncommitted changes, use git checkout -f, or git checkout followed by git reset --hard HEAD. Sometimes, if the changes you have not committed yet can't be merged into what you're checking out cleanly, you'll get an error message and the checkout will fail.

twalberg
  • 59,951
  • 11
  • 89
  • 84
  • 3
    I don't want to discard anything. But I don't wan't that uncommited changes get merged automatically. If I commit something in `test`, then make some uncommited changes and try to switch again, git says that it can't because there actually are uncommited changes. But why does git don't do this if there are no commits in this new branch? Because the `master` branch and `test` have the same `HEAD`? – Razer Oct 10 '12 at 17:24
  • If you have committed something in `test`, then there are commits on this new branch, so I guess I'm not following your question... If, following the above example, you committed the `test2` change on your `test` branch, then made more modifications to `test.txt` and tried to switch back to `master` without committing first, it's quite likely the uncommitted changes can't be copied cleanly, so `checkout` will fail until you discard the changes or use `git stash`. – twalberg Oct 10 '12 at 17:45
  • 1
    The confusion here is in the fact that OP thinks that having the test2 line in the file when he checks out to test branch means they are merged. This is not correct: Those changes are not merged into the test branch, but rather preserved in the working directory. try to do git diff and git status in both branches and you will see what I'm talking about. – Eugene Sajine Oct 10 '12 at 19:58
  • @EugeneSajine Correct, but also it seems the OP assumes that changes made in the working directory somehow belong to a particular branch before they are committed, which is also false. So in reality, there's nothing to merge (in `git`s usage of the term) to begin with. As you state, local uncommitted modifications are simply preserved by `git` unless you tell it not to. – twalberg Oct 10 '12 at 20:05
  • Now I understand :) I was confused that git outputs `M test1.txt` while checkout the new branch. For this reason I thought git makes a merge - but this isn't so. Git only takes the local changes to the new branch - which are are also local changes here. – Razer Oct 11 '12 at 05:03
  • @Razer Ah - I guess I can understand that. However, for future reference, that `M` stands for `M`odified, not `M`erged... – twalberg Oct 11 '12 at 11:26
0

Have you used any option with git checkout command? I ask because the behaviour you are describing seems like when "git checkout -f" is used.

Lucia Pasarin
  • 2,268
  • 1
  • 21
  • 37
0

git checkout replaces locally changed files.

git merge merges local & incoming changes, alerting to any conflicts.

Neither if these commands will remove local files that do not exist in the incoming commit.

Only git reset --hard will completely wipe out local changes.

Mars
  • 1,530
  • 10
  • 15
  • I know that. But why does `git checkout` merges local changes from the `master` branch into the `test` branch although I didn't commit anything? – Razer Oct 10 '12 at 16:13
  • What do you mean "merges local changes from master"? It is not actually performing a `merge`. – Mars Oct 10 '12 at 21:25