The O’Reilly Git Pocket Guide

I’m Richard Silverman, co-author of the O’Reilly books SSH: The Secure Shell (The Definitive Guide) and The Linux Security Cookbook. My latest book, the “Git Pocket Guide,” was published on 11 July 2013.

If you find an error in the book, please check it against O’Reilly’s online errata system, and submit it there if it’s not already listed. If you have a question, feel free to email me at res@qoxp.net. On this web site, I plan to add various bits of information related to the book, including stuff which may be incorporated in later editions.


the relationship between origin and clone repositories

“Push and Pull” (p26) and “Tracking Other Repositories” (chapter 6) discuss the relationship between a repository and one cloned from it, and synchronizing them using git push and git pull. Here is a diagram that may help grasp the idea:

clone diagram (small)

(other diagram formats: SVG, PDF)

The remote name “origin” in the clone is linked to the original repository via the clone’s configuration in .git/config, which refers to the URL of the original. git fetch (which happens during a pull) maintains an image of the local branch namespace of the original (refs/heads/*) in the origin remote namespace of the clone (refs/remotes/origin/*); thus the master and topic branches of the origin are available as “remote-tracking branches” origin/master and origin/topic in the clone. The clone has its own, local versions of those branches in its own refs/heads/ namespace, shown in green; these are created when you check out a remote branch in the clone.

When git fetch in the clone updates the tracking branches to match the current state of the remote, it pulls over any objects required to complete the new history; that is, all commits needed to connect the new positions of the branch heads to their old positions, filling in the graph as the remote branches progress. Thus, the commit graph of the origin is a subset of the graph of the clone, at least with respect to the branches being tracked. The diagram reflects this: the entire origin commit graph, shown in black, appears unaltered as a subgraph in that of the clone (but the branch names are now prefixed with origin/).

In between its last two fetches, this clone has added to its local versions of both remote branches. Nothing happened to the “upstream” master (the one in the origin) during that time, so git push can do a “fast-forward” update of the remote branch, simply moving it up to match the local one (after sending the requisite commits to the origin’s object database, of course). But while the clone has added two commits to its version of the topic branch, the origin has also added to its version (four commits on its side). Thus, this branch requires either a merge or a rebase before it can be pushed. git branch -vv in the clone gives a succint summary of the situation:

$ git branch -vv
* master a675f734 [origin/master: ahead 3] "Forever Knight"
  topic  9b0e3dc5 [origin/topic: ahead 2, behind 4] ... is awesome!