Skip to content

Working conventions

Jan Stolarek edited this page May 3, 2019 · 11 revisions

This page outlines various working conventions for developing Links code and gives instructions how to follow these conventions.

Using git

Merging git branches and pull requests should be done only using fast-forward merges and not merge commits. This will keep the git history easy to read for humans. Results of git bisect will also be much easier to understand.

Turning off merge commits

To make sure that you don't introduce merge commits into git history turn them off by running:

git config --global merge.ff only

This instructs git to use fast-forward merges only and prevents accidentally creating merge commits. If it is not possible to merge a branch with a fast-forward merge then the merge will be aborted. If you want to create a merge commit you will have to request it explicitly with:

git merge --no-ff

Merging github pull requests to avoid merge commits

Say that somebody created a pull request called foo. Assuming you are on the up-to-date sessions branch you can merge the pull request from the command line by running the following commands:

git fetch origin                # grab the pull request from origin repository
git checkout -b foo origin/foo  # create a local branch for the pull request
git rebase master               # rebase a pull request on top of latest changes
git checkout master             # switch to sessions branch
git merge foo                   # merge pull request into sessions
git push                        # push changes to the public repo

Remember to replace foo with the actual name of the pull request branch. Last step assumes that you are tracking the master branch from origin repo. If not, then you need to run:

git push origin master

Two crucial parts in the above procedure are:

  • using rebase in step (3). This ensures that changes in the pull request are applied on top of the latest code in the repository. Note that if the pull request branch is already rebased on top of latest changes in the repository this will be a no-op.
  • using fast-forward merging in step (5) - assuming you've configured git to use fast-forward merges only, as described above. If you have not configured git to only use fast-forward merges then it is recommended that you use --ff-only flag as a safeguard. Note that git by default will use fast-forward merging whenever possible and it will be possible in this scenario since we have done a rebase in step (3).

Merging your own branches to avoid merge conflicts

This is essentially the same as merging pull requests. The only difference being that in step (2) you don't create a new branch but instead checkout an existing one. So assuming that you have a branch called bar and you are on an up-to-date sessions branch you would need to type:

git checkout bar      # create a local branch for the pull request
git rebase master     # rebase a branch on top of latest changes
git checkout master   # switch to sessions branch
git merge bar         # merge pull request into sessions
git push              # push changes to the public repo

Interactive rebasing

You can run rebase in interactive mode by providing -i switch. To rebase your current branch interactively on top of master branch you need to run:

git rebase -i master

This will allow you to clean up commit history during a rebase by:

  • squashing commits. Useful when the branch contains lots of small work-in-progress commits that don't really matter.
  • reordering commit history.
  • omitting some commits.
  • editing commit messages.

Pulling & rebasing at the same time

Say you are working on some minor change and have not bothered to make a separate branch for it. To ensure that you don't create a merge commit when pulling from the repo you should use --rebase flag:

git pull --rebase

This fetches the latest changes on the remote branch, merges them into the local branch and then rebases your local changes on top of pulled remote changes. Note: this is simple and will work most of the time. Nevertheless this workflow is definitely not recommended if your local changes are large.

Dealing efficiently with rebase conflicts

If you are working on a large feature branch that you are often rebasing against latest changes you might find yourself resolving same merge conflicts over and over. Git has a hidden feature called rerere (reuse recorded resolution) to help in such scenarios. Enable rerere with:

$ git config --global rerere.enabled true

See here for a detailed explanation.

Code conventions

Trailing whitespace

Introducing trailing whitespaces to the source code will cause CI to fail. To avoid adding them by accident add these two lines to your .emacs configuration file:

(setq-default show-trailing-whitespace t)
(setq-default indicate-empty-lines t)

This will highlight trailing whitespaces so that they don't go unnoticed. You can also delete all trailing whitespaces in a file with M-x delete-trailing-whitespace.