storage       High level overview of how commits, tags, and branches are stored

Basics
  Each revision is referred to by a cryptographic checksum (in particular,
  a sha1sum) of its contents.  Each revision also knows which revision(s)
  it was derived from, known as the revision's parent(s).

  Each branch records the cryptographic checksum of the most recent commit
  for the branch.  Since each commit records its parent(s), a branch
  consists of its most recent commit plus all ancestors of that commit.
  When a new commit is made on a branch, the branch just replaces the
  cryptographic checksum of the old commit with the new one.

  Remote tracking branches, if used (see 'eg help remote'), differ from
  normal branches only in that they have a slash in their name.  For
  example, the remote tracking branch that tracks the contents of the
  stable branch of the remote named bob would be called bob/stable.  By
  their nature, remote tracking branches only track the contents of a
  branch of a remote repository; one does not switch to and commit to these
  branches.

  Tags simply record a single revision, much like branches, but tags are
  not advanced when additional commits are made.  Tags are not stored as
  part of a branch, though by default tags that point to commits which are
  downloaded (as part of merging changes from a branch) are themselves
  downloaded as well.

  Neither branches nor tags are revision controlled, though there is a log
  of changes made to each branch (known as a reflog, short for "reference
  log", because calling it a "branch log" wouldn't make the glossary of
  special terms long enough).

Pictorial explanation
  Using the letters A-P as shorthand for different revisions and their
  cryptographic checksums (which we'll assume were created in the order
  A...P for purposes of illustration), an example of the kind of structure
  built up by having commits track their parents is:
        N
        |
        M   P
        |   |
        L   O
        | \ |
        J   K
        |   |
        H   I
        | /
        G
        |
        F
       / \
      C   E
      |   |
      B   D
      |
      A
  In this picture, F has two parents (C and E) and is thus a merge commit.
  L is also a merge commit, having parents J and K.  There are two branches
  depicted here, which can be identified by N and P (due to the fact that
  branches simply track their most recent commit).  This history is
  somewhat unusual in that there is no unique start of history; instead
  there are two beginnings of history -- A and D.  Such a history can be
  created by pulling from, and merging with, a branch from another
  repository that shares no common history.  While unusual, it is fully
  supported.

  For further illustration, let's assume that the following branches exist:
      stable: N
      bling:  P
  Then the picture of each branch, side by side (using revision identifiers
  explained in 'eg help topic revisions'), is:
            stable
              |
           stable~1                                     bling
              |                                           |   
           stable~2                                    bling~1
              |   \                                       |   
        stable~3  stable~2^2                           bling~2
              |     |                                     |   
        stable~4  stable~2^2~1                         bling~3
              |  /                                     /      
          stable~6                                bling~4     
              |                                     |         
          stable~7                                bling~5     
            /   \                                 /   \       
      stable~8  stable~7^2                   bling~6  bling~5^2
          |       |                             |       |     
      stable~9  stable~7^2~1                 bling~7  bling~5^2~1     
          |                                     |             
      stable~10                              bling~8             
  Note that there are many commits which are part of both branches,
  including two commits (I and K in the original picture) which were
  probably created after these two branches separated.  This is simply due
  to recording both parents in merge commits.

  Note that this tree-like or graph-like structure of branches is an
  example of something that computer scientists call a Directed Acyclic
  Graph (DAG); referring to it as such provides us the opportunity to
  make the glossary of special terminology longer.

Files and directories in a git repository (stuff under .git)
  You may find the following files and directories in your git repository.
  This document will discuss the highlights; see the repository-layout.html
  page distributed with git for more details.

  COMMIT_EDITMSG
    A leftover file from previous commits; this is the file that commit
    messages are recorded to when when you do not specify a -m or -F option
    to commit (thus causing an editor to be invoked).

  config
    A simple text file recording configuration options; see 'eg help config'.

  description
    A file that is only used by gitweb, currently.  If you use gitweb, this
    files provides a description of the project tracked in the repository.

  HEAD
  ORIG_HEAD
  FETCH_HEAD
  MERGE_HEAD
    See the Special Names section of 'eg help topic revisions'; these files
    record these special revisions.

  git-daemon-export-ok
    This file is only relevant if you are using git-daemon, a server to
    provide access to your repositories via the git:// protocol.
    git-daemon refuses to provide access to any repository that does not
    have a git-daemon-export-ok file.

  hooks
    A directory containing customizations scripts used by various commands.
    These scripts are only used if they are executable.

  index
    A binary file which records the staging area.  See 'eg help topic
    staging' for more information.

  info
    A directory with additional info about the repository

    info/exclude
      An additional place to specify ignored files.  Users typically use
      .gitignore files in the relevant directories to ignore files, but
      ignored files can also be listed here.

    info/ignored-unknown
      A list of unknown files known to exist previously, used to determine
      whether unknown files should cause commit (or push or publish) to
      abort.  See 'eg help commit' for more information; this list is
      updated whenever the -b flag is passed to commit.

    info/refs
      This is a file created by 'eg update-server-info' and is needed for
      repositories accessed over http.

  logs
    History of changes to references (i.e. to branches, tags, or
    remote-tracking branches).  The file logs/PATH/TO/FILE in the
    repository records the changes to the reference PATH/TO/FILE in the
    repository.  See also the 'Revisions from logged branch tip history'
    section of 'eg help topic revisions'.

  objects
    Storage of actual user data (files, directory trees, commit objects).
    Storage is done according to sha1sum of each object (splitting sha1sums
    into a combination of directory name and file name).  There are also
    packs, which compress many objects into one file for tighter storage
    and reduced disk usage.

  packed-refs
    The combination of paths, filenames, and sha1sums from many different
    refs -- one per line; see refs below.

  refs
    Storage of references (branches, heads, or remote tracking branches).
    Each reference is a simple file consisting of a sha1sum (see 'eg help
    topic storage' for more information).  The path provides the type of
    the reference, the file name provides the name for the reference, and
    the sha1sum is the revision the reference refers to.

    Branches are stored under refs/heads/*, tags under refs/tags/*, and
    remote tracking branches under refs/remotes/REMOTENAME/*.  Note that
    some of these references may appear in packed-refs instead of having
    a file somewhere under the refs directory.