第11章 Packaging with git

目次

11.1. Salsa repository
11.2. Salsa account setup
11.3. Salsa CI service
11.4. Branch names
11.5. Patch unapplied Git repository
11.6. Patch applied Git repository
11.7. Note on gbp
11.8. Note on dgit
11.9. Patch by gbp-pq approach
11.10. Manage patch queue with gbp-pq
11.11. gbp import-dscs --debsnap
11.12. Quasi-native Debian packaging
11.13. Git commit history organization

Up to 10章上級パッケージング, we focused on packaging operations without using Git or any other VCS. These traditional packaging operations were based on the tarball released by the upstream as mentioned in 「Historical perspective」.

Currently, the git(1) command is the de-facto platform for the VCS tool and is the essential part of both upstream development and Debian packaging activities. (See Debian wiki Debian git packaging maintainer branch formats and workflows for existing VCS workflows.)

[注記]注記

Since the non-native Debian source package uses diff -u as its backend technology for the maintainer modification, it can’t represent modification involving symlink, file permissions, nor binary data (March 2022 discussion on [email protected]). Please avoid making such maintainer modifications even though these can be recorded in the Git repository.

Since VCS workflows are complicated topic and there are many practice styles, I only touch on some key points with minimal information, here.

Salsa is the remote Git repository service with associated tools. It offers the collaboration platform for Debian packaging activities using a custom GitLab application instance. See:

There are 2 styles of branch names for the Git repository used for the packaging. See 「Branch names」.

There are 2 main usage styles for the Git repository for the packaging. See:

There are 2 notable Debian packaging tools for the Git repository for the packaging.

It is highly desirable to host Debian source code package on Salsa. Over 90% of all Debian source code packages are hosted on Salsa. [21]

The exact VCS repository hosting an existing Debian source code package can be identified by a metadata field Vcs-* which can be viewed with the apt-cache showsrc <package-name> command.

After signing up for an account on Salsa, make sure that the following pages have the same e-mail address and GPG keys you have configured to be used with Debian, as well as your SSH key:

Salsa runs Salsa CI service as an instance of GitLab CI for 「Continuous integration」.

For every git push instances, tests which mimic tests run on the official Debian package service can be run by setting Salsa CI configuration file debian/salsa-ci.yml file」 as:

---
include:
  - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml

# Customizations here

The Git repository for the Debian packaging should have at least 2 branches:

In this tutorial, old style branch names are used in examples for simplicity.

[注記]注記

This upstream-branch may need to be created using the tarball released by the upstream independent of the upstream Git repository since it tends to contain automatically generated files.

The upstream Git repository content can co-exit in the local Git repository used for the Debian packaging by adding its copy. E.g.:

[debhello] $ git remote add upstreamvcs <url-upstream-git-repo>
[debhello] $ git fetch upstreamvcs master:upstream-master

This allows easy cherry-picking from the upstream Git repository for bug fixes.

The patch unapplied Git repository can be summarized as:

The debian/source/local-options and debian/source/local-patch-header files are meant to be recorded by the git command. These aren’t included in the Debian source package.

  • This allows the extracted files from the generated Debian source package to be the patch-applied one suitable for NMU.
  • This also allows the recorded files outside of the debian/* directory in the git repository to be the patch-unapplied one without modification for easy history tracking.
[注記]注記

The focus of this introductory tutorial Guide for Debian Maintainers isn’t the patch applied Git repository which is rather a new trend. So minimal explanation is given here.

The patch applied Git repository can be summarized as:

  • The source tree matches extracted contents by dpkg-source -x of the Debian source package.

    • The source tree is buildable and the same as what NMU maintainers see.
    • The source is recorded in the Git repository with maintainer changes including the debian/ directory.
    • Maintainer changes to the upstream source are also recorded in debian/patches/* files for the Debian source format 3.0 (quilt).

Use one of workflow styles:

The gbp command is provided by the git-buildpackage package.

  • This command is designed to manage contents of 「Patch unapplied Git repository」」 efficiently.
  • Use gbp import-orig to import the new upstream tar to the git repository.

    • The --pristine-tar option for the git import-orig command enables storing the upstream tarball in the same git repository.
    • The --uscan option as the last argument of the gbp import-orig command enables downloading and committing the new upstream tarball into the git repository.
  • Use gbp import-dsc to import the previous Debian source package to the git repository.
  • Use gbp dch to generate the Debian changelog from the git commit messages.
  • Use gbp buildpackage to build the Debian binary package from the git repository.

    • The sbuild package can be used as its clean chroot build backend either by configuration or adding --git-builder='sbuild -A -s --source-only-changes -v -d unstable'
  • Use gbp pull to update the debian, upstream and pristine-tar branches safely from the remote repository.
  • Use gbp pq to manage quilt patches without using dquilt command.
  • Use gbp clone REPOSITORY_URL to clone and set up tracking branches for debian, upstream and pristine-tar.

Package history management with the git-buildpackage package is becoming the standard practice for many Debian maintainers. See more at:

The dgit command is provided by the dgit package.

The new dgit package offers commands interact with the Debian repository as if it was a git repository. It does not replace gbp-buildpackage and both can be used at the same time. Using plain gbp-buildpackage is recommended for developers who want to run git push/pull on Salsa and use things such as Salsa CI or Merge Requests on Salsa.

For more details see the extensive guides:

  • dgit-maint-merge(7) — for the Debian non-native package with its changes flowing both ways between the upstream Git repository and the Debian Git repository which are tightly coupled using 「Patch applied Git repository」.
  • dgit-maint-debrebase(7) — for the Debian non-native package with its changes flowing mostly one way from the upstream Git repository to the Debian Git repository using 「Patch applied Git repository」.
  • dgit-maint-native(7) — for the Debian native package in the Debian Git repository. (No maintainer changes)
  • dgit-maint-gbp(7) — for the Debian non-native package using source format 3.0 (quilt) with its Debian Git repository which is kept usable also for people using gbp-buildpackage(1) using 「Patch unapplied Git repository」.

The dgit(1) command can push the easy-to-trace change history to the https://browse.dgit.debian.org/ site and can upload Debian package to the Debian repository properly without using dput(1).

Here are some hints.

  • For a package already using dgit, start with dgit clone package to construct the git view of history for package.
  • For a package not yet using dgit but has its cloned git working tree, start with dgit setup-new-tree to configure the current working tree the way that dgit clone package would have set it up.
  • In order to keep the working tree dgit-compatible, delete debian/source/local-options if it exists.

Topics around dgit are beyond this tutorial document to cover them in depth. Please start reading relevant information:

For 「Patch unapplied Git repository」」, you can generate debian/patches/* files using the gbp-pq(1) command from git commits in the through-away patch-queue branch.

Unlike dquilt which offers similar functionality as seen 「Patch by dquilt approach」 and 「Manage patch queue with dquilt, gbp-pq doesn’t use .pc/* files to track patch state, but instead gbp-pq utilizes temporary branches in git.

You can add, drop, and refresh debian/patches/* files with gbp-pq to manage patch queue.

If the package is managed in 「Patch unapplied Git repository」」 using the git-buildpackage package, you can revise the upstream source to fix bug as the maintainer and release a new Debian revision using gbp pq.

  • Add a new patch recording the upstream source modification on the file buggy_file as:

    [debhello] $ git checkout master
    [debhello] $ gbp pq import
    gbp:info: ... imported on 'patch-queue/master
    [debhello] $ vim buggy_file
      ...
    [debhello] $ git add buggy_file
    [debhello] $ git commit
    [debhello] $ gbp pq export
    gbp:info: On 'patch-queue/master', switching to 'master'
    gbp:info: Generating patches from git (master..patch-queue/master)
    [debhello] $ git add debian/patches/*
    [debhello] $ dch -i
    [debhello] $ git commit -a -m "Closes: #<bug_number>"
    [debhello] $ git tag debian/<version>-<rev>
  • Drop (== disable) an existing patch

    • Comment out pertinent line in debian/patches/series
    • Erase the patch itself (optional)
  • Refresh debian/patches/* files to make dpkg-source -b work as expected after updating a Debian package to the new upstream release.

    [debhello] $ git checkout master
    [debhello] $ gbp pq --force import # ensure patch-queue/master branch
    gbp:info: ... imported on 'patch-queue/master
    [debhello] $ git checkout master
    [debhello] $ gbp import-orig --pristine-tar --uscan
      ...
    gbp:info: Successfully imported version ?.?.? of ../packagename_?.?.?.orig.tar.xz
    [debhello] $ gbp pq rebase
     ... resolve conflicts and commit to patch-queue/master branch
    [debhello] $ gbp pq export
    gbp:info: On 'patch-queue/master', switching to 'master'
    gbp:info: Generating patches from git (master..patch-queue/master)
    [debhello] $ git add debian/patches
    [debhello] $ git commit -m "Update patches"
    [debhello] $ dch -v <newversion>-1
    [debhello] $ git commit -a -m "release <newversion>-1"
    [debhello] $ git tag debian/<newversion>-1

For Debian source packages named <source-package> recorded in the snapshot.debian.org archive, an initial git repository managed in 「Patch unapplied Git repository」 with all of the Debian version history can be generated as follows.

[debhello] $ gbp import-dscs --debsnap --pristine-tar <source-package>

The quasi-native packaging scheme packages a source without the real upstream tarball using the non-native package format.

[ヒント]ヒント

Some people promote this quasi-native packaging scheme even for programs written only for Debian since it helps to ease communication with the downstream distros such as Ubuntu for bug fixes etc.

This quasi-native packaging scheme involves 2 preparation steps:

The rest is the same as the non-native packaging workflow as written in 「Packaging workflow」.

Although this can be done in many ways (「Snapshot upstream tarball」), you can use the Git repository and git deborig as:

[~] $ cd /path/to/debhello
[debhello] $ dch -r
  ... set its <version>-<revision>, e.g., 1.0-1
[debhello] $ git tag -s debian/1.0-1
[debhello] $ git rm -rf debian
[debhello] $ git tag -s upstream/1.0
[debhello] $ git commit -m upstream/1.0
[debhello] $ git reset --hard HEAD^
[debhello] $ git deborig
[debhello] $ sbuild

When your local Git commit history becomes intertwined, you need to organize it before pushing it out to the public.

The most simple organization process is to squash all changes to a single commit using git rebase -i. But this may create a huge illegible commit. Manually splitting the squashed commit using the splitdiff command from the patchutils is an option but may be quite cumbersome.

More fine grained organization process can use git rebase -i in combination with git add some_file and git commit. But this may be quite cumbersome.

For this task, the git ime command in the imediff package can help. It automatically splits a single commit with many files into multiple commits involving only a single file changes. When operating on a single file change commit, it interactively splits the commit into multiple commits of line changes. Invoking it with the --auto* option will automate this commit operation. Now you can manage changes interactively using git rebase -i. By using gitk on the working tree along this task, you get decent visibility over all commits.



[21] Use of git.debian.org or alioth.debian.org are deprecated now.