Kapitel 11. Packaging with git

# Kapitel 11. Packaging with git

Up to „Kapitel 10, Advanced packaging“, 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 „Abschnitt 10.1, „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.)

| Anmerkung
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 debian-devel@l.d.o). 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:

- „Abschnitt 11.1, „Salsa repository““
- „Abschnitt 11.2, „Salsa account setup““
- „Abschnitt 11.3, „Salsa CI service““

There are 2 styles of branch names for the Git repository used for the packaging. See „Abschnitt 11.4, „Branch names““.

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

- „Abschnitt 11.5, „Patch unapplied Git repository““
- „Abschnitt 11.13, „Patch applied Git repository““

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

- gbp(1) and its subcommands:

  - This is a tool designed to work mainly with „Abschnitt 11.5, „Patch unapplied Git repository““.
  - See „Abschnitt 11.9, „Note on gbp““.

- dgit(1) and its subcommands:

  - This is a tool designed to work mainly with „Abschnitt 11.13, „Patch applied Git repository““.
  - This contains a tool to upload Debian packages using the dgit server.
  - See „Abschnitt 11.14, „Note on dgit““.

## 11.1. Salsa repository

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.

## 11.2. Salsa account setup

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

- https://salsa.debian.org/-/profile/emails
- https://salsa.debian.org/-/user_settings/gpg_keys
- https://salsa.debian.org/-/user_settings/ssh_keys

## 11.3. Salsa CI service

Salsa runs Salsa CI service as an instance of GitLab CI for „Abschnitt 10.4, „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 „Abschnitt 6.13, „debian/salsa-ci.yml file““ as:

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

    # Customizations here

## 11.4. Branch names

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

- debian-branch to hold the current Debian packaging head.

  - old style: master (or debian, main, …​)
  - DEP-14 style: debian/latest

- upstream-branch to hold the upstream releases in the imported form.

  - old style: upstream
  - DEP-14 style: upstream/latest

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

| Anmerkung
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.

## 11.5. Patch unapplied Git repository

The patch unapplied Git repository can be summarized as:

- This seems to be the traditional practice as of 2024.

- The source tree matches extracted contents by „dpkg-source -x --skip-patches“ of the Debian source package.

  - The upstream source is recorded in the Git repository without changes.
  - The maintainer modified contents are confined within the debian/* directory.
  - Maintainer changes to the upstream source are recorded in debian/patches/* files for the Debian source format „3.0 (quilt)“.

- This repository style is useful for all variants of traditional workflows and gbp based workflow:

  - „Abschnitt 5.7, „Schritt 3: Anpassung der Vorlagendateien““ (no patch)

  - „Abschnitt 5.10, „Patch by „diff -u“ approach““

    - debian/patches/* files can also be generated using „git format-patch“, „git diff“, or „gitk“ from git commits in the through-away maintainer modification branch or from the upstream unreleased commits.
  - „Abschnitt 5.11, „Patch by dquilt approach““ including the last „dquilt pop -a“ step
  - „Abschnitt 11.6, „Patch by „gbp-pq“ approach““

- Use helper scripts such as dquilt(1) and gbp-pq(1) to manage data in debian/patches/* files.

  - Add .pc line to the ~/.gitignore file if dquilt is used.
- Use „dpkg-source -b“ to build the Debian source package.
- Use dput(1) to upload the Debian source package.

## 11.6. Patch by „gbp-pq“ approach

For „Abschnitt 11.5, „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 „Abschnitt 5.11, „Patch by dquilt approach““ and „Abschnitt 9.5, „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.

## 11.7. Manage patch queue with gbp-pq

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

If the package is managed in „Abschnitt 11.5, „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

## 11.8. gbp import-dscs --debsnap

For Debian source packages named „<source-package>“ recorded in the snapshot.debian.org archive, an initial git repository managed in „Abschnitt 11.5, „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>

## 11.9. Note on gbp

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

- This command is designed to manage contents of „Abschnitt 11.5, „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:

- „Building Debian Packages with git-buildpackage“
- „4 tips to maintain a “3.0 (quilt)” Debian source package in a VCS“
- The systemd packaging practice documentation on „Building from source“
- The workflow mentioned in dgit-maint-gbp(7) which enables to use this gbp with dgit

## 11.10. The Git repository browser

The gitk command in the gitk package displays changes in a repository or a selected set of commits. This includes visualizing the commit graph, showing information related to each commit, and the files in the trees of each revision.

This gitk command also provides very intuitive UI to many cumbersome operations of the „git“ command such as „git checkout …​“, „git reset* …​“, „git diff …​“, etc..

## 11.11. Git commit history organization

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“ interactively.

But this may create a huge commit with files such as auto-generated files not intended to be committed. You can drop such files in the commit using „git rm some_file“ and „git commit --amend“. This may be quite cumbersome.

This cumbersome drop process can be eased by using the „git-ime“ command in the imediff package. It automatically splits a single commit with many files into multiple commits involving only a single file changes. Now you can drop such files using „git rebase -i“ interactively.

| Tipp
The „git-ime“ operating on a single file change commit splits it into multiple commits of line changes using imediff interactively. Invoking this with the --auto option will automate this split commit operation. See git-ime(1) and imediff(1).

## 11.12. Quasi-native Debian packaging

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

| Tipp
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:

- Organize its source tree almost like native Debian package (see „Abschnitt 6.4, „Natives Debian-Paket““) with debian/* files with a few exceptions:

  - Make debian/source/format to contain „3.0 (quilt)“ instead of „3.0 (native)“ .
  - Make debian/changelog to contain version-revision instead of version .

- Generate missing upstream tarball preferably without debian/* files.

  - For Debian source format „3.0 (quilt)“, removal of files under debian/ directory is an optional action.

The rest is the same as the non-native packaging workflow as written in „Abschnitt 6.1, „Arbeitsablauf des Paketierens““.

Although this can be done in many ways, 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

## 11.13. Patch applied Git repository

| Anmerkung
The focus of this introductory tutorial „Guide for Debian Maintainers“ isn’t the patch applied Git repository which is rather a new trend initiated by the proponent of the dgit command. 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)“.

## 11.14. Note on dgit

The dgit command is provided by the dgit package.

- This command enables to access the Debian package repository as if it were a git remote repository.

- This command offers tools to manage Debian packaging activities mainly using „Abschnitt 11.13, „Patch applied Git repository““.

  - No more convoluted operations to manage patch files in the debian/patches directory.
- Use „dgit build-source“ or „dgit sbuild“ to build the Debian source-only or source+binary package.
- Use „dgit push-source“ or „dgit push-build“ for uploading the Debian source-only or source+binary package via the dgit server.
- Use git-deborig(1) to produce Debian package.orig.tar.xz from the upstream version in debian/changelog.

| Tipp
The dgit server is browsable at https://browse.dgit.debian.org/ site.

| Anmerkung
In order to keep the working tree dgit-compatible, delete debian/source/local-options and debian/source/local-patch-header if they exist.

Hints for workflow styles:

- dgit-maint-merge(7) workflow.

  - Use this for the Debian non-native package without granular topic patches recorded in the Debian source package.

    - Good enough for packages only with trivial modifications to the upstream.
    - Only choice for packages with intertwined modification histories to the upstream.

  - Add auto-commit and single-debian-patch lines in the debian/source/options file

    - No granular topic patches recorded inside of the Debian source package.
  - Use „git checkout upstream; git pull“ to pull the new upstream commit and use „git checkout master ; git merge <new-version-tag>“ to merge it to the master branch.
  - See „Abschnitt 5.12, „Patch by „dpkg-source --auto-commit“ approach““ for example.

- dgit-maint-debrebase(7) workflow.

  - Use this for the Debian non-native package with granular topic patches recorded in the Debian source package.
  - Use the git-debrebase(1) command to maintain series of Debian changes to upstream source.

- dgit-maint-native(7) workflow,

  - Use this for the Debian native package in the Debian Git repository. (No maintainer changes)

- dgit-maint-gbp(7) workflow

  - Use this for the Debian non-native package using source format „3.0 (quilt)“ with its Debian Git repository which had been using gbp-buildpackage(1) with „Abschnitt 11.5, „Patch unapplied Git repository““.

This author likes this new dgit command and just started to use it with dgit-maint-merge(7) and dgit-maint-native(7) workflows. Thus, topics around dgit are beyond this tutorial document to cover in depth. Please start reading the latest relevant manpages and upstream resources:

- „dgit: use the Debian archive as a git remote (2015)“
- „tag2upload (2023)“

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

Kapitel 10. Advanced packaging |  | Kapitel 12. Tipps