Weird behavior of git switch/checkout if index has same content as target commit

43 Views Asked by At

Let's create a small local repository:

git init
echo foo > foo
git add foo
git commit -m foo
git branch bar
echo foo >> foo
git commit -a -m 'another foo'

If we do this now, we replace our file foo in our index as well as in our working copy with the one from the branch bar:

git restore --source bar --staged --worktree foo

and now we switch to bar:

git switch bar

Expectation

git should refuse the switch due to a dirty repository

Actual behavior

git does the switch and acts like nothing ever happened:

git status
On branch bar
nothing to commit, working tree clean

Even weirder, if we instead just restore to the index:

git restore --source bar --staged foo

and switch then:

git switch bar

It will again just do it, but this time with uncommitted changes to foo?

git status
On branch bar
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   foo

Questions

  • Why does git perform the switch?
  • Why doesn't it refuse to switch because of a dirty repository?
  • What is happening behind the scenes?
  • Where is this behavior documented?

FYI, the same happens with git checkout.


All I could find in the documentation is this sentence:

The operation is aborted however if the operation leads to loss of local changes, [...]

But that doesn't really explain it, since if I do this instead of the restore above:

echo foo >> foo
git add foo
git switch bar
error: Your local changes to the following files would be overwritten by checkout:
        foo
Please commit your changes or stash them before you switch branches.
Aborting

git won't do the switch because of a dirty repository (as expected), even though it theoretically could without losing local changes by only updating the index and not the working directory, as it seemingly does when the index already has the desired content for the switch.

Why is there an exception when the index has the same content as the target branch?

0

There are 0 best solutions below