Skip to content

Branching Strategy

Alexander V. Wolf edited this page Jul 19, 2021 · 11 revisions

Branches

There exist a few important branches in the Stellarium repository.

  • master branch: branch used for producing releases. Commits in this branch should not break compilation or introduce bugs.
  • release branch: same branch as master, but used for CI services to reduce number of calls to produce binary packages.
  • Feature branches: short-lived branches used e.g. for Pull Requests
git checkout -b my-new-feature-branch
<edit as you need>
git stage <files>
git commit
git push --set-upstream origin my-new-feature-branch

Try to keep a linear git history on master

  • merge commits to master should be avoided. Rebase your feature branches before pushing them to master and remember that you must re-test a rebased branch before pushing.
  • some branches take long to develop. Rebase them occasionally to let them "grow out of the current master".
git checkout mybranch
git rebase master
<fix issues and commit as needed>
git push -f origin HEAD:mybranch

This rebasing is OK on branches developed by single or closely coordinated team members. In general, beware of "changing history" too much.

  • you should always close all applications (such QtCreator) before starting a rebase, otherwise directory permission conflicts and incomplete disc synchronisation issues are very likely to occur. This also holds true when committing.
  • if you need to merge some fixes from a maintenance branch to master, it is better to cherry pick the patches instead of merging.
  • be aware that files managed by some applications (XML and the like, config, JSON, ...) can be very tricky to merge/rebase due to their "pseudo-binary" nature. It is exceptional that such applications provide features to perform merging. Sometimes the only solution to merging/rebasing is to manually perform the three-way merge by opening all required instances of the objects in separate instances of the editor application, and carefully reapply and recombine all edit actions. This is a far from trivial process that is likely to produce bugs.

Various tips and tricks

I keep rebasing, and run into the same merge conflicts each time

Use git's rerere feature:

git config --global rerere.enabled true

This will cache your merge resolution and can automatically apply it next time you rebase.

Oops - forgot branching

Sometimes it can happen that you start to add some changes in your master without making a branch first. "Just try out something". Then you are interrupted and should continue elsewhere. You can stash your work and unstash it into a new branch.

git stash
git stash branch my_little_changes_which_need_more_thoughts

This also switches to the new branch. To continue in the master branch (just to compile it cleanly), commit these changes and git checkout master again. You will also see the new branch listed via git branch.

Friendlier remote names

Git uses default names for repositories, such as origin. This is an unfortunate default value, as it can be confusing and can be a problem when you routinely push to different repositories within a project.

When you track several repositories (of course including stellarium, the main one), it can help to rename repositories using folder names.

git remote # lists all you repositories
# rename the official repo to a friendlier name
git remote rename origin stellarium
# rename your public repo
git remote rename <whatever> my-github
# group all remote user repositories
git remote add user/abalkin 	https://github.com/abalkin/stellarium.git
git remote add user/ray		https://github.com/rayw000/stellarium.git
git remote add user/ultrapre	https://github.com/ultrapre/stellarium.git
# now the listing becomes far more nice
git remote
my-github
stellarium
user/abalkin
user/ray
user/ultrapre

Note: upstream is also a good suggestion to replace origin.

Manage branch names

You will soon discover that you will be submerged by local as well as remote branches. Git offers a powerful feature to manage this namespace, by allowing to move branch names (as well as remotes) into subdirectories

Here is an example.

git branch --remotes | grep "stellarium/"
...
  stellarium/SH_AlmagestSkyculture
  stellarium/african-sky-cultures
  stellarium/android-port
  stellarium/astrocalc-ephemeris-refactoring
  stellarium/avoid-sun-streak
  stellarium/aw_svgTextureSupport
  stellarium/catalan-sc
  stellarium/coverity_scan
  stellarium/debian-packaging
  stellarium/dynamic-mgr-plugins
  stellarium/fix-orbit-lines
  stellarium/fix-orbits
  stellarium/fix-orbits2
  stellarium/fix_telrad
  stellarium/gz_AtmosphereTweaks
  stellarium/gz_aberration
  stellarium/gz_curvatureFix
  stellarium/gz_reduceOpenGLstateChanges
...
# by moving branch names into "subdirectories" one can achieve a better overview:
git branch rename stellarium/SH_AlmagestSkyculture stellarium/user/sh/SC/AlmagestSkyculture
git branch rename stellarium/gz_aberration stellarium/user/gz/feature/aberration
...
# Here is what can be achieved:
# notice that even in this example, improvements are possible!
git branch
...
  contrib/1315/comet-icon
  contrib/algol-types
  contrib/astrocalc/iprove-graph-label
  contrib/astrocalc/notes
  contrib/dbl-click-shortcut
  contrib/dlg
  contrib/general/startpage
...
  user/ajk-alex
  user/ajk/navstar
  vendor/etwright/almagest
...

This approach allows you to keep a high level overview by grouping branches that logically belong together (eg contributor branchess, main branches such as master and release, tests, maintenance branches, vendor branches, etc). This also applies to names of remotes and tags.

Such approaches will prevent a explosion of names in the namespaces of remotes, branches and tags.

In some Git clients (such as e.g. SourceTree), using subdirectories in names will produce a nice tree of remotes, branches and tags.

Note: Git implements this tree by physically using subdirectories; this means that you cannot create objects (names of remotes, branches, tags) that exist as a directory. Take a look at .git/ to discover this.

Clean up!

From time to time, perform some cleanup, get rid of old branches, etc:

git fetch --prune --prune-tags --verbose
git prune --verbose
git gc