#!/bin/blog --author=p4bl0

the blog where all numbers are written in base 10

fugitive: README

by p4bl0, on
last update by p4bl0, on

Info

fugitive is a blog engine running on top of git using hooks to generate static html pages and thus having only git as dependency.

In its hooks, fugitive uses only standard UNIX® tools that are included in the GNU core-utils package, plus sh as script interpreter. That's it.
Moreover, everything that can be done using git, is.
No dependencies like rack, heroku, or whatever Ruby gems you can think of. No configuration files. No metadata in your articles files. Hell, if you want to you could even make a template that use git log as storage backend, which means no files either, just and only git.

Install

Build

If you want to build fugitive from the source, clone the git repository:
git clone http://clandest.in/fugitive fugitive
Then go in the newly created directory: cd fugitive, and run the build script: ./build.sh.
This will generate an executable file "fugitive" which you can use to create your blog.

Create a blog

There's two install mode for fugitive: local and remote. The local mode should be used to install a repository where you edit your blog, and the remote mode for a repository to which you're going to push to publish your blog.
The local mode can also be used to publish if you edit your file directly on your server.

To create your blog run the command:
fugitive --install-mode <dir>, where mode is either "local" or "remote".
This will create the git repos with appropriate hooks, config and files in <dir>.
If <dir> isn't specified then the current working directory is used.

Once you have installed your blog you need to set the blog-url parameter in your git configuration. See configuration for details.

Configuration

All this settings are in the "fugitive" section of the git config. You can change them with the command
git config fugitive.parameter value, where parameter is one of the following:

blog-url
This is the public url of the generated blog. You need to set it as soon as possible since it's required for the RSS feed (and used in the default template's footer).
public-dir*
This is the path to the directory that will contain the generated html files. Default value is "_public". You could set it to "_public/blog" for instance if you want to have have a website in "_public" and your blog in "/blog".
articles-dir*
This is the path where fugitive will look for published articles. Default value is "_articles".
templates-dir*
This is the path where fugitive will look for templates files. Default value is "_templates".
preproc
If you want your article to be preprocessed by an external tool (markdown, textile...) you need to set preproc to a command line that will read on stdin and write to stdout.

* Those paths are relative to the root of the git repository, must be in it and must not start with "." neither have a '/' at the end. Example: "dir/subdir" is valid but "./dir/subdir" and "dir/subdir/" are not.

Usage

General use

Article you want to publish should be file without the .html extension in the articles-dir directory (see configuration). The first line of the file will be used as title and the rest of the file as the content of the article.

By default there's a "_drafts" directory in which you can put articles you are writing and you want to version control in your git repository but you don't want to publish yet.

When you commit change to a fugitive git repository, the post-commit hook looks in the articles-dir directory (see configuration) for newly added articles, modified articles and deleted ones. Then it does the following things:

  • it generates static html files for newly added articles,
  • it regenerates static html files for modified articles,
  • it deletes static html files for deleted articles,
  • it regenerates static html files for articles that are just before and after newly added and deleted articles (this to maintain the "previous" and "next" links alive),
  • it regenerates the archives.html and feed.xml files,
  • and finally it copies the static html file of the last article to "index.html".

If a change happen in the templates-dir directory (see configuration), then static html files for everything is regenerated to make the change effective.

All generated files are created in the public-dir directory (see configuration).

When you push to a remote repository installed with fugitive, the same thing will happen but instead of looking only at the last commit, the hook will analyse every changes since the last push and then (re)generate html files accordingly.

Do not create an article file named "archives".
Do not create an article file named "index".

Template system

The better explanation about the templates system is to see what the default templates looks like. But since they do not use all the offered possibilities, here are some more explanations...

The fugitive template system uses xml preprocessor syntax: <?fugitive var ?> is rendered as the value of var. This choice has been made because with this syntax templates are still valid xml (and html) document, and it is semantically more accurate than xml comments (<!-- var -->).

In addition to variable rendering, there are a conditional and a foreach loop constructs, plus an include directive.

The syntax of the include directive is <?fugitive include:file ?> where file is relative to the templates-dir directory (see configuration). The includes are processed before anything else.

The foreach loop construct is specific to the archives.html and feed.xml templates and will therefore be described at the same time. Where available, the loops are processed right after the includes.

The syntax of the conditional construct is as follow:

<?fugitive ifset:var ?>
  Template code which is ignored if var value is empty, and
  which typically includes <code><?fugitive var ?></code>.
<?fugitive endifset:var ?>

Not every variables can be used in the conditional construct, it is indicated in the description of those which can't.

The following variables are available everywhere:

page_title
Its value is "archives" in the archives.html template, "feed" in the feed.xml template, or the article title in the article.html template.
blog_url
the blog-url value in the "fugitive" section of the git configuration (see configuration).
commit_Hash
Its value is the hash corresponding to the last commit that provoked the (re)generation of the file.
commit_hash
Its value is the short hash (the seven first digit of the hash) corresponding to the last commit that provoked the (re)generation of the file.
commit_author
Its value is the name of the author of the last commit that provoked the (re)generation of the file.
commit_author_email
Its value is the email of the author of the last commit that provoked the (re)generation of the file (with '@' replaced by "[at]" and '.' replaced by "(dot)").
commit_datetime
Its value is the date and time of the last commit that provoked the (re)generation of the file.
commit_datetime_html5
Its value is the date and time of the last commit that provoked the (re)generation of the file, but in an html5 <time> compliant format.
commit_date
Its value is the date of the last commit that provoked the (re)generation of the file.
commit_time
Its value is the time of the last commit that provoked the (re)generation of the file.
commit_timestamp
Its value is the unix timestamp of the last commit that provoked the (re)generation of the file.
commit_subject
Its value is the subject (first line of the commit message) of the last commit that provoked the (re)generation of the file.
commit_body
Its value is the body (the rest of the commit message) of the last commit that provoked the (re)generation of the file. This variable can't be used in the conditional construct.
commit_slug
Its value is the subject of the last commit that provoked the (re)generation of the file but formatted to be file name friendly.

Variables specific to the article.html templates:

article_title
Its value is the title of the article (the first line of the file).
article_content
Its value is the content of the article (the rest of the file). This variable can't be used in the conditional construct.
article_file
Its value is the file name of the article (without the .html extension).
article_cdatetime
Its value is the date and time of the publication of the article (the date of the commit which added the article to the repository in the articles-dir directory (see configuration)).
article_cdatetime_html5
Same as previous, but in an html5 <time> compliant format.
article_cdate
Its value is the date of the publication of the article.
article_ctime
Its value is the time of the publication of the article.
article_ctimestamp
Its value is the timestamp of the publication of the article.
article_mdatetime
Its value is the date and time of the last modification of the article (the date of the last commit which changed the article file).
article_mdatetime_html5
Same as previous, but in an html5 <time> compliant format.
article_mdate
Its value is the date of the last modification of the article.
article_mtime
Its value is the time of the last modification of the article.
article_mtimestamp
Its value is the timestamp of the last modification of the article.
article_cauthor
Its value is the author of the commit which added the article to the repository.
article_cauthor_email
Its value is the email of the author of the commit which added the article to the repository (with '@' replaced by "[at]" and '.' replaced by "(dot)").
article_mauthor
Its value is the author of the last commit which changed the article file.
article_mauthor_email
Its value is the email of the author of the last commit which changed the article file (with '@' replaced by "[at]" and '.' replaced by "(dot)").
article_previous_file
Its value is the file name (without .html extension) of the previous article ordered by publication date.
article_previous_title
Its value is the title of the previous article ordered by publication date.
article_next_file
Its value is the file name (without .html extension) of the next article ordered by publication date.
article_next_title
Its value is the title of the next article ordered by publication date.

foreach loops in archives.html and feed.xml:

Two foreach loops are available: foreach:article and foreach:commit. The syntax is as follow:

<?fugitive foreach:article ?>
  Template code that will be repeated for each article and
  where the values of <code>article_*</code> variables are
  set in accordance with the article each time.
<?fugitive endforeach:article ?>
<?fugitive foreach:commit ?>
  Template code that will be repeated for each commit and
  where the values of <code>commit_*</code> variables are
  set in accordance with the commit each time.
<?fugitive endforeach:commit ?>

The only difference between the archives.html and feed.xml templates is that in feed.xml these constructs only loop on the five last articles and commits.

Hacking fugitive

If you want to hack fugitive code to customize the behavior of the hooks, you can either edit the hooks directly in your fugitive blog repository, or edit them in the fugitive source code, then rebuild the fugitive executable using the build.sh script provided in the source code repository.

In the latter case and if you already have a fugitive blog running, you'll need to install the new hooks. This can be done by running the command:
fugitive --install-hooks <dir>, where <dir> is the path to your fugitive blog repository, if it isn't specified then the current working directory is used.

This can be handy if you decide for instance that you want to have the last n articles on your index.html page rather than a mere copy of the last article.

Known issues

There seems to be some issues with the version of git provided in Debian Lenny (1.5.*), I didn't investigate it yet, and I don't know if I'll do it, because at this time Squeeze is already frozen and git 1.7.* is available in the backports which are now officially supported by Debian.

If you have any remark about this blog or if you want to react to this article feel free to send me an email at "pablo <r@uzy dot me>".