DITrack Manual

Version 0.4

The DITrack Project

This work is licensed under the BSD license terms. The full text of the license is available here.

Oct, 2 2006

Table of Contents

1. Overview
System Design
The Ontology
2. Installation
3. Usage
Getting Help
Specifying Database To Use
Other Environment Settings
Database Initialization
Database Configuration
Regular Work Cycle
Adding A New Issue
Acting On An Existing Issue
Querying The Database

Chapter 1. Overview

DITrack is an issue tracking system. Its primary purpose is to store and organize text records that reflect real-world issues an organization has to deal with. The system is primarily targeted to small software projects with flat organizational structure (where no complex access control policies have to be enforced).


This document is a general system architecture overview and a user manual at the same time. It is assumed that the reader is familiar with Subversion version control system and has a basic knowledge of UNIX environment.

System Design

DITrack uses a Subversion repository to store its data. The repository is used merely as a distributed versioned file system: DITrack makes no assumptions about its layout. The diagram below displays the system structure.

	Server side				Client side

	+-------------------+		     +-------------------+
	| Subversion server |----------------| Subversion Client |
	+-------------------+		     +-------------------+
		 /				|	    \
		/				|	+--------------+
(DITrack Pre-Commit Hook)			|	| Working copy |
	     /					|	+--------------+
+------------+					|	    /
| Repository |				    +----------------+
+------------+				    | DITrack Client |
					    |     End User   |
					    |   Or Software  |
					    |    Component   |

The diagram shows only single client instance; however there may be a number of them. Each client has a working copy which contains a snapshot of DITrack issues database. Since the latter is just a subtree of a Subversion repository, single repository may contain unlimited number of DITrack databases. Again, since the issues database is just a Subversion working copy, usual rules of dealing with that apply: it should be periodically updated (i.e. synchronized with the repository by 'svn update').

All data files DITrack makes use of within the working copy are plain text (mostly conforming to RFC2822 message format). In a case when the DITrack client is not available, a user may just hand-edit the files with any ASCII text editor and commit the changes.

However, since the issue database is a set of related entities, the consistency should always be preserved (at least at the synchronization points, i.e. when an 'svn update' or 'svn commit' happens). To enforce data consistency, a pre-commit hook script is installed on the server side. It basically ensures that the transaction which is about to be committed doesn't break the database consistency. Thus, even is a user edits data files manually, the database won't get corrupted.

NB! As of version 0.4, there is no server-side hook. It will be implemented in a future release.

It is worth noting that instead of a human user the client might be a software component that acts on behalf of the user. This way, for example, a web interface or e-mail integration facility for the issues database may be built.

Also note that DITrack on the client side is only a driver which controls Subversion client. The former does not initiate or handle any network activities. Its role is limited to modifications of local working copy and running appropriate Subversion commands to synchronize with the repository.

The Ontology


The data model used by DITrack is designed to be as simple and general as possible. The basic entity class is the issue - a collection of (primarily) textual records describing real-world issue and the progress being done to resolve that. Each issue is assigned a unique numeric identifier. The very first issue in a database is assigned identifier 1 and each following one is given the next integral number.

Each issue consists of a header and a description; it can also have comments added and files attached.

An issue header contains a number of fields that are used by DITrack and can also have arbitrary user-specified fields (provided they conform to certain syntax rules). DITrack makes use of the following fields:

A category the issue falls into.
Current estimate of the issue resolution deadline.
An identifier of the user who originally opened the issue.
A timestamp when the issue was initially opened.
An identifier of a user who is currently responsible for resolving the issue.
A version of a product the issue was reported against.
Current status of the issue: "open" or "closed".
A short description of the issue.


The system has a notion of users. Each user has an identifier which is basically the user's login name. There are no roles or access rights attributed to any user in the system.


Issues handled by the system fall into different categories. Hence the notion of the latter. Each category has an identifier which is a sequence of non-blank characters. The name space for the categories is flat (i.e. the names are not structured in any sort of hierarchy that DITrack is aware of); however it is possible to imitate tree structure by crafting category names according to certain rules. For example, the following category names are treated as flat by DITrack but are perceived as hierarchially organized: "unknown", "frontend", "frontent/user-editor", "backend", "backend/server", "backend/tools", "backend/tools/cleaner", etc. "-" cannot be used as a category name.

Each category is associated with a version set. Different categories may share common version sets.


Versions represent different time points in a lifetime of a product. Obviously they are not strictly tied to real version numbers; they may represent arbitrary milestones in a development cycle. Version names are sequences of non-blank characters; "/" cannot be used as a version name.

Versions are arranged into sets. Since a single project may contain several products released on different schedules, different version sets may be used to track each product development. Version names within a set are divided into three groups ("tenses"): "past" versions, "current" versions and "future" versions.

The notion of "tenses" is introduced to aid a user in dealing with potentially large version sets. A product may have a huge number of versions released per its lifetime; however, when filing a bug report or planning the features for a couple of nearest releases of a product, a user needs only a handful of versions to consider. Thus, "future" versions are used for planning: the target milestone for the issue (the "Due-in" header field) may contain only a future version name. The "current" versions are used when reporting an issue: they indicate all versions of product that are currently in use. And finally the "past" versions represent versions of product that are no longer supported: their names cannot appear in an open issue.

Chapter 2. Installation

As of now, DITrack doesn't have an installation routine. DITrack itself is a couple of Python and Shell scripts and modules. Thus, it can be used without regular system-wide installation.

Alternatively, DITrack may be installed system-wide manually as follows:

  1. Copy the 'dt' and 'dt-createdb' files to the location where your locally installed binaries reside. Most probably, it is '/usr/local/bin', '/opt/bin' or alike.

  2. Copy the 'DITrack' directory to the location where your locally installed Python modules reside. Most probably, it is '/usr/local/lib/python' or alike.

Chapter 3. Usage

The DITrack command line client and the script to create new issue databases are named 'dt' and 'dt-createdb' respectively. The former is a Python script that uses library modules distributed with the system in 'DITrack' subdirectory. So make sure that the modules are available in system paths for Python modules (PYTHONPATH environment variable, see Python manual for details) or in current directory. This means that if you have not installed DITrack system-wide, you'll need to change current directory to the one where DITrack resides each time you run 'dt'.

All following examples assume that DITrack is installed system-wide. '$' represents shell prompt here.

Getting Help

You can always get a brief help message with a list of available commands by issuing:

$ dt help

To get help for specific command, append its name after 'help', as in

$ dt help act

Specifying Database To Use

The 'dt' script assumes that the current directory is the root of the issues database you want to work with. There are two ways to change this assumption.

DITrack checks the DITRACK_ROOT environment variable, and if it's set, its value is used to reference an issue database. In a Bourne shell, it may be set with the the command like the following:

$ export DITRACK_ROOT="/home/joe/myproj/issues"

Alternatively, the '-d' option may be used to specify the location of a database. It has the highest precedence so may be used to override DITRACK_ROOT environment variable:

$ dt ls -d ~/some/other/issue/database

Other Environment Settings

Since working with issues includes a fair bit of text editing, DITrack needs to know which application to use for that. Environment variable EDITOR should be set upon invocation of any 'dt' command that might involve editing.


Database Initialization

DITrack needs an issue database to work on. It has to be checked out and reside in a working copy and be available for both reading and writing. The database has certain structure, so it needs to be created with special utility; 'dt-createdb' is the one to use for that purpose.

An issue database is usually created on per-project basis. Depending on your preferences the Subversion repository you own probably hosts one or multiple projects. This detail is irrelevant here, since whatever repository structure is, we'll consider only a single project of that to use in the following examples.

Suppose, the project structure in the repository is as follows:


The natural placement for an issue database with such a layout would be under 'myproj' directory.

The following command will nonrecursively check out specified repository path into 'myproj-root' directory and initialize issue database named 'issues' in there.

$ dt-creatdb svn://server/projects/myproj issues myproj-root

The command will initialize database structure without committing any changes to Subversion repository. This action item is left for you do. You might want to tweak the database configuration as described below before committing that to your repository.

Database Configuration

The first things you might wish to configure for newly created issue database are: user list, version sets and categories.

User List

Users' identifiers are stored in the 'etc/users' file under a database root. The syntax is simple: it's just a list of user identifiers, one per line. Example:


You may edit the list with any text editor and commit your changes manually.

Version Sets

Version sets are stored in the 'etc/versions' file under a database root. This configuration file defines one version set per line. Each line is arranged as follows:

set-name: [pv [pv [ ...]]] / [cv [cv [ ...]]] / [fv [fv [ ...]]]


is a name of the version set;
is a name of a past version;
is a name of a current version;
is a name of a future version.


infrastructure-milestones: initial 200605 200606 / - / 200607 200608 sometimes
editor-versions: 1.0 2.0 2.1 / 2.2 3.0 3.1 / 2.3 3.2 4.0 5.0
backend-versions: 1.0.0 1.0.1 1.1 / 1.1.1 1.1.2 / 1.1.3 1.2.0 2.0


Category definitions are stored in the 'etc/categories' file under a database root. The configuration file defines one category per line. Each line is arranged as follows:

category-name: versions=version-set default-owner=user


is a name of the category being defined;
is a name of the version set associated with this category;
is an identifier of a user who is the default owner of issues for this category.


infrastructure: versions=infrastructure-milestones default-owner=joe
editor: versions=editor-versions default-owner=sally
backend: versions=backend-versions default-owner=rob

Regular Work Cycle

There are three basic actions that can be performed against an issue database: adding issues, acting on existing issues and querying. Thus DITrack command line client ('dt') features three basic commands for that: 'new', 'act' and 'ls'.

Adding A New Issue

To add a new issue, use the 'new' command. You will be prompted to choose a category that the new issue falls into, the version of a product this issue is filed against, the issue title and then shelled out into an editor to enter the issue description. Once you are done with that, you'll be finally asked for a due version of this issue and upon that the newly added issue will be committed into the database.

Acting On An Existing Issue

To take an action on an existing issue, use the 'act' command. A menu of possible actions will appear, which include closing/reopening the issue, changing due version, adding a comment, reassigning owner and edition of the issue header.

It is also possible to act on several issues at once. Just specify a list of issues as arguments for the 'act' command:

$ dt act 10 14 28

Actions you take will apply to all listed issues. Available menu options depend on the particular issues properties. For example, "change due version" menu option is only available if all issues listed share the same version set.

Querying The Database

Listing Existing Issues

The 'ls' command provides a way to query an issues database. If run without additional arguments, it dumps a list of all existing issues.

Additional arguments may be supplied that will be recognized as filter expressions or predefined filter names. If an argument doesn't look like an expression (doesn't contain '=', as of now), it's assumed to be a predefined filter name.

Filter expression is a list of comma-separated conditionals:


...where each condition


is a field name and value, separated by an operator:


Operators supported are '=' ("equals") and '!=' ("doesn't equal").

A filter expression matches if all of its conditionals match.

For example, the following command will list all issues which status is "open" and the owner is "joe":

$ dt ls Status=open,Owned-by=joe

Note that field names and values are case-sensitive!

If several filter expressions are specified, the output will include issues that match any of the expressions. The following command will list issues owned by 'joe' or 'rob':

$ dt ls Owned-by=joe Owned-by=rob

Predefined filters associate filter expressions with names to save typing for frequently used queries. The configuration file for predefined filters is called 'filters' and resides under 'etc' directory of an issue database. The file lists predefined filter names, one per line, followed by a colon and a list of conditions as in arguments for 'ls' command:

1.0: Due-in=1.0,Status=open
1.1: Due-in=1.1,Status=open
closed: Status=closed

...thus, with the configuration above the invocation of:

$ dt ls 1.1

...is equivalent to:

$ dt ls Due-in=1.1,Status=open

In addition to this, the right side of conditional expression may refer to environment variable set at the time of 'dt ls' invocation, like:

my: Owned-by=$USER

When invoked:

dt ls my

... 'my' will be treated as 'Owned-by=$USER' where '$USER' is replaced with 'USER' environment variable value.

Viewing A Full Record Of An Issue

The 'cat' command dumps a full text of an issue record to standard output.