Git Storage Guide

Tackler has integrated and native support for GIT version control system.

This means that tackler will process accounting data directly from Git repository, which could be "bare". Point of history for accounting data could be selected by all normal Git’s way of references, and version metadata will be included directly to the generated reports. This also means that generated reports are always made out of well known and well defined state of accounting data.

This provides one key of the immutable audit trail of used accounting data. This audit trail can be printed e.g. on paper or transferred directly to accountant or escrow agent. See Accounting Auditing if there is need for audit trail of used account data.

See Transaction data sharding for ideas how to store data inside git repository. It is really good idea to select feasible way to split up journal, so that possible merge conflicts could be kept at minimum. Tackler supports happily one-transaction - one-journal-file mode.

Using GIT branches and references with Tackler

Tackler supports use of multiple branches, and transactions sets can be referenced by standard git ways:

  • by ref names (e.g. refs/heads/master, refs/tags/Y2016),

  • by symbolic refs (HEAD, master, Y2016)

  • directly by commit ids (short a7938d9b or long form a7938d9b61958d2cabea7503a7be89191d4fb31e are supported).

Git storage backend can use git repository as bare repository or as .git-directory inside cloned working copy. This means that Tackler is always using committed, clean internal state of git repository.

This has multiple advantages:

  • Transaction data can be read directly from pack files with bare repositories

  • Transaction data can be easily manipulated by server systems

  • Transaction data is always in "clean state" from git perspective and it is extremely well defined with recorded commit ids

Git storage backend is performance tested up to one million (1E6) transactions and its performance is on par or better with filesystem based storage backend.

Tackler’s Git support is provided by JGit. JGit is pure java implementation of the Git version control system.

Why to use git as transaction data storage?

There are several advantages to use git as storage system for account data. Git itself is very good distributed version control system with many features.

Git has some very important features for Tackler and accounting in general:

  • Data assurance

    • Clean, possible audited, track record who has made or changed journal data

    • Uniquely identified journal data which was used to generate reports (each report contains git metadata, e.g. commit id)

  • Data input collaboration, data distribution and backup

    • With all power of git it is very easy to distribute and share journal data input task

    • Journal handling (data input) and reporting can be separated

    • With good data shard merge conflicts can be kept at minimum

  • Topic based Accounting

    • With git’s branches it is possible to create topic based accounting system where each branch is specific topic

    • Topics could be used for auditing or handling cleared and uncleared transactions

    • These topics can be merged together in aggregate branches

Demo setup how to use git journal

First you have to create transaction data on git. This is just normal journal data, which is pushed to git repository. It is possible to use either bare repository or git-folder from cloned working copy.

Demo setup with bare journal
mkdir tackler
cd tackler

git init --bare journal.git
git clone journal.git

cd journal
mkdir txns

cat > txns/txn-01.txn << EOF
2017-04-23 'first demo transaction
 Expenses:Ice_cream  2
 Assets:Cash

EOF

git add txns/txn-01.txn
git commit -m 'first transaction'

cat > txns/txn-02.txn << EOF
2017-04-23 'second demo transaction
 Expenses:Lemonade  1
 Assets:Cash

EOF

git add txns/txn-02.txn
git commit -m 'second transaction'

git push

cd ..

Then you have to configure git storage, see tackler.conf for full explanation, but it could be as simple as:

cat >> git-storage.conf << EOF
tackler {
  core {
    basedir = .
    input {
      storage = git
      git {
        repository = "journal.git"
        ref = "master"
        dir = "txns"
        suffix = ".txn"
      }
    }
    reporting {
      console = true
      reports = [ "balance", "register" ]
    }
    accounts.strict = false
  }
}
EOF

Save configuration e.g. as git-storage.conf and put it into tackler folder:

ls tackler/
git-storage.conf
journal.git

Now you could run default reports by just running:

java -jar tackler-cli.jar --cfg git-storage.conf

This will produce something like that:

Txns size: 2
Git storage:
   commit:  cf9a1c3f6b0d34f4d28800062ad7d6e16189ccce
   ref:     master
   dir:     txns
   suffix:  .txn
   message: second transaction

BALANCE
-------
                 0.00   -3.00  Assets
                -3.00   -3.00  Assets:Cash
                 0.00    3.00  Expenses
                 2.00    2.00  Expenses:Ice_cream
                 1.00    1.00  Expenses:Lemonade
=====================
                 0.00

Git storage:
   commit:  cf9a1c3f6b0d34f4d28800062ad7d6e16189ccce
   ref:     master
   dir:     txns
   suffix:  .txn
   message: second transaction

REGISTER
--------
2017-04-23Z 'first demo transaction
            Assets:Cash                                   -2.00              -2.00
            Expenses:Ice_cream                             2.00               2.00
----------------------------------------------------------------------------------
2017-04-23Z 'second demo transaction
            Assets:Cash                                   -1.00              -3.00
            Expenses:Lemonade                              1.00               1.00
----------------------------------------------------------------------------------


Total processing time: 3019, parse: 641, reporting: 78

If you like to see your financial situatiation before you went crazy with lemonade, you could run git log inside your journal’s working copy, and figure out commit id for first transaction.

Let’s say that it was 49551a0f3418486e576ce9076506fe94e2dbddf6. You could also use short form of commit id:

java -jar tackler-cli.jar --cfg tackler-demo.conf --input.git.commit 49551a0f

This will generate reports from accounting data as it was by time of that commit:

Txns size: 1
Git storage:
   commit:  49551a0f3418486e576ce9076506fe94e2dbddf6
   ref:     FIXED by commit
   dir:     txns
   suffix:  .txn
   message: first transaction

BALANCE
-------
                 0.00   -2.00  Assets
                -2.00   -2.00  Assets:Cash
                 0.00    2.00  Expenses
                 2.00    2.00  Expenses:Ice_cream
=====================
                 0.00

Git storage:
   commit:  49551a0f3418486e576ce9076506fe94e2dbddf6
   ref:     FIXED by commit
   dir:     txns
   suffix:  .txn
   message: first transaction

REGISTER
--------
2017-04-23Z 'first demo transaction
            Assets:Cash                                   -2.00              -2.00
            Expenses:Ice_cream                             2.00               2.00
----------------------------------------------------------------------------------


Total processing time: 2879, parse: 600, reporting: 73

Notice that Tackler warns you (FIXED by commit) that you are not anymore following ref and ref’s head.

See Usage Manual for general instructions how to use tackler with git.

Difference between refs and commits

Tackler follows head of ref automatically, so ref is good way to follow accounting branch as it evolves.

On the other hand, commit ids are fixed in time and they do not change. Same way transaction data identified by commit id do not change over time.

So by specifying transaction data with commit id you create an immutable, persistent uniquely identified view to the journal. Tackler records used commit id on each report and it could be used to re-create same reports or additional reports if there is ever need in future.

For long term referencing of some certain state it is also possible to create a git tag.