

There are two aspects to the workflow: on the one hand is the importer logic, which relates to the construction of the repository(ies) in Launchpad for source package, and is documented in brief here mostly for transparency and documentation; on the other hand are tools for using the git repositories in Launchpad to do bugfixes and merges, which is most likely the section of interest to developers.


Introductory blog posts

There is a series of blog posts covering the git ubuntu tool and this Git Workflow:

Git configuration

Since this workflow obviously uses git, you should have at least this basic config in ~/.gitconfig:

        email = youremail@example.com
        name = Your Name

Git workflow for merging

Algorithm outline

  1. Obtain git tree.
  2. Split current Ubuntu delta into logical commits.
  3. Rebase delta onto latest Debian release.
  4. Build/test.
  5. Reconstruct debian/changelog for new version.
  6. Update metadata for new version.
  7. Upload.

Detailed workflow

This guide assumes we are attempting to merge the version of <source package name> in the latest Ubuntu series with the latest Debian unstable version. If that is not the case, you might need to pass different commitishes to git ubuntu merge and/or specify the onto. See below for details.

  1. Obtain git tree.


        1. If it is, proceed to the next step.
        2. If it is not, send an e-mail to the Ubuntu Server list asking for it to be updated or import it locally (see the git ubuntu import section). You should eventually get a reply with a reference to the imported tree.


    2. git ubuntu clone <source package name>

      1. Feel free to use git directly with other git configuration flags, etc. as desired, but this guide will only cover the use of the git ubuntu clone tool. Similar results can be achieve throughout this guide with appropriate git subcommands, but YMMV.

  2. Split current Ubuntu delta into logical commits.
    1. cd into the just created dir cd <source package name>

    2. git ubuntu merge start ubuntu/devel

      • This will create a local 'debian/sid' branch that tracks 'importer/debian/sid'.

        • especially if you are re-merging something formerly done with this process you will need "-f" on git ubuntu merge otherwise the tags will still point to the last merge revisions.

      • This will replay the git-merged delta into a sequence of linear non-merge commits.
        • Instead, this will replay the current ubuntu delta back onto 'old/debian', but dropping the merge commits as artifacts of the git ubuntu import algorithm.



          • This might be dropped from a future release.

      • This commit is tagged as 'reconstruct/<ubuntu version>'.

        • Please note that our convention is to use '{reconstruct,split,logical}/<version>' (with standard dep14 substitutions). This allows us to store multiple tags associated with multiple versions for archival purposes.

      • You can pass --bug to git ubuntu merge and it will prefix all of the following names with lp<bug>, e.g. 'lp<bug>/old/ubuntu'. This allows you to have multiple merges in the same local repository without having to pass -f and overriding tags.

        • If you do pass --bug, all the tags referred to below will be under lp<bug>, please adjust your commands accordingly.

    3. git rebase -i old/debian


        2. In the editor provided by git-rebase, there are three cases to consider:


          3. For copies of the same version between pockets/releases, the line will be commented out (reflecting an empty commit) and can be left commented out. This is mentioned above as an artifact of our rebasing process.









    4. git ubuntu tag --split

      1. Tag the final commit for easy reference and review.
    5. git rebase -i old/debian

      1. Interactively rebase the split Ubuntu delta and drop 'changelog' and 'update-metadata' changes, by simply dropping those lines from the rebase todo file.


    6. git ubuntu tag --logical

      1. Tag this commit for easy reference and review.
      2. This command uses 'old/ubuntu' as a reference for the version to use in the tag-name, so it must exist LP: #165113.

  3. Rebase delta onto latest Debian release.
    1. git rebase --onto new/debian old/debian HEAD

      1. Replay the logical delta (changes between old/debian and HEAD) onto the latest Debian release.

  4. Build/test.
    1. Explain sbuild / point to it.
    2. you can benefit from the importer being able to restore orig tarballs, for a merge all you need to do to create tarball, sign and upload with new tarball would be git ubuntu build -S -v --sign --for-merge

  5. Run git ubuntu merge finish ubuntu/devel. This effectively wraps all of the following steps. From git those can be run manually instead, if desired - in the snap not all subcommands might be exposed.

    1. Verify we started a merge from either new/debian or lp#/new/debian as ancestor of HEAD
    2. Reconstruct debian/changelog for new version.
      1. dpkg-mergechangelogs old/debian old/ubuntu new/debian

        1. This rebuilds the changelog for published versions from old/debian to new/debian, inserting Ubuntu releases as appropriate.
      2. git commit -m 'merge-changelogs' debian/changelog

      3. git reconstruct-changelog new/debian

        1. This replays the commit messages for all commits since new/debian on the current branch into debian/changelog in a new entry.
        2. Note that the new entry is 'UNRELEASED' and should be updated, and it's possible you will need to reorganized the replayed entries.
          • 1.1. Using git ubuntu merge finish will target the current development release or --release if specified.

      4. git commit -m 'reconstruct-changelog' debian/changelog

        1. It is appropriate to either commit the reconstruct-changelog result and then make changes, followed by a second commit with the final changelog; or to not commit reconstruct-changelog and then make changes, followed by a commit with the final changelog. In either case, the result of this step should be a changelog entry which fully covers all the delta, and explains any dropped or added changes.
    3. Update metadata for new version.
      1. update-maintainer

        1. This updates the maintainer entry in the control file appropriately for Ubuntu source packages.
      2. git commit -m 'update-maintainer' debian/control

  6. While doing the former the Changelog is constructed out of the commit messages you had in your branch. Please check debian/changelog if they are sufficient for an upload.
  7. Consider some Cleanup and check open Bugs

      1. closed already but not updated yet => close them

      2. likely closed, but need verification => notify reporter


    2. Check all you have listed as "Remaining changes" in your changelog and consider pushing as much as possible to Debian.
  8. Make Ready for Push and review.
    1. git checkout -b merge

      1. if you happened to have a merge branch for this source already, recommended branch names to avoid conflicts are 'merge-<release>' and if multiple merges happen in one release 'merge-<release>-<version>'

      3. You will see those commits again next time this is merged. Please see the Workflow commentary for details on squashing changes (optional on the merge, but required on creating logical).

    2. git ubuntu lint

      1. You will get an automated check on your merge proposal anyway, but you could do so and clean up before uploading by calling the linter which checks for common issues. This feature is still new, please report bugs if you think a check is a false positive.
  9. Push and review
    1. Pushing via git ubuntu is still WIP but was nicely outlined including the following review process which is specific to the Server Team and therefore in their Knowledge Base as "Merge Proposals and Reviewing"

    2. You can also push an MP via git and Launchpad by
      • git push <launchpad user> merge old/debian new/debian old/ubuntu reconstruct/<ubuntu version> \

      • split/<ubuntu version> logical/<ubuntu version>

      • The remote name here, <launchpad user>, is an artifact of git ubuntu clone. If you used git directly, you might push to git+ssh://yourusername@git.launchpad.net/~yourusername/ubuntu/+source/<source package name>




        3. Discussions, new revisions and so on will be handled on that merges launchpad page. It is typical to file merges as Launchpad bugs as well, so ensure that the appropriate bug is mentioned in debian/changelog (e.g., 'Merge with Debian unstable (LP: #...). Remaining changes:') and Launchpad will automatically refer to your MR in the bug.
  10. Upload (Eventually that step won't be needed as it will be picked up from approved Merge Proposals)
    1. tag the propsed merge as the upload that you'll sponsor (or be uploaded by other sponsors)

      $ git ubuntu tag --upload

    2. Upload this tag to USDI, the remotes are all set up already

      $ git push pkg upload/<version>

      pkg is the remote provided by git ubuntu already and maps to ssh://<LPuser>@git.launchpad.net/~usd-import-team/ubuntu/+source/<packagename> (Presumes you have write rights to the USDI git repository.)

    3. After this when the importer picks up the new version it will map the rich history provided by the upload tag to the new import it does.

Workflow commentary

During the review of a merge, sometimes changes are needed and these usually will get added on to the end rather than being squashed in. We think this approach is easier. We don't object to the merge being redone, and everything squashed in, if desired or if it is decided it is worth it in a particular case, but in the general case we don't think it is necessary.

But that means that the merge branch will often not be squashed. And on a re-merge, there may be extra uploads that were done after the merge upload.

So we think it makes sense to always do the squashing before doing the logical tag at the start of a merge. The previous merge should help significantly with this, but will not be sufficient in the general case.

This would also have the advantage that the logical tag has a strict definition: a logical tag must always consist of squashed commits. In other words, it a logical tag should never have commits that can be squashed. Of course, what can be squashed is subjective, so different developers won't necessarily produce identical logical commits.

The reason why one might suddenly be able to squash more than on logical is that due to Debian or Upstream changing there might be new opportunities to do so. But it turned out to be most useful to not squash (everything) on the merge branch.

After the merge or next time on reworking logical things can be re-squashed/separated, also it might be worth to rewrite commit messages at that time to make up a much better reconstructed changelog eventually.

It can in general be quite useful to store any sort of knowledge that one handling a merge or complex bug had along. But rather often the extra insight is not suitable for the main commit message. So if there is anything reasonable to save we recommend to use git notes to add those along the commits of the merge branch.

Tools: their usage, and where to get them

git ubuntu

Available from Launchpad git repository.

It is also available as as snap: sudo snap install git-ubuntu --classic and then it should be available as a git-ubuntu.

NOTE: we are still working on issues related to argcomplete with the recent rename from usd -> git-ubuntu.

Top-level command to all the Ubuntu git repository-manipulating tools. To see all available subcommands, type:

git ubuntu

Each subcommand has its own help page. For example:

git ubuntu clone --help

git ubuntu import






Algorithmic discussion




Local usage

While the intention is to use the ~usd-import-team/ubuntu/+source repositories as the remotes for merge requests, it is also possible to run the importer fully locally and not push to a remote.

git ubuntu import --no-push <srcpkgname> -d /path/to/repository/

This will run the import algorithm locally, which can take some time, leaving the repository in /path/to/repository, but not pushing to any remotes. By the nature of the importing algorithm, the SHAs of the commits in your local tree will match the commits of the ~usd-import-team/ubuntu trees. Note that the -d path should not exist and it must be provided as an absolute path.





git ubuntu clone

Clone a source package git repository to a directory with appropriate remotes and tracking branches.


  • clone to open-iscsi/: git-ubuntu clone open-iscsi

  • clone to ubuntu.git: git-ubuntu clone open-iscsi ubuntu.git

  • use https rather than git protocol for read-only remotes: git-ubuntu clone --https open-iscsi

git ubuntu merge

Given a git-ubuntu merge import'd tree, assist with an Ubuntu merge.

Creates old/ubuntu, old/debian and new/debian tags for the specified Ubuntu merge. Breaks the specified Ubuntu merge into a sequence of non-git-merge-commits suitable for rebasing. Working tree must be clean.



So you would break down reconstruct/<version> into its constituent changes (per debian/changelog for each version) and tag the resulting end-commit as split/<version>.


git ubuntu tag

Given a git-ubuntu tag import'd tree, tag a commit respecting DEP14

By default, an upload tag is created. Working tree must be clean.

This subcommand tags the given commitish with the specified format, following the DEP14 requirements. The base version is read from debian/changelog at that commitish, except for logical tags, which reads from 'old/ubuntu'.

If no format is specified, an upload tag is created, suitable for pushing to the importer's repository.






Reviewing Merges

Some notes to checking for correctness. The goal is to come up with a step-by-step process that, if done correctly, guarantees that the merge is correct.

  1. Mechnical checks: see wip/review
  2. Account for every change in the previous logical commit. You can use git range-diff old/debian..old/ubuntu new/debian..<merge branch> to help with this (requires Git >= 2.19).

    1. Is transferred exactly, transferred modified, or dropped.
    2. Is noted correctly in changelog (twice if modified).
    3. The changelog note still accurately reflects the changes.
  3. Account for any new commits.
    1. Check that the changelog matches the commits.
    2. All commits in the new delta should now be accounted for.
  4. Check new delta:
    1. Anything dropped was appropriately dropped.
    2. All previous delta still kept is still correct and appropriate to keep.
    3. Anything new or changed is appropriate to add or change.

UbuntuDevelopment/Merging/GitWorkflow (last edited 2020-02-14 04:15:50 by logan)