# Vision

Jonathan Aquino [suggests][1] that version control commit messages can
be a form of Literate Programming.

[1]: http://jona.ca/blog/git-commit-messages-are-the-new-literate-programming

The original Literate Programming concept by Donald Knuth suggested that
the code should be embedded in comments describing everything that was
in the head of the author while the code was being written. This never
caught on, perhaps because this leads to code with too long comments.

On the other hand, Jonathan notes that some people write really detailed
Git commit messages.

Would it be feasible to present a Git repository as a collection of
chapters and sections, with each coherent change accompanied with a
descriptive commit message telling the story behind the change?

Using the GitHub API, we can extract commit messages from a repository
and render them as Markdown documents, along with diffs.

I imagine that composing such a repository requires a vastly different
discipline and/or workflow than many of us are used to.

* For example, you don’t just `git commit -am 'Fix bug'`; you actually
start writing your commit message _before_ you start fixing the bug,
while investigating the bug cause, the workarounds, and the solution.
When implementing a new feature, you might start with an empty commit,
explaining the need for the feature and/or its design (like I’m doing
here).
* I also think this requires a good deal of history rewriting. For
example, just now I had to fix the syntax of the hyperlink above, so
that it would be parsed by the Markdown library I chose. This caused a
rebase of the whole repository.
HTML skeleton

Let’s add a simple HTML skeleton in which we will show the repository.
We will show the repo name in the page title, the description as the top
heading, and a list of commits. All these will be populated dynamically,
so we give them IDs.
Display repository description

Let’s try interacting with the GitHub API. As usual, we create an
`XMLHttpRequest`, hook up an event handler, and send the request.

For now, I hardcoded the repository owner and name. In future, they can
be taken from the URL query string.

Also, for simplicity, I treat the description as plain text; I will get
to Markdown formatting later.
Factor out AJAX mechanics

Before we display the list of commits, notice that a single API request
requires quite a few lines of code. Let’s factor out all the repeating
steps in a function.

The two things that change from one API call to another are the URL and
the handler function. However, the handler will always need to parse a
JSON response.
Show list of commits

Let’s now fetch the list of commits and show their summaries, with links
to the same page but with a ?sha=xxxxxx query parameter.

The regular expression there splits a commit message into the summary
and the body, using the topmost sequence of two consecutive newlines as
the separator; if there is none, considers the whole message to be the
summary. The `[^\0]` pattern matches any character including newline but
not including the null character (though hopefully nobody in their right
mind uses null characters in commit messages).
Factor out generation of commit list

The links are there but they don’t work. Since they all lead to the same
page, we’ll have to parse that ?sha= and, depending on its presence,
either show the commit list or details of a specific commit.

Before we do that, though, it makes sense to move the commit listing
functionality into a separate function.
Factor out commit message splitting function

We’ll need this function in at least one more place, so let’s DRY it
out.
Show commit details

Now let’s add an ability to show a specific commit.

In HTML, we add a single `div` for this mode, and inside it a heading
for the commit message summary, a `pre` for the body, and a `section`
for all the diffs.

We style the `commits` list and the `single-commit` div to be visible
only depending on the class of the root `body` element, which we toggle
in specific command handlers.

The `showCommit` function takes a `sha` argument, fetches the commit
details and populates the `single-commit` section.

For now, we are treating everything as plain text.
Render markdown

GitHub has a Markdown API but it suffers from a fundamental flaw: It
takes a single Markdown string, returns an HTML string, and is
Rate-limited. This has two consequences:

* We would make a lot of requests, which would be fulfilled
asynchronously and cause much redisplay.
* The default rate limit for unauthenticated requests is 60 requests per
hour. By browsing the list of commits of a mature repository, we can
exhaust that instantly.

So let’s do markdown rendering on the client, using the [markdown-js][]
library. It is distributed under the MIT license.

[markdown-js]: https://github.com/evilstreak/markdown-js