A branch is a label and a pointer to a commit. Every commit contains the files from the working tree. (Git employs all possible tricks to not waste space, it never stores copies of identical files, it stores pointers to files. But that doesn't matter — ideologically every commit stores the entire tree of files.)
When you switch branches git switches from the current commit (pointed to by HEAD) to a new commit (pointed to by the branch). Git synchronizes files in the working tree with the files in the new commit. For every file in the old and the new commits there are 4 variants:
The file in the old commit and in the new commit are the same. Git doesn't touch the file.
The file in the old commit and in the new commit are different. Git updates the file from the new commit.
The file in the old commit exists and in the new commit it's absent. Git removes the file.
The file in the old commit doesn't exist but exists in the new commit. Git put the file in the working tree.
There is a good chance there are modified files in the working tree before branch switching.
For the variant 1 above: git switches branches without touching the file so changes in the file remain. For the variant 2 and 3: git complains that it cannot update/remove modified file and aborts the switch.
So if you switch to a different branch and there are no files in the commit that were added to different commit you can:
Merge the other branch into the current. That brings all changes from the branch being merged — new files a re added, updated files updated, removed files removed.
Or you can just bring files from a different commit using the same command git checkout
in file mode:
git checkout <commitish> -- file1 file2…
git add file1 file2…
git commit
<commitish>
here is any pointer to a commit — SHA1 ID of the commit, branch or tag.
PS. git checkout
with its two modes (switch branches and copy files) is considered confusing so in newer releases it's being replaces by two separate commands git switch
and git restore
.