When you fetch from a remote repo, the state of the branches in that repo has to be recorded somewhere locally in your repo. That’s what remote tracking branches are. So if the remote called origin has a branch called master, and you fetch, git downloads the commits you don’t have and then updates .git/refs/remotes/origin/master to the commit ID of whatever master is on origin.
That’s all it is.
Basically you have a DAG just like you think. But git needs some way to label some of the nodes in that DAG. It calls those labels “references” or refs, it records them under .git/refs/, and there’s basically just three kinds: local branches (refs/heads/<branch_name>), tags (refs/tags/<tag_name>) and remote tracking branches (refs/remotes/<remote_name>/<branch_name>). There’s also the reflog which is a change log of the local branch refs, and a special log for HEAD which keeps track as you switch which branch is currently checked out.
Note: if you start poking around under .git (and you should in a toy repo!), you might not find exactly these files. For performance reasons, git sometimes combines the refs into a single file called packed-refs.
That’s all it is.
Basically you have a DAG just like you think. But git needs some way to label some of the nodes in that DAG. It calls those labels “references” or refs, it records them under .git/refs/, and there’s basically just three kinds: local branches (refs/heads/<branch_name>), tags (refs/tags/<tag_name>) and remote tracking branches (refs/remotes/<remote_name>/<branch_name>). There’s also the reflog which is a change log of the local branch refs, and a special log for HEAD which keeps track as you switch which branch is currently checked out.
Note: if you start poking around under .git (and you should in a toy repo!), you might not find exactly these files. For performance reasons, git sometimes combines the refs into a single file called packed-refs.