Collaborative Coding
It's tempting as hobbyists -- especially for those of us who are used to programming solo -- to take shortcuts in our programming practice. This could mean being neglectful with versioning, failing to properly document, or hackneying code.
Finding the shortest route from Point A to Point B might work for personal projects, but it can quickly cause headaches when sharing the codebase with others and our future selves. This is especially a problem within the Free Open-Source Software, aka FOSS, movement. FOSS features these shared codebases as a core principle, to contribute we need to understand proper collaborative coding practices.
This page is meant to give you a quick rundown of the tools/processes we as a team use, and give some links to references you may find useful in better understanding how to conduct these collaborative practices.
There are alot of places in this document where I try to to say: use your best judgement. This is more art than science. Mistakes get made, try and correct or ask for help if necessary.
Writing commit messages
A commit already contains the code changes, so the focus of the commmit messages ought to be on the reason for the change, not the change itself.
See "How to write better git commit messages" for detailed advice on writing commit messages.
Keeping an orderly git history
A readable git history is an important part of collaboration.
In a team the git history should not be an accurate record of the development history, but an informative overview of the important changes made to the source code. Thus a commit should contain one important feature, change, bug fix - something of significance.
Imagine you read through hundreds of commits with git log
- what information do you want to see?
Amend the latest commit: git commit --amend
If you have just created a commit and noticed that there is a bug, typo or other small error in that commit, you should not create a new bugfix commit. Instead, fix the bug, stage your changes and then commit with the --amend
flag. This will add your changes to the latest commit in the history and allow you to modify the commit message, if necessary, instead of adding a new commit.
After amending a commit you have already pushed, you will have to force push the amended commit to overwrite the original. Be careful not to amend commits that have already been pulled by other team members, without letting them know first.
Rewrite history with interactive rebases: git rebase -i HEAD~2
Sometimes it is necessary to change more than just the most recent commit. In this case, you should use an interactive rebase.
This command will allow you to edit, combine and remove commits from the commit history and recreate the git history anew by taking all the commits from the e.g. HEAD~2
to HEAD
and then reapplies each, giving you the ability to edit, squash or drop individual commits.
See "Git - Rewriting History" for documentation on using interactive rebases
Pitfalls when modifying the history
When you modify the git history of a branch that other team members are working on or amend a commit, that you have already pushed to a remote, make sure nobody else is working on that branch or commit while you are modifying the history.
After modifying the history, you may have to push with the --force
flag, to overwrite the existing git history on the remote. If others have pushed their work to the remote in the meantime, their work will be lost.
Thus only modify the history of branches you work on alone. And only amend commits when you are sure nobody else has pulled them already from the remote.
When you modify the history of an entire branch (and not just adding a small bugfix to the most recent commit), you should discuss this with your team first.
See "Git - Rewriting History" for further information.
How to receive modified history
Branches
When you work in a team, it's important to use branches to avoid getting into each other's way.
The decision to create a branch should often be made with these practical considerations: - Do I need to work on something specific? - Am I doing a lot of work that could collide with other's if done on the same branch? - Is this a feature, major or series of bug fixes that can be grouped together?
If in doubt, create a branch for anything that requires more than a handful of line changes.
Pull Requests
Sometimes a branch can simply be merged after it has been concluded without any review.
But if you want a second pair of eyes on your code - to ensure, for example, that you comply coding style standards or haven't made any obvious mistakes - you should create a pull request and request a review from another team member.
Further instructions on how to create a pull request can be found here.
Code Review
There are many approaches to code review, though they are all based on the same thing: you are asked to read the code and provide your opinion.
What you focus on during that reading depends on your preference. A few things you could keep an eye are: - Does the code follow our coding style? - Is this code well-documented? - Is this code readable? - Does this code have unit tests? - Are there typos or other obvious errors? - Are there alternative solutions to this problem? Should another paradigm be used here instead?
During a code review, you can write comments, request changes, approve the PR or disapprove the PR. You should use this to express your opinion on the code based on the focus that you set for your code review (if you are looking for well-documented code, you should request changes on functions lacking docstrings for example).
Code review is not an objective process. The reviewer is providing a subjective opinion, based on their experience, considerations and reading the code. This means that two reviewers can come to widely different results during code review and this is part of the strength of code reviews.
This is just one approach to writing PRs, there are many others that you can read up on, if you want a different perspective.