A tool for managing rpm based git projects.
Python Shell Perl
Latest commit 4d75af1 Jan 17, 2017 @dgoodwin committed on GitHub Merge pull request #255 from dgoodwin/issue253
253 - print cmd info when --debug is supplied
Failed to load latest commit information.
.tito Automatic commit of package [tito] release [0.6.9-1]. Jan 9, 2017
bin Replace old Perl script for munging RPM release number. Jun 10, 2015
doc Enable mkdocs and add documentation on Mead. Jun 12, 2015
hacking Merge pull request #249 from stevekuznetsov/skuznets/reconfigure-test-os Jan 6, 2017
share fixes #29 - remove --list-tags and --only-tags Jan 17, 2017
src/tito Merge pull request #255 from dgoodwin/issue253 Jan 17, 2017
test Clean up artifacts before test runs, not after Jan 9, 2017
.editorconfig provide config for editorconfig plugins Feb 27, 2014
.gitattributes provide config for editorconfig plugins Feb 27, 2014
.gitignore DRY up test harness to use spec file for build deps Jul 4, 2014
.mailmap add mailmap for cleaner shortlog output May 31, 2014
AUTHORS various enhancement to man pages Apr 24, 2013
COPYING added basic doc files Jul 21, 2009
HACKING make version comparison compat with python2 and python3 May 12, 2014
LICENSE added basic doc files Jul 21, 2009
MANIFEST.in Add more missing documentation to MANIFEST.in. Feb 27, 2014
README.md CentOS uses yum Jul 4, 2016
man.asciidoc resolve "[FIXME: manual]" in manpages Jul 22, 2011
mkdocs.yml Enable mkdocs and add documentation on Mead. Jun 12, 2015
releasers.conf.5.asciidoc Just a small typo Apr 23, 2016
runtests.py Clean up artifacts before test runs, not after Jan 9, 2017
setup.py Automatic commit of package [tito] release [0.6.9-1]. Jan 9, 2017
tito.8.asciidoc fixes #29 - remove --list-tags and --only-tags Jan 17, 2017
tito.props.5.asciidoc Fix typos in man pages Jan 2, 2017
tito.spec Automatic commit of package [tito] release [0.6.9-1]. Jan 9, 2017
titorc.5.asciidoc Allow a user specific Copr remote SRPM URL. Jul 24, 2015
tox.ini Add flake8 configuration. Fix style issues. May 18, 2015
wercker.yml use wercker instead of travis-ci to enable full test harness Apr 10, 2014



Tito is a tool for managing RPM based projects using git for their source code repository.

Tito offers the following features:

  • Tag new releases with incremented RPM version or release.
  • Auto-generate spec file changelog based on git history since last tag.
  • Create reliable tar.gz's with consistent checksums from any tag.
  • Build source and binary rpms off any tag.
  • Build source and binary "test" rpms off most recently committed code.
  • Build multiple source rpms with appropriate disttag's for submission to the Koji build system
  • Build rpms via the "mock" tool.
  • On a per-branch basis in git:
    • Maintain concurrent version streams.
    • Vary the way packages are built/tagged.
  • Report on any diffs or commits messages missing since last tag.
  • Define release targets to publish your packages to yum repositories, or the Fedora build system.
  • Define custom builder/releaser implementations for your own project needs.
  • Build packages off an "upstream" git repository, where modifications in the "downstream" git repository will be applied as a patch in the source rpm.
  • Manage all of the above for a git repository with many disjoint packages within it.



From Fedora:

dnf install tito

From CentOS / RHEL:

# Enable EPEL https://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_packages.3F
yum install tito

To install from source

git clone https://github.com/dgoodwin/tito.git
cd tito/
sudo yum install python-setuptools
./setup.py build
sudo ./setup.py install

To make an rpm of tito to install elsewhere

sudo yum install python-devel asciidoc
tito build --rpm
# see what's in the package
rpm -ql -p /tmp/tito/noarch/tito-*.noarch.rpm


From your git repository:

tito init

This will create a top-level metadata directory called ".tito/" and commit it to git. This directory will store tito's configuration and package metadata on a per branch basis. It will be filtered out when creating .tar.gz's.


Before doing most everything you'll need to tag your package(s).

Before doing this you'll need to ensure that your package spec files are at the top of the relative source tree for that package.

For the most common case, a single project git repository has the spec file and root of the project at the top level of the git repository:


For a multi-project git repository, packages can be defined in various sub-directories, provided they do not nest (i.e. walking up the tree, two spec files will never be encountered):


The packages can be organized in any hierarchy you like and even be moved around and re-tagged, we only need to have the spec file in the top level directory for that package.

Tagging packages is normally done with:

tito tag

This will:

  • bump the version or release in the spec file (use --keep-version to use whatever is defined in the spec file)
  • auto-generate a changelog from first line of each commit since last tag (use --no-auto-changelog if you do not want this)
  • open an editor allowing you a chance to edit that changelog
  • insert the changelog into your spec
  • commit these changes, and generate a git tag

By default if you omit --keep-version, tito will tag by bumping the rpm version. (i.e. we bump the Z in X.Y.Z. If you'd prefer to bump the package release instead (normally should just be used for changes to the spec file or patches applied within it), you can change the 'tagger' class in .tito/tito.props to ReleaseTagger. This will affect all packages in this git branch, if you'd prefer to do this on a per-package basis you can do so in a package specific tito.props. (see section below)

Once a package is tagged you will need to push both the auto-commit and the tag to your remote git repository before tito will let you build it. (better support for standalone git repositories is coming, for now --offline will help)

See "man tito" for more options.


To build the most recent .tar.gz for a package, cd into that packages directory and run:

tito build --tgz

Note that this tarball will have a consistent checksum every time.

Likewise the --srpm and --rpm options allow you to build both binary and source rpms.

Add in the --tag=TAG option to build any of the above for any past tag.

If you're working on something locally and would like to check that your package is still building ok without pushing your changes to the remote repository, add the --test option. This will build a test rpm from your most recently committed work. (NOTE: does not include uncommitted changes)

TODO: Document the use of --release, which is complicated and untested against Fedora's Koji.

See "man tito" for more options.


Tito supports a mechanism where you can define multiple release targets.

In .tito/releasers.conf, create a section like:

releaser = tito.release.YumRepoReleaser
builder = tito.builder.MockBuilder
builder.mock = fedora-15-x86_64
rsync = fedorapeople.org:/srv/repos/dgoodwin/tito/fedora-15/x86_64/

You can define as many release targets as you like with various configurations. To publish the most recently tagged build in your current branch you would run:

tito release yum-f15-x86_64

You can specify multiple targets on the CLI.

See "man 8 releasers.conf" for more information on defining release targets.

See "man tito" for more information on CLI arguments to "tito release".


If the existing implementations Tito provides are not sufficient for your needs, it is possible to define a lib_dir in tito.props globalconfig section. This is a directory that tito will add to the python path during execution, allowing you a place to define your own custom implementations of builders, taggers, and releasers.

The process of actually writing a custom Builder/Tagger/Releaser is an exercise left to the reader, but essentially you will want to work off the code in the tito.builder module. Inherit from the base Builder, and override the methods you need to.

Please note that if you store your custom implementations inside your source tree, they will need to be kept in sync in all branches you are using for consistent behavior. Also, there are no guarantees that tito will not change in future releases, meaning that your custom implementations may occasionally need to be updated.


If you create a tag accidentally or that you wish to re-do, make sure you have not git pushed the tag yet, the auto-commit is the most recent in your git history, and run:

git tag -d YOURNEWTAG
git reset --hard HEAD^1

If your project is standalone (no remote reference you communicate with as authoritative) you may wish to set offline = "true" in .tito/tito.props under the globalconfig section, so you do not need to specify --offline with each invocation.



man 5 tito.props

man 5 releasers.conf

man 5 titorc


How to create new release of RPM package in 5 seconds

How to build in Copr