Translation(s): English - Deutsch - Italiano - Indonesian

Packaging with Git

This page describes how to use gbp (git-buildpackage) tools to set up and maintain Debian source packages in a git repository. After setting up such git repository (known as git packaging repository), later in this article also discusses how to build Debian binary packages directly out of existing git packaging repositories.

Note, that this is just a very general introductory guide. Full, official documentation can be found in the git-buildpackage package (see online documentation).

For help converting Subversion repositories created by svn-buildpackage to git, see the svn-buildpackage conversion subpage.

You should also read about pristine-tar support below.

This page describes the workflow using the commands from the git-buildpackage package. Alternatively there is also git-dpm and gitpkg.

Git branch naming

There is a standardized naming scheme for the branches used in packaging. It it described in DEP-14: Recommended layout for Git packaging repositories. This page follows that standard, but there are still many packages that do not. The most common old pattern is using master instead of debian/latest for the main packaging branch, and upstream instead of upstream/latest for the branch with the most recent upstream code.

Upstream import methods

There are two main ways to import the upstream code into the debianized repository:

There's also a third option, which is a combination of the two: gbp import-orig --upstream-vcs-tag. This is useful primarily when the orig tarball is not identical to the upstream release tag, which can happen if for instance

The various pros-cons are discussed here:

Getting started

Importing upstream as tarballs

It is easiest to first create the first version of a package, outside of Git. Once this is done, you should import the package using the import-dsc command of the gbp tool. Previously this was git-import-dsc. The directory in which it is called will be the parent directory of the new Git repository.

$ gbp import-dsc /path/to/package_0.1-1.dsc

This will give output of its progress and make a few commits. Afterwards, you will have some new files and directories:

$ ls

Looking in the new repository shows git-buildpackage (aka gbp) has done the following:

Using the upstream repo

If upstream is already using git, simply make a branch for the debianization. The conventions for names of branches and tags are as in the case just described, so one can branch debian/latest off of the upstream/latest release, and add the debian/ directory as a commit.

Further packaging workflow

Now you can work in the debian/latest branch to edit the package. Commit with:

$ git commit -a

and build the package with:

$ gbp buildpackage

Once you have produced a release-ready package, you should tag it, in the following way:

$ gbp buildpackage --git-tag

Make sure that your debian/changelog file is correct, as that is what will be used to create the tag. The tag will be named debian/0.1-2 where 0.1-2 is the Debian version.

Handling debian patches

The gbp-pq tool can be used to track patches in git, and to export/import them to/from the quilt series in debian/patches.

Upgrading to new upstream version

Importing upstream as tarballs

When a new upstream version comes out, use the import-orig command to add it to the repository. Previously this was git-import-orig.

Using a debian/watch file (recommended)

$ gbp import-orig --uscan

Using a tarball file

$ gbp import-orig /path/to/new-upstream.tar.gz -u 0.2

where 0.2 is the new upstream version number.

{i} If the upstream tarball is already in the form packagename_version.orig.tar.gz (E.g. package_0.2.orig.tar.gz), then the -u option is not required.

Using the upstream repo

If we're using the upstream repo, we can git fetch the new release tag into the repo, in the upstream/latest branch. We need to git merge this branch into debian/latest, and to commit the new tarball with pristine-tar. The patches can be rebased with gbp-pq, and git itself can be used to resolve any conflicts that have been created.

Merging a debian/experimental branch into debian/latest for sid

Lets assume you have have the following branches:


latest upstream in development


upstream's 1.5 series, considered stable


branch for building packages for sid


branch for building packages for experimental

At some point, you want to move the work from debian/experimental to the debian/latest branch and release it to unstable.

First, it is necessary to make sure debian/experimental has everything correct in debian/* - maybe you committed something on debian/latest and didn't cherry-pick it to debian/experimental. You can compare the debian/ subtrees like this:

git checkout debian/latest
git diff debian/experimental debian

If necessary, cherry pick any changes onto debian/experimental. The next merge will obliterate everything on debian/latest and replace it with the contents of the debian/experimental branch. The only thing that is kept is debian/changelog because it needs to reflect the change history within sid and does not need to contain details of individual releases to experimental. Here is how we do it (make sure debian/latest is a clean workspace):

git checkout debian/latest
git clean -fd && git checkout .
git merge -s ours debian/experimental
git diff --binary debian/experimental | git apply -R --index
git reset debian/changelog
git checkout debian/changelog
git commit -m 'Merge 1.6.0~rc1 from debian/experimental' --amend

After doing this, it is strongly suggested that you inspect the merge with gitk and with git diff before you push to salsa or any other developer. For example,

git diff debian/experimental

invoked in debian/latest should only show the changelog, because everything else on debian/latest should now be identical to debian/experimental.


That is all to the basics of maintaining source packages and building binary packages with Git! I would recommend making copies of packages and trying out the tools on temporary repositories, to start with. Once you feel you have mastered it, there are other options that should be looked at.

Further options


To use pbuilder for binary package building, you must simply change builder in either ~/.gbp.conf or /etc/git-buildpackage/gbp.conf to /usr/bin/git-pbuilder

{i} /usr/bin/git-pbuilder can be edited to use additional options, such as --builddir and --debsign-k...

Signing tags

On calling either of the git-import-dsc or git-import-orig tools, the following options may be used:


Whether to sign tags


With what OpenPGP key to sign tags with


git-buildpackage also supports the use of pristine-tar, a new tool developed by Joey Hess to recreate identical tarballs from a small delta file and the files in the current directory.

If you enable pristine-tar, delta files are committed to a pristine-tar branch if you call git-import-dsc or git-import-orig. When you build the package using gbp buildpackage, the exact tarball is regenerated using pristine-tar.

On calling either of the git-import-dsc or git-import-orig tools, the --pristine-tar option may be used. On calling gbp buildpackage, the --git-pristine-tar option may be used. You may also enable the pristine-tar option /etc/git-buildpackage/gbp.conf.

running lintian after the build

Add this to ~/.gbp.conf :

postbuild = lintian -I $GBP_CHANGES_FILE && echo "Lintian OK"

running autopkgtest after the build

First configure an environment for adt (see autopkgtest docs, man adt-run) Then add this to your ~/.gbp.conf :

postbuild = adt-run --changes $GBP_CHANGES_FILE --- schroot sid-amd64-sbuild; [ $? -eq 0 -o $? -eq 8 ]

The last check is there to avoid failure when there are no tests to run.

An example gbp.conf

builder = git-pbuilder
cleaner = fakeroot debian/rules clean
# Create pristine-tar on import
pristine-tar = True
# Run lintian to check package after build 
postbuild = lintian -iIE --pedantic $GBP_CHANGES_FILE && echo "Lintian OK"""

export-dir = ../build-area/

# Filter out unwanted files/dirs from upstream
filter = [
# filter the files out of the tarball passed to pristine-tar
filter-pristine-tar = True

filter = [

# ignore merge commit messages
git-log = --no-merges

See also