Set up Git for Ubuntu Desktop work

The Desktop Team uses Git and Git Build Package (gbp) to maintain GNOME packages for Ubuntu. Let’s set up your system so that you can contribute to GNOME on Ubuntu Desktop.

We use the Settings application as an example. Internally, the application is known as the GNOME Control Center.

Initial setup

  1. Install the basic packages for working in Git and Ubuntu packaging:

    $
    sudo apt install git git-extras git-buildpackage ubuntu-dev-tools gnupg

    For details about the packaging environment, see How to set up for Ubuntu development.

  2. Install and configure the sbuild tool. Follow sbuild. Set the Ubuntu releases for which you’re preparing packages.

  3. In the Software & Updates application, enable Source code on the Ubuntu Software tab.

    This provides information about the source repository of every package so that you can easily clone it.

  4. Enable short formats for Git repositories: salsa:name-or-team/repo and salsa-gnome:repo for Salsa, fdo:repo for freedesktop.org:

    Add the following configuration to your ~/.config/git/config file:

    ~/.config/git/config
    [url "[email protected]:"]
        insteadof = salsa:
    
    [url "[email protected]:gnome-team/"]
        insteadof = salsa-gnome:
    
    [url "https://gitlab.freedesktop.org/"]
        insteadof = fdo:
    

Sign your commits

Some projects might require that you sign tags with your GPG key. Enable automatic signing.

  1. Create your GPG key as described in GnuPG.

  2. Display your public GPG key:

    $
    gpg --list-secret-keys --fingerprint
    /home/user/.gnupg/pubring.kbx
    -----------------------------------------------------
    sec   rsa2048 YYYY-MM-DD [SC]
        XXXX XXXX XXXX XXXX XXXX  XXXX XXXX XXXX D1B7 6B89
    uid           [ unknown] Key Name <[email protected]>
    ssb   rsa2048 YYYY-MM-DDD [E]
    

    Your short GPG key ID is the last eight digits of your public GPG key, or D1B76B89 in this example.

  3. Add the following configuration to your ~/.gbp.conf file:

    ~/.gbp.conf
    [buildpackage]
    sign-tags = True
    keyid = 0xGPGKEYID
    

    Replace GPGKEYID with your short GPG key ID.

Required accounts

  1. If you don’t have accounts on the following GitLab instances, create them:

    It might take a while for your account to be approved.

  2. In your account preferences, upload your SSH public key to be able to interact with the Git repositories.

Clone a repository

Let’s clone the GNOME Control Center repository.

  1. Check if the package provides information about its source repository:

    $
    apt-cache showsrc gnome-control-center | grep-dctrl -n -s Vcs-Git -
    https://salsa.debian.org/gnome-team/gnome-control-center.git -b ubuntu/master
    

    A link to a Git repository is attached to this package.

  2. Clone the repository from the Salsa remote:

    $
    gbp clone salsa-gnome:gnome-control-center
    gbp:info: Cloning from 'salsa-gnome:gnome-control-center'
    

    You can also use the repository link found earlier:

    $
    gbp clone https://salsa.debian.org/gnome-team/gnome-control-center.git
    gbp:info: Cloning from 'https://salsa.debian.org/gnome-team/gnome-control-center.git'
    

Configure branches

  1. Switch to the cloned repository:

    $
    cd gnome-control-center
  2. Enable Git to push tags automatically because gbp relies on them.

    Apply this as local configuration in the cloned repository:

    gnome-control-center$
    git config push.followTags true
  3. Add the upstream GNOME remote repository and call it upstreamvcs:

    gnome-control-center$
    git remote add -f upstreamvcs git@ssh.gitlab.gnome.org:GNOME/gnome-control-center.git

    Note

    If you don’t have an account on the GNOME GitLab or if your account is missing an SSH key, you can also refer to the repository using the HTTPS protocol:

    gnome-control-center$
    git remote add -f upstreamvcs https://gitlab.gnome.org/GNOME/gnome-control-center.git
  4. Check that you now have the following three branches:

    gnome-control-center$
    git branch -vv
      pristine-tar      a96c0e2e98 [origin/pristine-tar] pristine-tar data for gnome-control-center_49.0.orig.tar.xz
    * ubuntu/latest     a8640ab8a4 [origin/ubuntu/latest] debian/salsa-ci: Enable for ubuntu
      upstream/latest   4db8b3a502 [origin/upstream/latest] New upstream version 49.0
    
  5. Check that you have the following two remotes:

    gnome-control-center$
    git remote
    origin
    upstreamvcs
    

Examine the branches and repositories

We use a layout with two remote repositories. Let’s take a look.

Run these commands in the gnome-control-center repository that we cloned earlier.

gnome-control-center$
git remote -v

The command lists the following remote repositories:

origin

Points to the Salsa repository. The default for pull and push without any argument.

upstreamvcs

Points to the upstream GNOME repository, to easily cherry-pick upstream fixes.

This remote is called upstreamvcs to not be confused with local branch names, which might be called debian/<branch-name> or upstream/<branch-name>. Instead of having a local debian/latest branch tracking the debian/debian/latest remote, we have the debian/latest local branch tracking the origin/debian/latest remote, which is easier to understand.

Note

The debian/latest and ubuntu/latest branches were previously called debian/master and ubuntu/master, respectively. We renamed them on 4 September 2023 to use more inclusive naming and more closely follow DEP-14.

Salsa remote branches

Let’s look at the various branches in the Salsa remote repository:

gnome-control-center$
git remote show origin
* remote origin
  […]
  HEAD branch: debian/latest
  Remote branches:
    pristine-tar             tracked
    ubuntu/latest            tracked
    upstream/latest          tracked
  […]
ubuntu/latest, sometimes ubuntu/main or ubuntu/master

This branch is the content of the latest Ubuntu development release. Work ready to be uploaded or uploaded in a development release mostly happens here. It’s the default branch.

pristine-tar

This branch is an internal gbp-buildpackage branch, used to reconstruct release tarballs using upstream/latest. Usually, you don’t interact with it directly. When you do need to interact with it, such as to manage the tarballs, use the pristine-tar tool.

upstream/latest

This is another internal gbp-buildpackage branch. It’s a merge between the upstream Git branch corresponding to the latest release from the upstream repository and extra content coming from the tarball. You don’t interact with it directly.

In this configuration, you only interact with the ubuntu/latest branch and let gbp handle the other two branches. When you pull and push using gbp, it keeps all three branches up to date if no conflict occurs. This is easier than checking out every branch before pushing them.

Maintenance branches

Many release maintenance branches are available on the Salsa remote repository:

gnome-control-center$
git remote show origin
* remote origin
  […]
  Remote branches:
    […]
    pristine-tar             tracked
    ubuntu/noble             tracked
    ubuntu/latest            tracked
    upstream/latest          tracked
    upstream/46.x            tracked
    […]
ubuntu/noble

This branch contains the version of the project for the given Ubuntu release. In this example, the branch contains GNOME Control Center 46 for Ubuntu Noble. When a new release comes out of development, its ubuntu/latest branch becomes a maintenance branch.

upstream/46.x

This is a maintenance branch tracking a particular upstream GNOME series, similar to the ubuntu/noble branch. It’s derived from the upstream/latest branch when a new upstream release series, such as GNOME 46, comes out.

This branch is only necessary if you imported a new tarball (like the 46 series) in upstream/latest and you want to release a yet unimported 46.3 upstream release in Noble, for instance.

This branch is automatically managed by gbp buildpackage.

Each remote branch should have a corresponding local branch when working on Noble.

Let’s track the ubuntu/noble maintenance branch:

gnome-control-center$
git checkout ubuntu/noble
Switched to branch 'ubuntu/noble'
Your branch is up to date with 'origin/ubuntu/noble'.

Note

This short syntax is only available because we created a local ubuntu/noble branch that tracks the matching ubuntu/noble branch on the origin repository.

To create another local branch that tracks a remote branch, use the following commands:

gnome-control-center$
git branch -u <local-branch-name> <remote>/<branch-name>
gnome-control-center$
git checkout <local-branch-name>

Debian remote branches

In addition, we have at least one other branch tracking the Salsa Debian remote repository. Their main (default) branch is called debian/latest:

debian/latest

Pull from the origin remote repository, tracking the debian/latest remote branch. To push to this branch, you must be a Debian Developer.

Upstream GNOME remote branches

By default, we don’t have upstream GNOME branches checked out locally. We added the upstreamvcs repository and have access to its content.

Note

Later, we’ll import a new upstream tarball, representing a new release of the gnome-control-center project. The gbp tool will fetch the content of upstreamvcs thanks to the version tag.

Let’s browse the content of the upstreamvcs repository:

gnome-control-center$
git remote show upstreamvcs
* remote upstreamvcs
[…]
  HEAD branch: main
  Remote branches:
[…]
    gnome-49                                  tracked
[…]

The branches within origin/upstream on Salsa, such as the origin/upstream/latest branch, tag unmodified releases from the GNOME upstreamvcs remote, without the Debian packaging and changes. As a result, the local upstream/latest branch tracks the main branch of the upstreamvcs repository.

You can check out any of those branch locally. We can track any additional branches as needed for cherry-picking fixes.

Our convention is to check out the upstreamvcs/main branch locally and call it upstreamvcs-main:

gnome-control-center$
git checkout -b upstreamvcs-main upstreamvcs/main
Branch 'upstreamvcs-main' set up to track remote branch 'main' from 'upstreamvcs'.
Switched to a new branch 'upstreamvcs-main'

Optional configuration

The following configuration can simplify certain tasks on Ubuntu Desktop projects.

Git command aliases

Enable Git command aliases:

~/.config/git/config
[alias]
    matching-tags = "!f() { git for-each-ref --sort=creatordate --format '%(refname)' refs/tags| grep \"$1\"| sed s,^refs/tags/,,; }; f"
    last-tags = matching-tags '.*'
    last-match-tag = "!f() { git matching-tags $1 | tail -n1; }; f"
    last-tag = last-match-tag '.*'
    last-debian-tag = last-match-tag debian/
    last-ubuntu-tag = last-match-tag ubuntu/
    ubuntu-delta = "!f() { git diff $(git last-debian-tag) -- ${1:-debian} ':(exclude)debian/changelog'; }; f"

Exporting the build area

Export the ../build-area/ directory before building with the git-buildpackage tool:

~/.gbp.conf
[buildpackage]
export-dir = ../build-area/

For details, see the gbp.conf(5) and gbp-buildpackage(1) manual pages.

Merging the changelog automatically

To merge the changelog automatically, enable the dpkg-mergechangelogs tool in the ~/.config/git/config file:

~/.config/git/config
[merge "dpkg-mergechangelogs"]  
    name = debian/changelog merge driver
    driver = dpkg-mergechangelogs -m %O %A %B %A

Create the ~/.config/git/attributes file and set dpkg-mergechangelogs as the default strategy in it:

~/.config/git/attributes
debian/changelog merge=dpkg-mergechangelogs

Warning

This automation might not work when Ubuntu packages use a higher epoch than the Debian ones. In that case, fix the changelog manually.

Next steps

Now that your Git setup is complete, you can contribute to Ubuntu Desktop software. You can build, modify, maintain and package applications. See Maintain Ubuntu Desktop software.