2

GIF demonstrating the sequence of events

enter image description here

I create a branch foo, alter a file, then without committing the change I checkout master. GIT lets me do the checkout and the modification is carried over.

I commit this change.

Switch back to the branch foo, alter a file -- coincidentally in a way that makes it identical to the version in master -- then without committing the change I checkout master. This time I get an error "Error: Your local changes to the following files would be overwritten by checkout: index.html Please commit your changes or stash them before you can switch branches. Aborting"

What is responsible for this inconsistent behavior?

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
Mud
  • 28,277
  • 11
  • 59
  • 92
  • 1
    Answers are a bit off topic and this is duplicate so I won't add any answer, but long story short: `master` and `foo` point to the same commit and your changes in test.txt do not conflict with any other changes when switching between `foo` and `master`, therefore you can switch and keep your changes. – Thibault D. Jun 04 '17 at 07:31
  • @ThibaultD. I don't understand why I can't switch the second time. Case #1: no uncommitted changes in `master`, switch to `foo`, change a file, switch back to `master`. Case #2: no uncommitted changes in `master`, switch to `foo`, change a file, won't let me switch back to `master`. What's different? – Mud Jun 04 '17 at 18:33
  • Because now, `foo` and `master` don't point at the same revision anymore. Furthermore, `master` has a newer commit including a change to the file `test.txt`, which conflicts with your untracked change in `test.txt` _while on_ branch foo. Git will only help you to merge commited changes, so it can't and will not try to solve conflict induced by untracted changes. – Thibault D. Jun 05 '17 at 08:01
  • You should never have uncommitted changes when switching between branches. Consider the fact that you actually can switch between branches as an exception. This exception requires that both branches share a common ancestor and that no uncommitted changes conflict with later changes on the branch you want to checkout. – Thibault D. Jun 05 '17 at 08:04

3 Answers3

3

This is a misunderstanding of what branching does, and how it works.

You check out a branch, make a change to a file related to that branch, but you do not commit that change in that branch. The change you've made is in your uncommitted files space. This means, so long as your file doesn't conflict with another branch, Git will allow you to carry that uncommited change around with you.

If you add the file to the index, you should get a message like this when you switch branches:

M   foo

That means the file foo was modified, and this is your visual cue.

Now that you've switched over back to your other branch, and you edit the same file with the same content, Git cannot keep track of that because you haven't really told it to. You've created, in Git's mind, two completely different revisions to the same file, and it results in a conflict.

My recommendation:

  • Commit the change in your foo branch
  • Merge the change into master

Since you're in this state...

  • Rebase master onto foo to ensure their histories line up
Makoto
  • 104,088
  • 27
  • 192
  • 230
  • "You check out a branch, make a change to a file related to that branch, but you do not commit that change in that branch." That's *exactly* what I did the first time, when it let me. It's entirely non-obvious what's different between the first execution of the steps (checkout Foo, edit file, don't commit, checkout master) and the second *identical* execution of the exact same steps. I know how to avoid it, sure. But I don't know why it happens, which means I don't understand GIT, which seems to be par for the course with this tool. – Mud Jun 03 '17 at 21:33
0

As because master got your first commit, moving another active change from foo to master will be prevented as a fail safe condition. If you commit your second change in foo that won't be an issue though.

However, as a better way, I suggest you to rebase foo over master to make it same instead of trying to make the same modification.

hurturk
  • 5,214
  • 24
  • 41
  • "moving an active change to master will be prevented as a fail safe condition" But that's what *didn't* happen. I was in a separate branch (foo), I made a change, then checked out master. I got no warning of any kind, the change was lost in foo, and the change showed up in master (uncommitted). The second time I did *the exact same thing*: switch to separate branch (foo), make a change, then checkout master. This time I get a warning. The steps were identical in each case. – Mud Jun 03 '17 at 19:09
  • Even you make a change in `foo`, your changes are movable until you commit. So you technically made change on the `master` branch. It didn't conflict first, because your change relied over the exact same content. However, second time, you started with different files in git's perspective. – hurturk Jun 03 '17 at 19:12
0

This is not inconsistent behaviour. This is very expected from the GIT, it just complains that file it tries to merge test.txt file to the master it fails to do.

It clearly complaints please commit your changes while switiching to another branch.

It's recommended to commit the changes in our local branch. When you switch branch from, if you are able to keep track of the changes of few files it's ok, what if 20 files? in that case, its better to commit the changes and switch to another branch.

When you switch to another branch, uncommitted changed files, not the new files. only the files you changed in a branch merge to another branch.

Here you merge the text.txt file in master branch and you committed there. Later you went to branch Foo and edited the file and you didn't commit the file in your local branch and you switched the branch and it didn't let you do. Because of the change what you did not able to track.


The suggestion is to commit the changes to your local branch.

git checkout -b foo
echo random > test.txt
git add test.txt
git commit -m "random commit"
git rebase master
git checkout master
git merge foo

you're done.

danglingpointer
  • 4,708
  • 3
  • 24
  • 42
  • 1
    "you went to branch Foo and edited the file and you didn't commit the file in your local branch and you switched the branch and it didn't let you do" That's what I did the first time, too, *exactly*: I went to branch foo, I edited the file, I didn't commit the file, and I switched branches. It let me do it. The second time I repeated these same steps with the same file, it didn't let me do it. That's inconsistent. Apparently, according to Makato's response, that's because of some implement detail of how GIT detects that a /test.txt is the same file from one branch to another. – Mud Jun 03 '17 at 21:29