gittar
======

Gittar creates a git commit from a directory or an archive, allowing you to
store a sequence of selective filesystem-snapshots as git commits.


Why?
----

The initial use case for ``gittar`` was storing a compiled version of an
application in a seperate root inside a git repository. Here's an example:

Assume you have a webapplication that needs to compile its assets before being
deployed. You do not want to have to install a lot of LESS or JS compilers, CSS
minifiers, etc. on your production environment.

First, you run your build tool (e.g. ``scons`` when using `the scons-tools web
module <https://github.com/mbr/scons-tools>`_), now your app is inside the
directory ``myapp``, including the compiled static files, while the source
files reside outside the ``myapp`` directory.

Now, you can run::

  gittar -b web file:myapp

This will create a new commit containing everything inside the ``myapp``
directory. If the branch ``web`` does not exist, it will be created and will
point to the new commit, which will have no parent. If the branch did exist
before, the new commit will have it as a parent and the branch will be updated.

The hash of the new commit will be printed to stdout. If the ``-b`` option is
not specified, this is the only way to reach the commit.

A simple application for this is deploying to `heroku <http://heroku.com>`_.
Build your app, add a new ``gittar``-commit to the web branch and push it using
``git push heroku web:master``.


Schemes
-------

``gittar`` can add files from ZIP-Archives, tar-Archives or plain directories
and files.

All sources for inclusion are specified using the following syntax::

  scheme:arg1:arg2:...:named_arg1=value1:named_arg2=value2:...

A scheme is one of ``file``, ``zip`` or ``tar``. The arguments and named
arguments are passed on to the sources collecting the files and have meanings
depending on the scheme.

Multiple schemes can be specified in a single command.

The file-scheme
~~~~~~~~~~~~~~~

A single file or a directory can be added as follows::

  gittar file:myfile file:/my/home/special_file file:/some/directory

This will add ``myfile`` to the commit with the path ``myfile``. The file
``/my/home/special_file`` will also be added, but named ``special_file`` (no
path) inside the commit.

Assuming ``/some/directory`` is a directory, all files in it will be added
recursively, their names inside the commit being their relative paths to
``/some/directory`` and the directory name. Example: A file
``/some/directory/foo/bar`` will be added as ``directoryfoo/bar`` to the
commit.

The zip-scheme
~~~~~~~~~~~~~~

Adds the contents of a zip-Archive::

  gittar zip:/path/to/some/archive.zip

This will add all files inside ``/path/to/some/archive.zip`` with their
relative paths to the commit.

The tar-scheme
~~~~~~~~~~~~~~

Works fairly similiar to the ``zip``-scheme, but for tar archives. Automatic
detection of compression is done. Example::

  gittar tar:somearchive.tar tar:/another/archive.tar.bz2


Common Options
--------------

Extra options can be specififed, some are valid for all sources.

Inclusion/Exclusion
~~~~~~~~~~~~~~~~~~~

The ``include`` and ``exclude`` options can be used to specify which files
should be included in the commit. Example::

  gittar tar:myarchive.tar:include=*.css:include=output/*.html:exclude=*~

Note: You will most likely have to enter this with backslash-escaped asterisks
(``\*``) on your shell.

The command above will include all CSS files and all HTML files from the output
folder, provided they do not end in a tilde``~``.

If no include option is given all not-excluded files are included.

Regular expressions
~~~~~~~~~~~~~~~~~~~

The ``include`` and ``exclude`` commands use UNIX shell patterns. You can use
python (Perl-like) regular expressions by using ``rinclude`` and ``rexclude``
instead.
