You're starting from a bad assumption: git fetch
does not merely get metadata, it gets commits. The commits contain both data—snapshots of files—and metadata: information about who made the commit, when, and so on. Having obtained any new commits required, your git fetch
then goes on to update your remote-tracking names, which are the origin/*
names. Their full names are refs/remotes/origin/name
, where each name
corresponds to a branch name as seen in the other Git, over at origin
.
When you run git checkout remotes/origin/branch
, your Git puts you in detached HEAD mode with that one specific commit checked out. So this step updated the files you can see in your working tree. The git checkout -b name
step created a new name that identifies this same commit—the same commit that refs/remotes/origin/branch
identifies—and no files need updating.
It's the commits that matter. The names, whether they are remote-tracking names like origin/somebranch
or (local) branch names like somebranch
, merely help you (and Git) find the commits. The commits contain the files, and are the history. The git fetch
step obtains, from some other Git repository, any new commits that they have, that you don't, that you need; from then on, everything you do here is local.