How to Contribute Code#
Note
You’ll need to familiarize yourself with setting up a development environment and building FlightGear in order to contribute code. See Developing on the codebase if you do not already have a working setup. Some understanding of Git will also be necessary; this free, online book is quite useful.
The most efficient way to contribute changes to the FlightGear code base is to file a merge request (this doesn’t apply to aircraft or add-ons, which are managed differently). We’ll first give an overview of the process including its main prerequisites, then explain each step in more detail.
Overview#
The basic workflow for first-time contributors to a FlightGear Git repository is:
Fork the repository. Fork the relevant FlightGear repository into your GitLab account. You will need to know which repository contains the code you are trying to change. Familiarizing yourself with the code base and the purpose of each repository is strongly recommended.
Set up a local clone. Prepare a clone of the repository on your hard disk that is convenient for getting updates from the upstream repository and pushing changes to your fork. You’ll also use this clone to perform test builds.
Build the project. If you haven’t already done so, this will be the time to set up your development environment so that you can build FlightGear.
Create a new branch. Create a branch on your clone to isolate your changes. Use a clear and descriptive name for your branch (e.g.,
fix-menubar-typooradd-new-joystick-configs).Make changes. Make the changes on your branch in small, focused commits. Each commit should be self-contained and represent one logical change.
Test and double-check. Before you submit your changes to the FlightGear team for review, double-check your work. Ensure that your code builds and that tests pass.
Rebase and push. Check if the upstream repository was updated in the meantime. If so, rebase your work on its latest state and perform a final test run to make sure everything still works fine.
Submit a merge request. Open a merge request (MR) to propose your changes for review. Be sure to use the Merge Request Template to provide necessary context for reviewers. Feel free to ask on the developer mailing list if you’re unsure whom to add as a reviewer.
Code review. Once you have created a merge request, other developers will review your work, give feedback, and sometimes request changes be made. This is a crucial part of the development process, as it helps reduce bugs and improves code quality.
Clean up. If your merge request was applied, pull your changes from the upstream branch and delete the local branch you created for the merge request.
In order to present these steps in more detail, we’ll now assume that you intend to make your first contribution to the SimGear repository (and thus, that you haven’t already forked it). Except for the target branch name which may differ, the process would be the same for any Git repository of the FlightGear project.
Fork the Repository#
For what follows, you’ll need to create a GitLab account if you don’t already
have one. Once you are logged into your account, go to the repository home
page (here in our example) and click on the
Fork button as shown in forking-the-upstream-repo; after
filling some information, this will lead to the creation of a copy of the
upstream repository in your own GitLab namespace under
https://gitlab.com/YourUserName/.
Once you’ve clicked on the button, a new page is loaded as shown in
entering-fork-metadata. The Project name will be prominent but it’s
only a label—choose it as you wish (“My SimGear fork” in the example). For the
Project URL, you’ll want to select your GitLab username after the initial
portion https://gitlab.com/.
The Project slug is the final part of the base URL for the fork you’re about
to create; let’s choose flightgear-simgear so that all your forks of
repositories of the FlightGear project are named flightgear-something.
This way, they will be easy to distinguish from non-FlightGear repositories
you might want to publish under https://gitlab.com/YourUserName/. Beware
that if you modify the Project name, the GitLab user interface automatically
modifies the Project slug; so, better fill them in this order: Project name
then Project slug.
There are a few fields left to enter. If you choose to include only the default branch, you’ll save a little amount of space but might have to fetch other upstream branches later. Give your fork public visiblity so that reviews can take place. When ready, click on the Fork project button to actually create your fork of the upstream repository.
Set Up a Local Clone#
Since we want to pull updates from the upstream repository, it is convenient
to clone it to your hard disk and modify the clone so that pushes go by
default to your fork (which is online under
https://gitlab.com/YourUserName/). Cloning the upstream SimGear repository
can be done with:
git clone https://gitlab.com/flightgear/simgear.git
Tip
If you use download_and_compile.sh and it manages the repository you want to contribute to (this is obviously the case for SimGear), there is no need to create a new clone: you can simply use the repository clone it created on your disk.
Now, let’s add a Git remote that points to your fork of the upstream repository. We configure this remote so that pushing to it uses SSH authentication. We also configure your repository clone so that pushes go to your fork by default.
git remote add flo https://gitlab.com/frougon/flightgear-simgear.git
git remote set-url --push flo git@gitlab.com:frougon/flightgear-simgear.git
git config remote.pushDefault flo
In the above commands, replace flo (name of the created remote) with an
appropriate name of your choice; also replace frougon with your GitLab
username.
Build the Project#
Make sure you can build FlightGear using the repository clone set up in the previous step and that the resulting executables run normally. This way, you’ll be able to properly test any changes you later make in this clone.
Note
The following steps will have to be repeated for each “self-contained changeset” that you intend to contribute.
Create a New Branch#
Create a branch based on origin/next that tracks origin/next and make
sure it is up-to-date. Instead of new-branch-name, choose a name that
makes it clear what the changes in the created branch are supposed to do.
git checkout -b new-branch-name origin/next
git pull
Note
Here, origin is a remote that points to the upstream repository
you cloned from, and next is the name of the development branch
in the SimGear repository (this is also the case for FlightGear and FGData). If
you were to contribute to a different repository such as FlightGear
documentation, the branch
to base your work on might have a different name (e.g., main).
Make Changes#
Commit the desired changes to the branch you created in the previous step. If you need help with Git, this online book is a great resource.
Each commit message should start with a single, not too long summary line (no more than 72—80 characters if possible), then a blank line, then normal explanations. Example commit message:
HID: allow sending output reports from Nasal
- make watched properties only react on a value change
- refactor the larger usage enums to their own file
Like here, it is useful when the beginning of the first line is short and makes it clear to readers which part of the code (subsystem, class, etc.) is affected by the changes.
Test and Double-check#
Rebuild FlightGear with your changes, carefully test. Build the FlightGear
test suite and verify that the tests still pass. This can be done by running
make test_suite or ninja test_suite from the FlightGear build directory
(not the source repository!).
Use commands like:
git statusto check the state of your working directory and repository;git log -pto proofread your commit diffs and messages;git commit --amendto modify the most recent commit on the branch;git rebase -i ⟨ref⟩to modify commits located further in the ancestry graph (namely, descendants of commit⟨ref⟩; see the git rebase manual page for explanations).
The gitk program is not essential but can be nice for examining
commits and visualizing the commit graph. If gitk appears to see
local changes that really aren’t there, run git status then rerun
gitk.
The pre-commit and clang-format programs are useful to run code quality checks and apply the project formatting rules. Some of the configured pre-commit hooks will for instance check for common mistakes including typos, mixed whitespace or line endings, and so on. If you’ve installed the pre-commit hooks in your repository clone, pre-commit will be automatically run every time you commit.
Note
In most cases, the GitLab CI runs the pre-commit and clang-format checks as part of the automatic verifications that need to pass, before a merge request can be applied.
Rebase and Push#
If the upstream branch you started from has changed in the meantime, your work needs to be rebased on top of its latest state. This can be done with the following command:
git pull --rebase
In case someone was working on the same files as you, this may trigger conflicts (so it’s a good idea to first announce what you’re going to work on in order to minimize friction and benefit from the insight of experienced people). Conflicts don’t happen very often and it’s not the end of the world when they do. Again, this Git book is a very useful resource in such cases.
If the rebasing did grab upstream changes, perform a final build-and-test run to be sure everything works fine. Finally, push the branch to your fork:
git push
With no additional arguments, this pushes the current branch to the remote
specified with the remote.pushDefault setting, i.e. to your clone if you
followed the above instructions. Once
the push is successful, Git will show a URL; following it will
start the next step.
Submit a Merge Request#
The web page opened from the URL output by Git when you pushed to
your fork allows to create a merge request from the branch that was pushed.
From this page, select the proper target branch: for development code in
SimGear, that would be next. Select yourself as
an assignee (meaning that you are going to shape the merge request into
its final form). Select one or more reviewers to look at it—you can ask on the
flightgear-devel mailing-list if unsure, or just leave the field as
Unassigned. Don’t worry too much about the milestone (a priori, next
should do unless the merge request is specifically a fix for a release
branch). Select applicable labels, etc.
Regarding the Delete source branch when merge request is accepted option, we advise you to make sure it is enabled, otherwise your fork will soon have tons of branches. What this option does is the following: when the branch from your merge request is merged into the upstream branch, GitLab will automatically delete the merge request branch (that you pushed) from your fork. This happens online at GitLab, not in your local clone. Thus, even after this occurs, the branch will still be present locally in your clone, until you delete it yourself (cf. below).
Finally, the Squash commits when merge request is accepted option can be
used in case you pushed several commits but would rather have them coalesced
into a single one when the merge request is applied. This is something that
can be done locally using Git before pushing (in particular, with
git rebase -i), however the option is still useful in case commits are added
to the merge request after the initial push, be it by you or by reviewers.
Code Review#
After a few minutes, hours or days, you’ll receive feedback from the FlightGear developers about your merge request. Reviewing merge requests requires expertise and takes some time, so please carefully read the remarks and suggestions, follow up on the questions and requests for changes.
Clean Up#
Once the branch is merged, update the local branch of your clone that tracks
the upstream branch your merge request went to (this is the next branch in
our SimGear example):
git checkout next
git pull --rebase
(Normally, the --rebase option shouldn’t be necessary here as you
shouldn’t have any local commits on top of the upstream ones in this branch,
however it doesn’t hurt and can make things easier if you’ve been forgetful.)
You can now delete the local branch you created earlier to avoid cluttering your local clone with legacy, unneeded branches:
git branch -d new-branch-name
In case this branch hasn’t been merged exactly as is into the upstream
branch (same commit contents and metadata), Git will warn and
refuse to delete the branch unless you insist using -D. If this happens,
you’ll have to evaluate yourself (by using git log -p, by comparing
files…) if deleting your local branch new-branch-name is really the
right thing to do. In the likely case that what was merged is a strict
improvement over what you have in new-branch-name, then deleting is the
way to go.
Tip
If you really, really messed up and deleted the branch before
realizing that it was a mistake, git reflog is likely to save you:
among other things, it shows the commit hashes corresponding to
previous positions of the tips of various branches. As long as no
garbage collection occurred in the meantime (git gc), the commit
hashes are all you need to restore “lost commits”: simply create a
branch or tag from the desired commit (before doing do, you may want
to use git show ⟨hash⟩ to see the commit for a given hash, or git
log ⟨hash⟩ to examine its ancestry).
From time to time, you may also want to run git fetch -p flo (replace
flo with the name of a remote that points to your fork,
cf. Set Up a Local Clone). This removes the flo/...
branches from your local clone that have been deleted from your fork at GitLab
due to the Delete source branch when merge request is accepted option on the
merge request page (note that for instance, flo/new-branch-name and
new-branch-name are different branches in your clone; they’ll both clutter
the display when using git log or gitk until you delete them).