git concepts simplified

Sitaram Chamarty ([email protected])

1 preface

1.1 about this slideshow

If you’re viewing this on “gitolite.com”, please be aware that’s only an artifact of some very lazy DNS and hosting decisions I made. Just think of it as “sitaramc.github.com” instead, because these pages really have nothing to do with gitolite per se. They’re about git in general.

1.2 license

  1. Copyright Sitaram Chamarty, [email protected]. This documentation is provided under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

1.3 viewing This slideshow

This presentation uses HTML Slidy, a simple presentation software from the W3C. Although there’s a help button in the footer of each presentation, it’s missing some important stuff, so here’s a smaller but more complete summary of the keyboard controls.

<Navigation>

  Next slide: right arrow, page down, space
  Prev slide: left arrow, page up
  Down within slide: down arrow
  Up within slide: up arrow
  First slide: home
  Last slide: end

<Display>

  Smaller font: “S” or “<” key
  Larger font: “B” or “>” key
  Toggle Current versus All slides: “A” key
  Toggle Table of Contents popup: “C” key
  Toggle footer: “F” key

<To search> for stuff in the full document using your browser’s Ctrl-F, first view all slides (press the “A” key).

1.4 acknowledgements

this document

This document is vaguely inspired by https://eagain.net/articles/git-for-computer-scientists, except this page is not just for CS folks. And it’s a lot more detailed. Oh, and it’s actively maintained, meaning I will respond to feedback ;-)

this slide show

This slide show was all done with pandoc’s slidy output mode, and a few little pre-processing tweaks. Pandoc is absolutely fantastic and bloody powerful! I wish I’d discovered it sooner but now (Dec 2013) that I have, it’s eliminating a lot of my home-grown scripts to do various things like this!

The bulk of my tweaks are in terms of embedding graphviz diagrams inside the main document, so there’s only one file to maintain!

2 basics

2.1 what is a SHA

A commit is uniquely identified by a 160-bit hex value (the ‘SHA’). This is computed from the following pieces of information:

In the end, as I said, it’s just a large, apparently random looking, number, which is actually a cryptographically-strong checksum. It’s usually written out as 40 hex digits.

Humans are not expected to remember this number. For the purposes of this discussion, think of it as something similar to a memory address returned by malloc().

It is also GLOBALLY unique! No commit in any repo anywhere in the world will have the same SHA. (It’s not a mathematical impossibility, but just so extremely improbable that we take it as fact. If you didn’t understand that, just take it on faith).

An example SHA: a30236028b7ddd65f01321af42f904479eaff549

2.2 what is a “ref”

A ref is just a name for a SHA. Branches or tags (described later) are refs.

There are also some special refs (the most common being HEAD), that are usually symbolic refs (i.e., they usually point to a ref instead of directly pointing to a SHA).

Anyway, for now just think of them as a human-readable name you gave to a SHA.

2.3 what is a repo

A repository (‘repo’) is a graph of commits. In our figures, we represent SHAs with numbers for convenience. We also represent time going upward (bottom to top).

a simple chain of commits

(Hey, why are the arrows backward in your pictures?)

So why are the arrows pointing backward?

Well… every commit knows what its parent commit is (as described in the “what is a SHA” section above). But it can’t know what it’s child commits are – they haven’t been made yet!

Therefore a repo is like a single linked list. It cannot be a double linked list – this is because any change to the contents would change the SHA!

3 branches and tags

3.1 branch

Traditionally, the top of a linked list has a name. That name is a BRANCH name. We show branch names in green circles.

a branch

3.2 more than one branch

(a.k.a “more than one child commit”)

Remember we said a repo is a GRAPH? Specifically, more than one child node may be pointing at the same parent node. In this case, each ‘leaf node’ is a branch, and will have a name.

three branches

3.3 more than one parent commit

Well we can’t keep creating more branches without eventually merging them back. So let’s say “feature X” is now tested enough to be merged into the main branch, so you git merge feature_X. Here’s what you get:

Notice that commit 8 now has 2 parents, showing that it is a “merge commit”.

a merge commit

At this point, it’s quite common to delete the feature branch, especially if you anticipate no more “large” changes. So you can run git branch -d feature_X, which gives you this:

a deleted feature branch

3.4 current branch/checked out branch

There is a notion of a ‘currently checked out’ branch. This is denoted by a special ref called HEAD. HEAD is a symbolic ref, which points to the ‘current branch’.

HEAD

3.5 committing

When you make a new commit, the current branch moves. Technically, whatever branch HEAD is pointing to will move.

committing

3.6 naming non-leaf nodes

It’s not just ‘leaf’ nodes, but inner nodes can also have names. Recall the result of merging feature_X earlier (see the “more than one parent commit” section):

non-leaf

At this point, you could leave feature_X as it is forever. Or you could delete the branch (as we showed in that section), in which case that label would simply disappear. (The commit it points to (“4”) is safely reachable from master because of the merge. That is, it is not “lost”, since there is a sequence of commits from master which lead to it.)

You can also continue to develop on the feature_X branch, further refining it with a view to once again merging it at some later point in time. Although not relevant to the topic of this document, I should mention that the usual practice is to first merge master back into feature_X to make sure it has all the other stuff that master may have acquired till now (this is shown by commit 9 below) before continuing further development: