The DesktopTeam uses git to manage its packages. Here's how to do some common things. You need git-buildpackage installed for most of this.
Suggested configuration is available in the end.
Branches and repo layout
We will use a layout with 3 remote repositories:
$ git remote show origin # will point to salsa (default for pull and push without any argument) gnome # will point to upstream repository, to cherry-pick easily upstream fixes
Note: we named in the page the remote gnome, to not be mislead with local branch names (which are for instance debian/branchname and upstream/branchname) if any. Consequently, instead of having debian/master, a local branch tracking debian/debian/master remote, we end up with debian/master tracking origin/debian/master, which is easier to understand.
As those remote name are local to your system, you can rename them as you see
Salsa remote branches
Let's look at the various branches in the origin (salsa) remote repository:
$ git remote show origin * remote origin […] HEAD branch: ubuntu/master Local branches configured for 'git pull': pristine-tar merges with remote pristine-tar ubuntu/master merges with remote ubuntu/master upstream/latest merges with remote upstream/latest Local refs configured for 'git push': pristine-tar pushes to pristine-tar (up to date) ubuntu/master pushes to ubuntu/master (up to date) upstream/latest pushes to upstream/latest (up to date)
ubuntu/master branch is the content of the latest development release. Work ready to be uploaded or uploaded in dev release mostly happens here. It's the default branch.
pristine-tar is an internal gbp-buildpackage branch, used to reconstruct release tarballs (using upstream/latest). You are not intended to interact with it directly.
upstream/latest 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 are not intended to interact with it directly.
We find back those 3 branches locally:
ubuntu/master -> pull and push from origin (salsa) remote repository, on ubuntu/master branch (origin/ubuntu/master)
pristine-tar -> pull and push from origin (salsa) remote repository, on pristine-tar branch (origin/pristine-tar)
upstream/latest -> pull from upstream remote repository, on the master branch (upstream/master), and push to origin (salsa) remote repository, on upstream/latest branch (origin/upstream/master).
Basically, you will only interact with ubuntu/master under that configuration, and let gbp handling the 2 other branches. When you gbp pull and gbp push, the 3 branches will be kept up to date if no conflict occurs. This is easier than checkout every branch before pushing them.
Once we have maintenance branches on a project (ensure you already followed #Create_a_maintenance_branch), additional remote branches are available:
$ git remote show origin * remote origin […] Remote branches: pristine-tar tracked ubuntu/bionic tracked ubuntu/master tracked upstream/latest tracked upstream/3.28.x tracked
ubuntu/bionic branch is the content for the corresponding release, once a particular release it out. It's the previous ubuntu/master branch when bionic was in development.
upstream/3.28.x: this branch (automatically managed by gbp buildpackage) corresponds to the upstream/latest branch, but tracking a particular upstream series, similar to the ubuntu/bionic branch. This branch is only necessary if you imported a new tarball (like 3.29 series) in 'upstream/latest and want to release an unimported yet 3.28.3 upstream release in bionic for instance.
Each one should have a corresponding local branch when working on bionic.
Debian remote branches
In addition, we'll have at least another branch tracking salsa debian remote repository. Their master branch is named debian/master:
debian/master -> pull (no push, unless you are a debian developer) from origin remote repository, on debian/master branch.
Upstream remote branches
By default, we don't have upstream branches checked out locally. We added the gnome repo and have access to its content, which will be fetched when importing new upstream tarball thanks to the version tag, and inject the history in upstream/latest (or upstream/version, as explained before).
$ git remote show gnome * remote gnome […] HEAD branch: master […] gnome-3-28 tracked […] Local branch configured for 'git pull': upstream/latest merges with remote master
You can ofc checkout any of those branch locally if you want We have upstream/master tracking the gnome repo on master branch. We can track any additional branches as needed for cherry-picking fixes.
Let's checkout locally gnome/master branch and make it the current checkout:
$ git checkout -b gnome-master gnome/master Branch 'gnome-master' set up to track remote branch 'master' from 'gnome'. Switched to a new branch 'gnome-master'
We asked to create a new local branch named gnome-master (first argument), tracking the remote named gnome, on the branch master (second argument).
To sum up all this, the minimal setup it the following ( are tracked branch):
$ git branch -vv debian/master c02b29966 [origin/debian/master] Revert "Don't recommend libnss-myhostname since it doesn't seem needed any more (LP: #1766575)" gnome-master d814d9db0 [gnome/master] Update Chinese (Taiwan) translation pristine-tar e59ab7422 [origin/pristine-tar] pristine-tar data for gnome-control-center_3.29.1.orig.tar.xz * ubuntu/master 63337a4cd [origin/ubuntu/master] releasing package gnome-control-center version 1:3.29.1-0ubuntu5 upstream/latest 0bd90ca34 [origin/upstream/latest] region: Show scrollbars if needed
With an ubuntu maintenance branch, and so, linked gbp buildpackage tarball branch, and upstream "master" branch checked out, with a local branch, we have in addition:
gnome-master d814d9db0 [gnome/master] Update Chinese (Taiwan) translation ubuntu/bionic ba45348d3 [origin/ubuntu/bionic] debian/gbp.conf: use gbp-buildpackage for ubuntu. upstream/3.28.x 83b100dc9 [origin/upstream/3.28.x] New upstream version 3.28.3
With the suggested configuration (see it at the end of the page), any non committed changes (file modifications, additions or removal) will halt the build, as they won't be included as a safety reminder.
You can either:
ignore them, appending --git-ignore-new. The resulting package and build won't include those uncommitted changes. (../build-area/<your-package> will match the last commit).
force using the current directory with your local modifications instead of build-area, and include (despite the "ignore-new" option) any local modifications to the package. For this, append --git-ignore-new --git-export-dir=""
Check out a branch for the first time
1. Salsa remote
If the Vcs-Git field is correct, you can
$ debcheckout --git-track=* gnome-control-center declared git repository at https://salsa.debian.org/gnome-team/gnome-control-center/ git clone https://salsa.debian.org/gnome-team/gnome-control-center -b ubuntu/master gnome-control-center ... […}
Otherwise, you can check out any git-buildpackage repository manually
$ gbp clone salsa-gnome:gnome-control-center gbp:info: Cloning from 'salsa-gnome:gnome-control-center' $ cd gnome-control-center
We want to push tags automatically, as gbp relies on them (this is a local configuration):
$ git config push.followTags true
2. Add upstream and debian remote
$ git remote add -f gnome firstname.lastname@example.org:GNOME/gnome-control-center.git
You should now have 3 branches correctly setup and tracking the correct branch with expected configuration.
$ git branch -vv pristine-tar e59ab7422 [origin/pristine-tar] pristine-tar data for gnome-control-center_3.28.1.orig.tar.xz * ubuntu/master ba45348d3 [origin/ubuntu/master] debian/gbp.conf: use gbp-buildpackage for ubuntu. upstream/latest 83b100dc9 [origin/upstream/latest] New upstream version 3.28.1
And 3 remotes, we only use one right now.
$ git remote gnome origin
3. Maintenance branches
If we want to track maintenance branches as well:
$ git remote show origin * remote origin […] HEAD branch: ubuntu/master Remote branches: pristine-tar tracked ubuntu/bionic tracked ubuntu/master tracked upstream/latest tracked
Let's track ubuntu/bionic:
$ git checkout ubuntu/bionic Branch 'ubuntu/bionic' set up to track remote branch 'ubuntu/bionic' from 'origin'. Switched to a new branch 'ubuntu/bionic'
this short syntax is only available because we create a local ubuntu/bionic tracking on the origin repo the matching named ubuntu/bionic. It doesn't work with any other repository name or when name doesn't match (and need an explicit git branch -u local-name remote/branch-name && git checkout local-name).
Let's check that:
$ git branch -vv pristine-tar e59ab7422 [origin/pristine-tar] pristine-tar data for gnome-control-center_3.28.1.orig.tar.xz * ubuntu/bionic cf931abe4 [origin/ubuntu/bionic] debian/patches/privacy-panel-whoopsie.patch ubuntu/master dce53a3d2 [origin/ubuntu/master] Change gbp option order to be more meaningful upstream/latest 83b100dc9 [origin/upstream/latest] New upstream version 3.28.1
Day to day operation
Building a binary or source package
- Binary package:
$ gbp buildpackage […]
- Source package:
$ gbp buildpackage -S […]
With the proposed configuration, the artefacts will all end up in ../build-area (including tarball, which is reconstructed from the pristine-tar + upstream/latest branch) and build directory is cleaned up.
Some potential cases:
Don't purge the **build-area** directory after building: gbp buildpackage --git-no-purge
Build current branch with local uncommitted modifications: gbp buildpackage --git-ignore-new --git-export-dir=""
Use gbp pull to refresh current ubuntu/<branch> and corresponding upstream/<release> (only the ones referenced in your current checkout debian/gbp.conf) as well as pristine-tar branch.
$ gbp pull gbp:info: Fetching from default remote for each branch gbp:info: Branch 'upstream/latest' is already up to date. gbp:info: Branch 'ubuntu/master' is already up to date. gbp:info: Updating 'pristine-tar': 2bed57f20816..e59ab7422a13
-> the branch pristine-tar has been updated as refenced in debian/gbp.conf.
If you have a separate ubuntu/bionic branch, with its own upstream/3.28.x branch:
$ git checkout ubuntu/bionic $ gbp pull gbp:info: Fetching from default remote for each branch gbp:info: Branch 'pristine-tar' is already up to date. gbp:info: Branch 'upstream/3.28.x' is already up to date. gbp:info: Updating 'ubuntu/bionic': fe031c0214ba..59adb2d88983
gbp pull, contrary to git push, is a way for you to avoid checkouting each branch and git pull them one by one (as you need to have the branch as a current checkout for potential conflicts when pulling).
Pushing your git changes to salsa
Contrary for pulling, We are using git push for this. All branches tracking the origin repo will be pushed that way (no need to be on the correct checkout, contrary to gbp pull). Relevant tags as well (if you follow our advised configuration) will be pushed.
Merge a new upstream version
On the branch you want to have version imported (like ubuntu/master here).
As a first part, you need to create a patch/queue/ubuntu/master branch with gbp pq that is useful in case you need to refresh patches later. If you have it already, just rebase it.
# Create a patch/queue branch that will be useful for refresh patches later $ gbp pq import # if you already have it, just use `gbp pq rebase instead`
Using upstream tarball
You need to follow this path in the case debian has not imported this version yet, although since we don't want to have duplicated upstream/x.y.z tags, in this case you should push the pristine-tar and upstream/<current> branches to origin
$ git fetch gnome $ git checkout ubuntu/master $ gbp import-orig ../gnome-control-center-3.28.2.tar.xz # can be as well --uscan to let it download and import What is the upstream version? [3.28.2] gbp:info: Importing '../gnome-control-center-3.28.2.tar.xz' to branch 'upstream/latest'... gbp:info: Source package is gnome-control-center gbp:info: Upstream version is 3.28.2 gbp:info: Replacing upstream source on 'ubuntu/bionic' gbp:info: Successfully imported version 3.28.2 of ../gnome-control-center-3.28.2.tar.xz $ git push
This will push all needed branches (ubuntu/master for instance and pristine-tarball + upstream/3.28.x or upstream/latest if this upload is a new upstream release).
As said, now you should sync (or propose if not ubuntu developer) the affected upstream branch to salsa.debian.org (making sure you push the new tag too).
Note: If you get when importing:
$ gbp import-orig ../gnome-control-center-3.29.2.tar.xz What is the upstream version? [3.29.2] gbp:info: Importing '../gnome-control-center-3.29.2.tar.xz' to branch 'upstream/latest'... gbp:info: Source package is gnome-control-center gbp:info: Upstream version is 3.29.2 gbp:error: Import of ../gnome-control-center-3.29.2.tar.xz failed: revision '…' not found
There are 3 cases:
You didn't run git fetch gnome and so, didn't get latest commits and tags in your repository metadata.
Upstream has changed the tagging pattern (and so, debian/gbp.conf needs to be updated to match it)
Upstream is using an inconsistent release pattern (and so, debian/gbp.conf can't have a regexp for the version). In that case, please specify manually --upstream-vcs-tag=exact_version_tag to gbp import-orig. You can find the exact tag via git describe --tags --abbrev=0 gnome/master.
Another error you could get is:
$ gbp import-orig ../gnome-control-center-3.29.2.tar.xz What is the upstream version? [3.29.2] gbp:error: Upstream tag 'upstream/3.29.2' already exists
In this case, debian has already this tarball so you should follow the next chapter ("Using debian's upstream branch tags").
Using debian's upstream branch tags
If debian has already this version, you don't have to import the actual tarball but just merge with the latest upstream code, and so:
git merge upstream/3.28.2 -m "Update upstream source from tag 'upstream/3.28.2'"
There could be some additional steps involved, if master does have a newer version than the maintenance branch, and you are the first to deal with that case for that maintenance release.
Basically if debian/gbp.conf has upstream-branch=upstream/latest and the ubuntu/master branch has a newer upstream version than the one you are importing (which was never imported), please read this. Otherwise, just follow the steps in the previous case, after eventually creating a maintenance branch (see corresponding section) and switching to it.
For instance, let's say: - ubuntu/master is on 3.29.2 - ubuntu/bionic is on 3.28.1 and we want to update to 3.28.2 - we have pristine-tar having 3.28.1 and 3.29.2 imported - consequently the upstream/latest branch has upstream commits and tags for 3.28.1, 3.29.2 and corresponding gbp tags upstream/3.28.1 and upstream/3.29.2.
Ensure you are on your ubuntu/bionic branch.
1. Create a new upstream/<series> branch
Note that you need to check latest version of upstream/latest in your maintenance branch (upstream/3.28.1 in our case).
$ git branch upstream/3.28.x upstream/3.28.1
2. Update debian/gbp.conf to reference correct upstream gbp branch
# edit debian/gbp.conf and replace with '''upstream-branch=upstream/3.28.x''' $ git commit -a
Using upstream tarball
3a. Then if this revision is not in salsa upstream branch yet
$ git fetch gnome $ gbp import-orig ../gnome-control-center-3.28.2.tar.xz
3b. Remember pushing your changes, including the new branch that you want to track
$ git push $ git push -u upstream/3.28.x
Using debian's upstream branch tags
3a. Then if this revision is already in salsa upstrema branch
git merge upstream/3.28.2 -m "Update upstream source from tag 'upstream/3.28.2'"
4. Remember to push the upstream and pristine-tar branches to salsa
You can push to your guest account and prepare a pull-request or directly on the gnome branch if you have the right.
When merging with an upstream release, the patches might need to be refreshed. In case your patch/queue branch is in sync with previous release you can just use:
gbp pq rebase # Then use git rebase tools to refresh them
This is described better, for the case of using gbp import-orig in gbp documentation. This might won't work if you're instead merging with an upstream/x.z.y tag or if you didn't create the patch/queue branch first, so let's just write here one that should work in both cases, so you don't have to worry about too much:
# on corresponding branch… # Remove the patch-queue branch, if any... Not needed if you don't have one gbp pq drop # This is a brute-force approach that will try to find the first point where the patches merge, # so you can tune it increasing until when you won't find the previous release commit gbp pq import --force --time-machine=30 # This will re-apply the debian/patches/series on top of new upstream code stopping for manual # action if is needed. gbp pq rebase # If a patch doesn't apply cleanly, manual intervention is needed. In such case, just use # classic `git add`, `git rm` to resolve the conflicts, and eventually just proceed with # `git rebase --continue` # Regenerate debian/patches data, ready to be committed and switch back to your ubuntu/ branch gbp pq export --no-patch-numbers
Once back on ubuntu/master or ubuntu/<series> branch, you need to commit the changes too.
Release a package
If this is a sponsored upload, the sponsor performs these steps.
Generate changelog for native packages
# Add debian/changelog entries based on git log gbp dch # You might need to manually edit debian/changelog # to properly group changes per people
# on corresponding branch… $ dch -r "" $ git commit debian/changelog -m "Finalise changelog" $ gbp buildpackage --git-tag-only $ gbp buildpackage -S $ dput ../build-area/….changes $ git push # Make sure you also pushed the tag(s) we care about: $ git tag | grep -E '^ubuntu/|^debian/|^upstream/' | xargs -r git push
This will push all tracked branches to salsa if you made any change: ubuntu/master, ubuntu/old-series, pristine-tar, upstream/lastest. Tags will also be pushed.
Working on patches
1. Ensure you are on the correct ubuntu/ branch (or your local experimental-feature branch).
$ git checkout ubuntu/master # for instance
2. Turn each patches in debian/patches as commits.
$ gbp pq rebase gbp:info: Switching to 'patch-queue/ubuntu/master' Current branch patch-queue/ubuntu/master is up to date.
-> Now, we have every patch referenced in debian/patches/series applied as separate commits on top of ubuntu/master, in a patch-queue/ubuntu/master branch, and we switched to that current checkout.
$ git missing ubuntu/master.. # git log would also show the commits * 11a3a8cc6 - (HEAD -> patch-queue/ubuntu/master) [PATCH] night-ligth-dialog: Avoid dereferencing invalid p ointer (5 minutes ago) * da06252e1 - [PATCH 4/4] thunderbolt: move to the 'Devices' page (5 minutes ago) * 2c9f5bcbb - [PATCH 3/4] thunderbolt: new panel for device management (5 minutes ago) * 660e9e633 - [PATCH 2/4] shell: Icon name helper returns symbolic name (5 minutes ago) * a78ae89dd - [PATCH 1/4] shell: Don't set per-panel icon (5 minutes ago) […]
We can git add/git commit. Any new commit will be a separate patch applied at the end of debian/patches/series. Commit description will be then converted to the patch description.
Remember previous tip of gbp buildpackage --git-ignore-new --git-export-dir="" to build a package with current content without having to switch branch.
4. optional: Reorder patches
If we don't want this patch to be the last one, we can use an interactive git rebase:
$ git rebase -i ubuntu/master
That way, we only see the patches commit, can reorder them, amend or stash them. Removing one will also remove the patch from debian/patches/series
5. Reapply all changes to the original branch:
$ gbp pq export --no-patch-numbers gbp:info: On 'patch-queue/ubuntu/master', switching to 'ubuntu/master' gbp:info: Generating patches from git (ubuntu/master..patch-queue/ubuntu/master)
6. Modify changelog, git add, git commit
Note that gbp pq will unfuzz a lot of patches everytime you use it, creating some noise. Please add those changes separated from your new or modified patch hack.
And either push the change to your branch or to the main branches with a simple git push!
Pick some upstream commits
1. Refresh upstream repo if needed:
Remember that we don't have a local checkout, only a remote that we need to refresh
$ git fetch gnome
2. Find the commit(s) you want to cherry-pick
Look at log history with, for instance:
$ git log -p gnome/master
3. Cherry-pick one commit as a patch (here on ubuntu/master branch):
$ git checkout ubuntu/master $ git pull $ gbp pq rebase # or, gbp pq drop; gbp pq import (this will delete your patch queue and re-create it from debian/patches, which can be useful if the patch-queue branch gets out of sync with master) $ git log -p upstream/latest # get a hash commit you want to cherry-pick $ git cherry-pick -e -x <hash> # if there are no conflicts, edit the commit message to be DEP-3 compliant - this will end up as the patch header # if there are conflicts, fix them (e.g. with `git mergetool`) and then `git cherry-pick --continue` - again edit the commit message to be DEP-3 compliant $ gbp pq export --no-patch-numbers # update changelog $ git add debian/patches/* debian/changelog $ git commit
See previous section for more info on gbp pq.
Import an out of VCS ubuntu upload
On the branch you want to have that ubuntu upload, after downloading the source tarball:
$ gbp import-dsc ../gnome-control-center_3.28.1-0ubuntu5.dsc gbp:info: Version '1:3.28.1-0ubuntu5' imported under '…/gnome-control-center' $ git push
This will push all needed branches (ubuntu/master for instance and pristine-tarball + upstream/latest if this upload is a new upstream release).
Out of VCS upload while having changes in tree
importing take latest tarball and will eventually revert any changes that were sitting in the VCS. You have 2 strategies:
- rewriting the history (but everyone who pulled the repo will have conflicts with refreshing) via a rebase. This is thus discouraged.
applying the latest source package, and reintroducing the changes (cherry-picking the commits). Note that as your commits are already in tree (but reverted), git cherry-pick <hash> won't work. You should rather:
$ git show <hash> | git apply $ git commit -C <hash>
Create a maintenance branch
1. Find correct version
Fin latest version in common between the development release and that maintenance branch. Here, we'll use the version tag ubuntu/1%3.28.1-0ubuntu4
2. create a branch from start starting point, and push it to salsa
$ git branch ubuntu/bionic ubuntu/1%3.28.1-0ubuntu4 $ git checkout ubuntu/bionic Switched to branch 'ubuntu/bionic'
3. Adjust parameters in debian/gbp.conf and debian/control.
# Change `debian-branch` to '''ubuntu/bionic''' in debian/gbp.conf # Change Vcs-Browser in debian/control to the branch's page on https://salsa.debian.org/<package>/tree/<branch> # Add `-b '''ubuntu/bionic'''` at the end of Vcs-Git # Preserve debian Vcs-* values as XS-Debian-Vcs-* $ git commit -a
4. Push your changes to salsa and track that branch
$ git push -u origin ubuntu/bionic Total 0 (delta 0), reused 0 (delta 0) To git+ssh://email@example.com:gnome-team/gnome-control-center * [new branch] ubuntu/bionic -> ubuntu/bionic Branch 'ubuntu/bionic' set up to track remote branch 'ubuntu/bionic' from 'origin'.
Merge with debian
Convert a package to git for the first time from Debian
This section has been moved to DesktopTeam/git/NewPackageImport.
To easily access to salsa git repositories with git clone salsa:name-or-team/repo or git clone salsa-gnome:repo, you should add to your .gitconfig file the following paragraph:
[url "firstname.lastname@example.org:"] insteadof = salsa: [url "email@example.com/gnome-team/"] insteadof = salsa-gnome:
See this gitlab doc for more information on git configuration with gitlab.
git-buildpackage uses this file for its default configuration; some tweaks are recommended.
[buildpackage] # use this for exporting first your directory in a ../build-area: export-dir = ../build-area/ # automatically GPG sign tags with associated keyid sign-tags = True keyid = 0xGPGKEYID
See gbp.conf(5) and man of gbp-buildpackage for more options.
To merge changelog automatically, dpkg-mergechangelogs can be used, so change ~/.gitconfig as follows:
[merge "dpkg-mergechangelogs"] name = debian/changelog merge driver driver = dpkg-mergechangelogs -m %O %A %B %A
Then set it as the default strategy:
# Create a global gitattributes file and set the merge strategy for debian/changelog files mkdir -p -m 700 ~/.config/git/ echo 'debian/changelog merge=dpkg-mergechangelogs' >> ~/.config/git/attributes
WARNING: This may not work when ubuntu packages use an higher epoch than the debian ones, so will need manual fix
Work to be done:
- Talk with upstream about preventing importing older tarball in upstream/latest and handling creation of upstream/maintenance-branch
- Ensure that if no upstream tag is in debian/gbp.conf and not found in repo, erroring out when importing a tarballs.