Debian Perl Group Git Guide

This guide describes the procedures that the Debian Perl Group contributors use to maintain packages in the Git repositories on git.debian.org.

It will describe how to upload an initial package, how to update the packages, how to build them, how to upgrade them, and how to get all packages with mr(1).

The guide is a work in progress. Different people tend to do things in different ways. If your way diverges, you may want to document it here so that others can benefit. Please send any comments or ideas to <debian-perl@lists.debian.org>.

For a more general guide to Git, see the Git User's Manual at http://www.kernel.org/pub/software/scm/git/docs/user-manual.html.


The Tools

If you just want to work on an individual package maintained by the Debian Perl Group, you need the following packages installed (the versions in squeeze will work fine for this case):

Each package has its own git repo. If you are working with multiple packages maintained by the Debian Perl Group, then you will probably want to use mr(1) to manage the multiple git repos involved. For this workflow, you'll need the following packages installed:


Packaging walkthrough

starting a new package

the "all-in-one" approach

Since version 0.73 dh-make-perl has the --vcs git option, which will make it populate a Git repository with upstream and pristine-tar branches, and will setup an origin remote pointing to alioth, etc.

    $ dh-make-perl [option…] --cpan Foo --vcs git

adding Git stuff manually

git-import-dsc is used to introduce the source of a package into the Git repository. It operates on the .dsc file and the associated source files. It checks in the package and upstream code in the Git repository.

Example of starting a new package from scratch:

    $ dh-make-perl [option...] --cpan Foo
    ...
    $ mkdir libfoo-perl
    $ cd libfoo-perl
    $ git init
    $ git-import-dsc --pristine-tar ../libfoo-perl_1.23-1.dsc

If the package is already in Debian and you want to add a bit of history to the repository, repeat the last command for all .dsc files you have, in incremental version order. Alternatively you could use git-import-dscs.

Note that dh-make-perl(1) has many options to make your life easier.

Attention: git-import-dsc(1) adds a debian/$version tag. This one should not be pushed for new packages (but deleted, and later created after the first upload).

An alternative for a new package, as described in http://www.eyrie.org/~eagle/notes/debian/git.html ("Importing a package" -> "If you're instead starting from scratch ..."), is to create a new empty repository and then use git-import-orig(1) and dh-make-perl(1).

If your package does not have a .dsc file you can use

    $ git-import-orig --pristine-tar ../libfoo-perl_1.23-1.tar.gz

work with existing packages

cloning a single package repository

This can be done with plain git-clone(1), but using gbp-clone(1) will setup tracking branches for upstream sources and pristine-tar data:

    $ gbp-clone --all --pristine-tar ssh://git.debian.org/git/pkg-perl/packages/libfoo-perl.git

track all repositories on Alioth with mr(1)

Add the following to your (existing or new) ~/.mrconfig:

    [src/pkg-perl/git]
    chain = true
    checkout = git clone ssh://git.debian.org/git/pkg-perl/meta.git git

Note 1: The path has to be under the place of the .mrconfig file, otherwise it won't work; i.e. [/tmp/foobar] in ~/.mrconfig is a bad idea. (Might have changed in mr(1) 1.06 according to the changelog.)

Note 2: The last part of the path has to be the same as the target of the clone command (in this example: 'git').

Then add ~/src/pkg-perl/git/.mrconfig to ~/.mrtrust, otherwise the chain feature doesn't work.

Now run mr up which will clone the meta repository, which contains another .mrconfig with some features and some helper scripts.

A second invocation of mr up will then clone all the repositories mentioned in meta's .mrconfig, i.e. all pkg-perl git repositories in /git/pkg-perl/packages on git.debian.org.

For the adventurous:

    mr --trust-all bootstrap ssh://git.debian.org/git/pkg-perl/meta.git

probably does the same.

repository layout

Upstream sources are kept (in plain, uncompressed form) in the upstream branch. The original source tarballs are kept with the help of the pristine-tar(1) tool in the pristine-tar branch. The merge of the upstream sources and Debian-related changes is in the master branch, which is the usual place to work in.

From this point on, work on the package normally. Some prefer to update debian/changelog with each commit, others leave this to the git-dch(1) tool at package release time. In case you use git-dch(1) for the changelog entries, don't forget to use it when you stop working on the package.

pushing to git.debian.org

the easy way

The first time:

    $ ../../alioth-git-repo

This will ssh to alioth, run setup-repository there with the right arguments, then push the local repository over there.

From then on, just use git push --all && git push --tags as usual or use mr(1) for committing, which also pushes the changes to the original repository on alioth, mimicking the subversion commit behaviour at the expense of the ability to make amends, squashes and splits of commits (you still have to push any non-active branches or tags via git push).

the long story

Before pushing to git.debian.org for the first time, an empty repository needs to be created there. To do this, use the setup-repository script available in the /git/pkg-perl directory. Run it similarly to:

    $ ssh git.debian.org
    $ cd /git/pkg-perl
    $ ./setup-repository libfoo-perl 'Packaging of FOO in Debian'

This will create an empty, bare, shared Git repository and setup some hooks.

Each package is kept in its own Git repository. We don't use git-submodules.

Now, on your local machine add the alioth repository as a remote:

    $ git remote add origin ssh://git.debian.org/git/pkg-perl/packages/libfoo-perl.git

Then push to it:

    $ git push --all --set-upstream
    $ git push --tags

The --set-upstream option helps future use of git pull.

building the package

Use your favourite way of building the Debian package. If the source tarball is not in ../, check it out from the pristine-tar info (not needed if you use git-build-package(1) with the settings mentioned in Tips & tricks below):

    $ pristine-tar checkout ../libfoo-bar-perl_1.23_orig.tar.gz

(or ../../scripts/pristine-orig, which figures out the package name and version from debian/changelog.)

This requires that you have the pristine-tar current (e.g. via git fetch or gbp-pull(1)).

After uploading, tag the release. The easiest way is to use debcommit(1)

    $ debcommit -a -r

Push the result afterwards:

    $ git push
    $ git push --tags

upgrading to a new upstream release

First make sure that the local repository is up to date, for example using gbp-pull(1).

If the Debian package has a debian/watch file you can use the uscan(1) tool to check for the latest upstream release and download it:

 $ uscan

This will download the latest tarball in ../ and symlink it to the proper .orig.tar.gz (you can use the --rename options of uscan to directly rename the tarball without symlinking). If the watch file is not present you have to download the tarball manually.

Then import the new upstream release in the git repository:

 $ git fetch origin upstream:upstream pristine-tar:pristine-tar
 $ git-import-orig --pristine-tar ../libfoo-bar-perl_2.00_orig.tar.gz

This will import the new sources in the upstream branch, update tarball info in the pristine-tar branch, tag the upstream release and finally merge that tag in the master branch. It would also update debian/changelog.

git-import-orig(1) has also a --uscan option:

(Before using it, check if branch upstream exist with git branch. It it does not exist create it with git branch upstream command or you will get an error.)

 $ git-import-orig --uscan --pristine-tar

Attention: don't use git-import-orig --uscan for repacked tarballs as long as http://bugs.debian.org/635920 is not fixed.

This combines the previous two steps in a single command.

Create a new debian/changelog stanza about the new upstream release:

 $ dch -v2.00 'New upstream release'

Can be automated by the following configuration in ~/.gbp.conf:

 [git-import-orig]
 # run hook after the import:
 postimport = git-dch -N%(version)s -S -a --debian-branch=$GBP_BRANCH

Commit the changes so far:

 $ debcommit -a -m'new upstream release 2.00'

Don't forget to share your work when ready:

 $ git push --all
 $ git push --tags


Patches

quilt(1) does a fine job managing patches, especially if using the 3.0 (quilt) source format. See http://pkg-perl.alioth.debian.org/howto/quilt.html for a guide. gbp-pq(1) can be used for treating the patches as a series of commits. See https://honk.sigxcpu.org/piki/development/debian_packages_in_git/


Branches

From time to time, there is a need to work in a branch for a stable update or a security fix. Things are simple:

First create a branch from the tag that represents the version currently in the archive:

    $ git branch squeeze debian/2.40-5
    $ git checkout squeeze

or, with one command

    $ git checkout -b squeeze debian/2.40-5

If the squeeze branch already exists, check it out and merge the version currently in the archive:

    $ git checkout squeeze
    $ git merge debian/2.40-5

From this point on, work normally in the squeeze branch, build, tag and push.


Mass changes

For changes across many repos. - Just do them and

    $ mr commit

from within the top directory of the repositories.

Note: Our global ~/.mrconfig redefines mr commit to not push to the repositories (The default for mr is to push on mr commit).

Note: After commiting now push to the git repositories. Before doing so disable the KGB notifications on vasks. touch /home/groups/pkg-perl/KGB-notifications-disabled.

    $ ssh vasks.debian.org 'touch /home/groups/pkg-perl/KGB-notifications-disabled'

push the changes and then re-enable the KGB notifications.

    $ ssh vasks.debian.org 'rm /home/groups/pkg-perl/KGB-notifications-disabled'

This for now has to be done by hand until we have a way to disable them dynamically on mass commits.


Commit policy

single change per commit

This is true for any VCS, but it won't hurt saying it again: Please include only one change in each commit. git-gui(1)'s ability to stage single lines (or hunks) is a huge help if you have done several unrelated changes in the sources.

changelog maintenance

Some prefer to update debian/changelog with each commit, while others prefer to do that only at release time by using git-dch(1). There is no policy yet about which method to recommend, so please state your preference and reasoning by replying to http://lists.debian.org/msgid-search/20110801153235.GD8289@PC-Ale.fastwebnet.it.


Removing packages

When there is need to remove a package from the group you can either remove it completely (if added without never beeing released) or move it to attic. It can be done by using remove-repository on vasks.


Tips & tricks

git-buildpackage(1) has a configuration file which can save some typing on each command. The pristine-tar option is particularly handy.

An example of configuration file:

 [DEFAULT]
 pristine-tar = True
 sign-tags = True

This may be stored for example in ~/.gbp.conf (per user configuration), in debian/gbp.conf (per branch configuration) or in .git/gbp.conf (per repository configuration).

If using the 3.0 (quilt) source format may also be handy to add the .pc directory to the .gitignore file. To do this globally, you may use the following:

 git config --global --add core.excludesfile ~/.gitignore
 echo '/.pc/' >> ~/.gitignore

(If you have a Git repository in your home, you may want to change ~/.gitignore above).


Caveats

Git is detached. This is very good, when you prefer to work mainly offline or on the road. The problem is not to forget to publish your work at some point in time :)

Various shell hooks that change the prompt may be of help.


Authors


License

Copyright (c) 2010-2011 by the individual authors and contributors noted above. All rights reserved. This document is free software; you may redistribute it and/or modify it under the same terms as Perl itself

Perl is distributed under your choice of the GNU General Public License version 1 or later or the Artistic License. On Debian systems, the complete text of the GNU General Public License version 1 can be found in `/usr/share/common-licenses/GPL-1' and the Artistic License in `/usr/share/common-licenses/Artistic'.