I use the Bazaar VCS for tracking all my package work. This workflow should function well in any modern DVCS, though terminology differences are inevitable.

The proposed patch management workflow in this document has many similarities with git-pq. It differs in these points:

For the purpose of this document, the master branch is the branch where /debian/ lives. Others like to call this branch e.g. "debian".

Short overview

This is how Martin F. Krafft summarized this proposal:

  1. you develop your features on branches, but you do not push the branch heads;
  2. the feature branches get merged into an integration/build branch, which is pushed. This way, all contributors get the commits;
  3. as part of the build process, the feature branches are exported to a debian/patches series, and each patch file includes additional information, such as dependency data, and also the SHA-1 of the feature branch head at the time when the patch was made;
  4. at a later stage, when someone wants to edit a patch, they can create a branch off the SHA-1, merge the branch into the build branch and provide the updated patch (with updated SHA-1), or just provide an updated patch file and let the maintainer update the branch with an interdiff.

One of the points Martin disliked was the merge of the patches in the integration branch. I pointed out an alternative:

As a variation of the described workflow you can establish a special branch that holds references to all feature branch commits in its history. The content of this branch does not matter. A status command should warn you if the head of any feature branch is not in the history this special branch. Another command could create a new commit in this special branch with the parent pointing to all new heads.

Most basic workflow, without patches, sane upstream

|  master
|  |
| /* merge, new debian version (n commits)
|/ |
*  | new upstream version 
|  |
|  * debianize, debian release (n commits)
| /
* import upstream

Upstream needs clean up to be dfsg compliant

|  dfsg_clean
|  |
|  |  master
|  |  |
|  |  * new debian version 
|  | /|
|  |/ |
|  *  | merge, clean up (n commits)
| /|  |
|/ |  |
*  |  | import new unmodified upstream
|  |  |
|  |  * debianize, debian release
|  | /
|  |/
|  * merge, clean up (n commits)
| /
* import unmodified upstream

Patches, dfsg free upstream

principles, requirements, concepts



Creating patches:

  1. Checkout patch branch from upstream (or from the branch it depends on).
  2. Hack, commit
  3. Create an annotated quilt patch from the patch branch
  4. repeat the above for other patch branches
  5. merge the patch branches into the build branch
  6. Once the patches are merged in the build branch, the patch branches can be deleted.

Editing patches:

  1. Recreate the patch branches with informations from the quilt annotations
  2. Hack, commit
  3. update quilt files
  4. merge updated patch branches into build branch

Update upstream:

  1. Import upstream, merge into master
  2. recreate the patch branches
  3. either merge upstream changes into each patch branch or rebase patch branches
  4. hack on patch branches
  5. update quilt files
  6. checkout a new build branch from master
  7. merge updated patch branches into build branch


The outlined workflow could be done manually without new tools. It's however only practical, if additional tools are provided. This section describes the necessary tools to be implemented.

environment variables (names can change):

create quilt file


Creates a quilt patch file from a patch branch or updates an existing one, inheriting options from an exisiting quilt file.

Additionally there should be a wrapper command to invoke this command over all patches listed in debian/patches to update the quilt files.

checkout branch from quilt file


Creates a branch with the given name pointing to the commit specified in the git-commit line of the quilt file. Checks out the branch if checkout option is true.

Additionally there should be a wrapper command to invoke this command over all patches listed in debian/patches.

merge patch branch(es)


Merges all patch branches into the target branches. Creates the target branch if it doesn't exist yet.



Gives the following informations:


Detect cherry-picked patches available in upstream

Requirement: Upstream uses GIT and you track upstream in your repository Use case: You cherry picked a commit from upstream which was not yet available in the packaged version. When you later package an upstream version that contains the cherry-picked commit, the tools should note that and drop the patch.

Implementation: An additional dep-3 header field ( git-upstream-cherry-picked ) could contain a commit sha-1 (or a range commit range). It's then possible to detect, whether the commit is available in the current worked on upstream version.

Detect patches applied upstream via empty diff

When the diff between upstream and a patch branch becomes empty after a diff, then this means, that a patch has been applied upstream and the patch can be dropped.



Change log

* 2011-08-16 Cribbed the bulk of this page from ThomasKoch/GitPackagingWorkflow and edited for my workflow.