I'm guessing that the reason each branch has its own history is probably related to the goal of only appending new entries at the end of things. Since any branch can be under development, they need their own files. It sort of makes sense.
I still think that you're a little confused. The reflog is a "history of where this branch has pointed since the repository was created/cloned." If I clone a repository with a history of 100 commits on the 'master' branch, the reflog for the 'master' branch will only have one entry. You can completely delete the `.git/logs` and still run `git log` successfully.
Here's an example:
$ git clone blah
DAG:
A - B - C - D - E
\
Z - X - Y
Branches:
master => E
topic/new-feature => Y
reflog:
master
E - clone from blah
topic/new-feature
Y - clone from blah
Notice how cloning a repository with an existing DAG doesn't populate the reflog. It just give it a single entry saying that the branch was updated from 'nothing' to whatever commit it was pointing to remotely.
Now let's change where 'master' is pointing:
$ git reset master C
DAG:
A - B - C - D - E
\
Z - X - Y
Branches:
master => C
topic/new-feature => Y
reflog:
master
E - clone from blah
C - reset to C
topic/new-feature
Y - clone from blah
Notice how the reflog is a history of the values that the branch was referencing, but is not the history as what you get when you run 'git log'. After the reset, 'git log master' would show you commits A, B and C, but A and B are nowhere in the reflog.
I see. I started reading the internals chapter at[1]. This free book seems better than the O'Reilly book, which I bought.
So the DAG is actually stored inside objects. The contents of the objects directory could be described by a relational schema, and I think that would make it easier for a lot of people to understand (myself included):
Blob
- sha1hash (primary key)
- contents (blob)
Tree
- sha1hash (primary key)
TreeEntry
- treeid (foreign key into Tree)
- mode (mode of blob/subtree)
- type ("blob" or "tree")
- objectid (foreign key into Tree or Blob)
- name
Commit
- sha1hash (primary key)
- tree (foreign key into Tree)
- parent (foreign key into Commit)
- author
- committer
- comment
The tree entries are actually denormalized and stored as a list inside the tree. You could represent this more accurately with XML. But who likes XML?