First, I'm not a Debian maintainer, I mostly do some package for my
personal use, to follow SVN trunk or git HEAD of some softwares.

As I use Debian, I do not want to "make install" things ;-).

I attach[1] a rough document about my actual uses of git for debian
packaging and post it here for comments.

There are some items about which I would like to discuss, like:

- automatic handling of debia/changelog

- multi-distributions/version packaging (and avoiding conflicts)

- automatic build of packages

- management of orig.tar.gz

I already read some maling-list archives, mostly the "Patch mgmt
workflow proposal" plus the links givent in the thread, but the
conversations are way to high for me.

I read the Debian wiki[2] plus its links, I like Russ Allbery page[3],
it's a real life example[4].


[1]  I need to setup some web access to my git repositories ;-)

[2]  http://wiki.debian.org/PackagingWithGit/

[3]  http://www.eyrie.org/~eagle/notes/debian/git.html

[4] Thanks for the trick to split a upstream/debian combined source

Daniel Dehennin
Récupérer ma clef GPG:
gpg --keyserver pgp.mit.edu --recv-keys 0x6A2540D1

#+TITLE: Manage Debian packaging with git
#+AUTHOR: Daniel Dehennin

* Introduction

This documentation is based on my personal packaging of the
enlightenment display manager: elsa.

It's code can be found in the enlightenment [[http://svn.enlightenment.org/svn/e/trunk/PROTO/elsa][SVN repository]].

* git-buildpackage workflow

My current usage is [[https://honk.sigxcpu.org/piki/projects/git-buildpackage/][git-buildpackage]] oriented:

- One branch is upstream
- One branch is patches to upstream sources
- One branch is packaging

Upstream is mostly VCS based, I do not use the [[http://kitenet.net/~joey/code/pristine-tar][pristine-tar]] mechanism.

My first use was to package SVN/git snapshot of some softwares like
cfengine3, gnus and elsa.

For convention I always use a dedicated mirror of upstream branch, in
which I only pull from upstream.

Another convention is to always prepend my trigraph (=dad/=) to my

The basic setup is the following:

- Upstream branch is under =upstream/= and reflect the VCS used by
  upstream: =upstream/svn/trunk= or =upstream/git/master=
- Packaging: =dad/debian/snapshot=
- Patches to upstream: =patch-queue/dad/debian/snapshot=

** git-buildpackage configuration

I use one global full git-buildpackage configuration, stored
in =~/.gbp.conf= and one minimal configuration per packaging.

The following is my default, I use pbuilder to keep a clean
workstation and track dependency problems.

#+begin_src conf
  # Configuration file for git-buildpackage and friends
  # Where I track upstream
  upstream-branch = upstream
  # Branch I use to build package
  debian-branch = debian/snapshot
  # the default tag formats used:
  upstream-tag = upstream/%(version)s
  debian-tag = debian/%(version)s
  # Use a clean environment to build
  # Need some setup with sudo cowbuilder --create
  builder = /usr/bin/git-pbuilder
  # Use color when on a terminal, alternatives: on/true, off/false or auto
  color = auto
  # Look for a tag matching the upstream version when creating a tarball
  upstream-tree = tag
  # Sign tags by default:
  sign-tags = True
  # Sign after the build, required because of cowbuilder
  postbuild = debsign ${GBP_CHANGES_FILE}
  # Let the working tree clean
  # Transparently handle submodules
  # submodules = True
  # Use my git identity
  git-autor = True
  # Merge the commits by maintainer
  multimaintmerge = True
  # Do not use merge log
  git-log = --no-merges
  # Parse meta tags like Closes: from commit messages
  meta = True
  # Add seven digits of the commits sha1 to the commit message
  # Regex for matching bugs to close
  meta-closes = Closes|LP|BZ|Fixes|fixes
  # Use the full commit message instead of the first line only
  full = True
  # Ignore these in commit messages
  ignore-regex = (git-svn-id|(Signed-off|Acked)-by):

** Setup a new package

*** Base is upstream repository

As I do not use pristine-tar, everything is based on the upstream
version control repository.

If upstream do not use git, you must look for a plugin to make the mapping.

Actually I tested following SVN and bzr repository, I may write some
separate documentations about this but for the moment I just show how
to start from SVN and git.

**** SVN upstream

#+begin_src sh
  dad@home:~/src/$ git svn clone --prefix=upstream/svn/trunk http://svn.enlightenment.org/svn/e/trunk/PROTO/elsa && cd elsa
  dad@home:~/src/elsa$ git branch upstream/svn/trunk upstream/svn/trunk

**** Git upstream

#+begin_src sh
  dad@home:~/src git clone http://git.gnus.org/gnus.git && cd gnus
  dad@home:~/src/gnus$ cd gnus && git branch upstream/git/master

*** A branch for debian packaging

My fist task is to create a dedicated branch to manage the packaging:

#+begin_src sh
  dad@home:~/src/elsa$ git checkout -b dad/debian/snapshot

Next, I create the mapping between =upstream=, =patch-queue= and
=debian=, as it is stored per debian branch I can have several debian
packaging, for several debian based distribution with several upstream

#+begin_src conf
  # Per debian package configuration
  # It is just used to map upstream/debian
  # Where I track upstream
  upstream-branch = upstream/svn/trunk
  # Branch I use to build package
  debian-branch = dad/debian/snapshot
  # the default tag formats used:
  upstream-tag = upstream/svn/snapshot/%(version)s
  debian-tag = debian/snapshot/%(version)s

We need to do some more things for this first packaging:

**** Make a tag for snapshot

git-buildpackage is now [[http://bugs.debian.org/cgi-bin/bugreport.cgi?bug%3D635883][tag based]], create one for upstream:

#+begin_src sh
  dad@home:~/src/elsa(dad/debian/snapshot)$ git tag -s -m "upstream/svn/snapshot/$(date +%Y%m%d)" "upstream/svn/snapshot/$(date +%Y%m%d)" upstream/svn/trunk

**** Create an orig.tar.gz

The tool to debianize, dh_make, need an orig.tar.gz, we build one from
the upstream tag:

#+begin_src sh
  dad@home:~/src/elsa(dad/debian/snapshot)$ git archive -o "../elsa_$(date +%Y%m%d).orig.tar.gz" --prefix "elsa-$(date +%Y%m%d)/" upstream/svn/snapshot/20111103

**** Create a base packaging layout

This is a simple step to have an initial, mostly garbage =debian/=

#+begin_src sh
  dad@home:~/src/elsa(dad/debian/snapshot)$ dh_make -p elsa_$(date +%Y%m%d) -c gpl3 -s -r cdbs -e $(git config user.email)
  dad@home:~/src/elsa(dad/debian/snapshot)$ git add debian/
  dad@home:~/src/elsa(dad/debian/snapshot)$ git commit -m "dh_make templates"

**** First debian packaging

You need to modify many files under the =debian/= directory before
building your first package.

Do not forget to commit often small changes, it's cleaner and easier to follow the

During the packaging, you can let =git-dch= edit your
=debian/changelog= with all the commits relatives to the packaging
since you tagged the upstream version:

#+begin_src sh
  dad:~/src/elsa(dad/debian/snapshot)$ git-dch -a debian/
  gbp:info: Changelog last touched at '4c1ffb57bde0130fcdd5f5c5f596e20eff1299eb'
  gbp:info: Continuing from commit '4c1ffb57bde0130fcdd5f5c5f596e20eff1299eb'
  gbp:info: Only looking for changes on 'debian/'

You can repeat the =git-dch -a debian/= call but you need to commit after
each change to =debian/changelog= or you will have some duplication in

*** A branch to patch upstream source for packaging needs

If you need to patch the upstream sources, you must do it with
patches under =debian/patches= with =debian/source/format= as "3.0
(quilt)" (the default under debian sid at the time of writing).

I use a patch queue branch to track the =debian/patches/*patch= files,
this branch does not need to be published as everyone can build it
From =debian/patches/*patch=

#+begin_src sh
  dad@homme:~/src/elsa$ gbp-pq import

Every commit in this branch became a patch under =debian/patches/=
directory, the commit message as patch comment.

*** Building and tagging

When you are done with the packaging you need to build the

#+begin_src sh
  dad@home:~/src/elsa(dad/debian/snapshot)$ git buildpackage

And if the packaging is ok, you can tag your debian release, it will
be used firstly by =git-dch= when creating a new entry.

#+begin_src sh
  dad@home:~/src/elsa(dad/debian/snapshot)$ git buildpackage --git-tag-only
  dad@home:~/src/elsa(dad/debian/snapshot)$ git tag -l

** Make a new debian version

1. I update the branch =upstream/svn/trunk= using =git svn rebase=
   #+begin_src sh
     dad@home:~/src/elsa(master)$ git checkout upstream/svn/trunk
     dad@home:~/src/elsa(upstream/svn/trunk)$ git svn rebase

2. I merge it with the packaging branch
   #+begin_src sh
     dad@home:~/src/elsa(upstream/svn/trunk)$ git checkout dad/debian/snapshot
     dad@home:~/src/elsa(dad/debian/snapshot)$ git merge upstream/svn/trunk

3. I update the patches (if any) by rebasing them and resolve any conflicts:
   #+begin_src sh
     dad@home:~/src/elsa(dad/debian/snapshot)$ gbp-pq rebase

4. I then export them (if any) to the packaging branch:
   #+begin_src sh
     dad@home:~/src/elsa(patch-queue/dad/debian/snapshot)$ gbp-pq export
     dad@home:~/src/elsa(dad/debian/snapshot)$ git commit -m "Rebase patches to upstream sources."

5. I update the =debian/*= files to make the packaging working, like
   new dependencies

6. I update the =debian/changelog= to make a new version:
   #+begin_src sh
     dad@home:~/src/elsa(dad/debian/snapshot)$ git-dch -a -N $(date "+%Y%m%d-1") debian/

7. Finalize the =debian/changelog= and then commit.

8. Build the new package:
   #+begin_src sh
     dad@home:~/src/elsa(dad/debian/snapshot)$ git buildpackage

9. Tag the package if it's OK.
   #+begin_src sh
     dad@home:~/src/elsa(dad/debian/snapshot)$ git buildpackage --git-tag-only

* Tasks

** TODO Do not manage =debian/changelog= in the packaging branch

The idea is to permit the merge between several debian packaging
branches, the =debian/changelog= file should be updated in its own
branch, a build branch.

This requires:

- a new sublevel of branching to maintain several packaging
  - =/dad/debian/snapshot/master=
  - =/dad/debian/snapshot/build=

- Modification of =debian/gbp.conf=

#+begin_src conf
  # Per debian package configuration
  # It is just used to map upstream/debian
  # Where I track upstream
  upstream-branch = upstream/svn/trunk
  # Branch I use to build package
  debian-branch = dad/debian/snapshot/build
  # the default tag formats used:
  upstream-tag = upstream/svn/snapshot/%(version)s
  debian-tag = debian/snapshot/%(version)s

Then the new git snapshot workflow looks like this:

#+begin_src sh
  dad@home:~/src/elsa(master)$ git checkout upstream/svn/trunk
  dad@home:~/src/elsa(upstream/svn/trunk)$ git svn rebase
  dad@home:~/src/elsa(upstream/svn/trunk)$ git tag -s -m  "upstream/svn/snapshot/$(date +%Y%m%d)" "upstream/svn/snapshot/$(date +%Y%m%d)"
  dad@home:~/src/elsa(upstream/svn/trunk)$ git checkout dad/debian/snapshot/master
  dad@home:~/src/elsa(dad/debian/snapshot/master)$ git merge upstream/svn/trunk
  dad@home:~/src/elsa(dad/debian/snapshot/master)$ gbp-pq rebase
  dad@home:~/src/elsa(patch-queue/dad/debian/snapshot/master)$ gbp-pq export
  dad@home:~/src/elsa(dad/debian/snapshot/master)$ git add debian/patches/
  dad@home:~/src/elsa(dad/debian/snapshot/master)$ git commit -m "Rebase patch to upstream"
  dad@home:~/src/elsa(dad/debian/snapshot/master)$ git checkout dad/debian/snapshot/build
  dad@home:~/src/elsa(dad/debian/snapshot/build)$ git merge dad/debian/snapshot/master
  dad@home:~/src/elsa(dad/debian/snapshot/build)$ git-dch -a -N $(date "+%Y%m%d-1") debian/
  dad@home:~/src/elsa(dad/debian/snapshot/build)$ git commit -m "New debian snashot package"
  dad@home:~/src/elsa(dad/debian/snapshot/build)$ git buildpackage
  dad@home:~/src/elsa(dad/debian/snapshot/build)$ git buildpackage --git-tag-only

** TODO Use =dist/= prefix for packaging

*** For sid

- =dist/debian/sid/master=
- =dist/debian/sid/build=

*** For wheezy

- =dist/debian/wheezy/master=
- =dist/debian/wheezy/build=

*** For snapshot

- =dist/debian/snapshot/master=
- =dist/debian/snapshot/build=

*** For oneiric

- =dist/ubuntu/oneiric/master=
- =dist/ubuntu/oneiric/build=

** TODO Automatic build

My idea is to build a new package each time I create a new specific
tag, the debian/changelog should be handled automatically.

This requires:

- Testing the packaging locally before tagging the package version
  with a specific "to-release"/"to-build" tag

- This tag must be different than the debian-tag, this one is used to
  mark a builded/uploaded package with (the changelog)

- Something to do the work, somewhere, when a new "to-release" tag appears:

    1. Checkout the build branch from the last "release" tag

    2. Merge the "to-release" tag in the build branch, with automatic
       =debian/changelog= generation, this should not give conflicts

    3. Update the =debian/changelog= and commit

    4. Generate the orig.tar.gz, debian.tar.gz and dsc

    5. Give item 4. production to some building processes

Attachment: pgpo48sNII1Qt.pgp
Description: PGP signature

vcs-pkg-discuss mailing list

Reply via email to