Table of Contents:
Git is used for version control for all Apertis projects. This page assumes good working knowledge of git; some introductory material is available here, and a git cheatsheet is here.
Summary
- Make atomic, revertable commits. (Guidelines for making commits)
- Include full reasoning in commit messages, plus links to relevant bug reports or specifications. (Guidelines for making commits)
- Keep large changes, such as renames, in separate commits. (Guidelines for making commits)
- Merge changes from feature branches by rebasing. (Use of git)
Use of git
For projects where Apertis is the upstream developer, the git repositories follow these rules:
- No forced pushes to main branches.
- Rebase commits rather than merging.
- Work on feature branches on Apertis git, then rebase on the main branch and fast-forward merge the changes.
- Hide sausage making by squashing commits before merging.
- Changes intended for the development branch of Apertis should be based on the
branch named after that release under
apertis/
, for example the v2021dev3 branch isapertis/v2021dev3
. - Targeted changes for stable branches of Apertis (for example
v2019
) should use the relevant branch named likeapertis/v2019-security
orapertis/v2019-updates
, depending on the focus of the change. - Changes should be proposed via a merged request to the relevant release branch when ready.
Third-party packages
For packages where we are packaging and maybe modifying a third-party
project such as dbus
, the git repositories follow these rules:
- We follow the naming convention from
DEP-14:
- The main development branch is
apertis/${APERTIS_RELEASE}
- Updates for frozen or stable branches of Apertis are on a branch named like
apertis/${APERTIS_RELEASE}-security
andapertis/${APERTIS_RELEASE}-updates
, depending on the focus of the change.
- The main development branch is
- Non-native packages are assumed to use the
3.0 (quilt)
source format. Theapertis/*
branches must be in the “patches unapplied” state: all changes outsidedebian/
are represented by (unified diff) patches indebian/patches
and listed indebian/patches/series
. For example, if we patchconfigure.ac
, the version ofconfigure.ac
seen in git is the upstream version, and our change is only visible as a patch indebian/patches/series
.- Developers can use either
quilt
orgbp pq
to manipulate the patch series. If usinggbp pq
, thepatch-queue/*
branches must not be pushed to the central repository.
- Developers can use either
- The versions from Debian on which our versions are
based, should be imported onto
debian/${UPSTREAM_DISTRIBUTION}
(e.g.debian/buster
). The required process is covered in the ci-package-builder documentation. - Each version of an Apertis package derived from a Debian package must
have a local version suffix. If the Apertis package has no functional
changes and the only difference from the upstream is metadata under
debian/apertis/
, the suffix should beapertis0
. Due to how Debian packaging tools work, this version change must be reflected in by adding a new entry at the top ofdebian/changelog
with the distribution field set toapertis
.
Guidelines for making commits
Commits should be as small as possible, but no smaller. Each commit should address a single issue, containing only changes related to that issue. The message for each commit should describe the issue, explain what causes it, and explain how it has been fixed if it is not obvious.
The changes in each commit should be easy to read. For example, they should not unnecessarily change whitespace or indentation. Large, mechanical changes, such as renaming a file or function, should be put in separate commits from modifications to code inside that file or function, so that the latter changes do not get buried and lost in the former.
The following principles give the reasoning for all the advice above:
- Each commit should take the repository from one working state to another, otherwise bisection is impossible.
- Each commit should be individually revertable. If it later turns out that the
commit was a bad idea,
git revert [commit ID]
should take the repository from a working state to another working state. - The reasoning for each commit, and its relationship to external resources like specifications and bug reports, should be clear, to the extent that commits written by one developer a year in the past should still be understandable by a second developer without having to trace through the changes and work out what they do. See the Commit messages section for details.
- Each commit should be written once, and designed to be read many times, by many reviewers and future programmers.
Commit messages
Commit messages should focus on why a change has been introduced rather than what it does, as the latter should be understandable by looking at the commit diff.
In more detail, the messages should include as much reasoning about the change as possible, pointing out its relationship to external resources like specifications and bug reports: always write them such that they can be understood by other developers a year after you commit.
There are a few guidelines that describe how to write good commits and the style and formatting to be used:
- the very short seven rules
- the longer Linux kernel style guide for commit messages
Minimally the following should be followed:
- Subject: less than 50 characters
- Body: each line should be less than 72 characters long
- A
Signed-off-by
tag must be present as a Developer Certificate of Origin
Here’s an example:
CbyServiceManager: Instruct systemd to send SIGKILL after 10s
After executing the ExecStop command-line or sending SIGTERM,
by default systemd will wait up to 90 seconds for a service to exit
before it becomes impatient and sends SIGKILL. This seems far too long
for our use-case; wait 10 seconds instead.
The choice of this arbitrary timeout is a trade-off. If it is too
short, applications with a lot of state to serialize to disk might
be killed before they have done so (we'd better hope they're using
crash-safe I/O patterns like g_file_set_contents()). If it is too
long, a user uninstalling an app-bundle will be left waiting
a long time.
When Ribchester calls TerminateBundle (T2696) it will need to wait
a little longer than this; whatever timeout it uses, a broken or
compromised per-user instance of Canterbury would be able to delay
app-bundle upgrade, rollback or removal by up to that long.
Apertis: https://phabricator.apertis.org/T12345
Signed-off-by: Simon McVittie <smcv@collabora.com>
Reviewed-by: Frédéric Dalleau <frederic.dalleau@collabora.co.uk>
Differential Revision: https://phabricator.apertis.org/D7088
Tags can be used in commit messages to enhance the information recorded in the
debian/changelog
by
gbp-dch.
gbp-dch
is a tool that parses the commit messages and automatically turns
them in entries for debian/changelog
.
With it you can use the following tags in your commit messages:
Gbp-Dch: {Full,Short}
Short
will create a short changelog entry using the short commit message (ie. the first line of the commit message). This is the default.Full
will include the long description in the generated changelog entry
Thanks: $SOMEONE
if you want to give kudos to someoneApertis: {$TASK_URL,$TASK_ID}
, is translated to(Apertis: Txxxx)
indebian/changelog
for automated task status tracking
For the last tag to work, the package requires the following entries in
debian/gbp.conf
:
[dch]
meta-closes = Apertis
meta-closes-bugnum = (?:https://phabricator.apertis.org/)?(\T?\d+)
Running gbp dch
will turn a commit message like:
Update website link to demo images
The website has new path for demo images.
Gbp-Dch: Full
Apertis: https://phabricator.apertis.org/T12345
Thanks: Mariano for pointing out the issue
Signed-off-by: Héctor Orón Martínez <hector.oron@collabora.co.uk>
to the following debian/changelog
entry:
* Update website link to demo images.
The website has new path for demo images.
Signed-off-by: Héctor Orón Martínez <hector.oron@collabora.co.uk>
Thanks to Mariano for pointing out the issue (Apertis: T12345)
Merging procedure
Merges should be carried out via the gitlab UI as a merge request to enable easy review.
-
Ensure the local copy of the main development branch is up-to-date
git checkout apertis/${APERTIS_RELEASE} git pull
-
Checkout the feature branch and rebase on the main development branch
git checkout my-branch git rebase --interactive apertis/${APERTIS_RELEASE}
-
Ensure the rebase is successful; test the changes.
-
Push the feature branch to git as a “wip” branch for review
git push origin my-branch:wip/${USER}/my-branch
-
Follow the URL provided by the above command to complete creating a merge request