1

Consider these commands:

# create file myfile.txt
git add myfile.txt
git commit myfile.txt               # sha = SHA1
# modify myfile.txt 
git status  # shows myfile.txt modified

git branch branch2
git checkout branch2                # myfile is not replaced
git status                          # shows myfile.txt modified
git add myfile.txt 
git commit myfile.txt

git checkout master                 # myfile is replaced
git status                          # nothing to commit, working directory clean
# myfile.txt is back to original state SHA1

When branch2 is checked out, the working directory copy of myfile.txt is not modified. However when master is checked out, the working directory copy of myfile.txt is modified, it is replaced with that from the repo.

Is this inconsistent behavior? If not, what is the "mental model" to use that explains it?

beginner
  • 43
  • 2
  • https://git-scm.com/docs/git-checkout#git-checkout-emgitcheckoutemltbranchgt: "*`git checkout`* `` - To prepare for working on ``, 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**" – melpomene Nov 26 '17 at 18:14
  • See also https://stackoverflow.com/q/22053757/1256452 – torek Nov 26 '17 at 19:02

1 Answers1

2

The general mental model is that unstaged changes are left alone, and everything else in the working copy is updated when checking out a different commit. Or as the docs put it:

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>.

This is consistent with both cases that you've observed.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • It's worth noting that if an unstaged/modified file has changed between the to two branches you're switching between, the checkout will fail with "local changes would be overwritten" error rather than changing the unstaged file. – Holloway Nov 26 '17 at 20:45
  • This still seems like inconsistent behaviour to me, although consistent. When the new branch is created, its version of a file is identical to the parent, and when the branch is checked out, consistent behaviour would mean writing the committed version of the file (and failing with this "local changes would be overwritten" message). – beginner Jan 02 '18 at 14:31