We always use Git for our code version control needs. No matter how big or small the project is, Git is required at all times as it allows us to track changes, revert to previous without using
ctrl-z 😨 and primarily work efficiently as a team.
Github and Bitbucket are both used depending on the nature and requirements of the project. As a general rule, this is how we decide which service to use:
- Private repositories for native mobile applications (iOS and Android) as most Continuous Integration providers only work with Github
- Private repositories for web projects for clients who already use Github for their organization
- Public repositories for open source projects developed by us
- Bitbucket private repositories for everything else
Our methodology is mostly inspired from git-flow which basically allows to separate works by branch types: feature, bug, chore and release.
- By default, there must be 2 branches:
development. Both branches must be created when setting up the code repository.
masterbranch is the version in production
developmentbranch is the version currently on the staging environment
- No one should commit directly to either the
- Commit history rewrites on either the
developmentbranch must be avoided at all costs as it could leave the project in a dire state
Branches names must be hyphenated:
feature/list-job-positions bug/user-reset-password chore/setup-segment
- All features, bugs, chore and releases branches must be checked out locally from the
developmentbranch. By avoiding branching more than one node away from the main branch, we can easily avoid complex conflicts and rebasing which can take hours or days to solve
- The definition of what constitutes a feature, bug or chore depends on the user story type. No code should be committed if there is not a user story for the tasks at hand
- Releases branches are required when opening a pull request to merge code into the
masterbranch. No code is merged directly into the
- Release branches name must contain the corresponding version number e.g.
- Write clear and precise messages for each commit
- Commit regularly to avoid losing any massive amount of changes
- Stage file changes in a meaningful way i.e. commit changes for a group of files together with a good commit message. All staged files must correspond to the same change. If you’re using the word “and”, then this probably is a good indicator that you might need to split it up in to a separate commit
User Story IDbetween brackets
]at the beginning of each commit message:
[<User Story ID>] Commit message
This serves two main purposes:
- Traceability of each commit which is very useful when rebasing, cherry-picking and merging
- Integration with our project management tool as commits will be displayed in the user story card
Write meaningful commit messages. Think that there is a high chance that you or someone else will be reading this commit message a few years from now. What would you like to communicate to your future self or developer about?
[<User Story ID>] Implement change because ... [<User Story ID>] Fix the error triggered by ... in the following situation ... [<User Story ID>] Setup this chore so that ...
Everyone has their own preferred way of styling their commit messages, but as a team we need to agree on one convention only. This will lead to improved readability and clear expectations:
Capitalization, as we should read the commit message as a sentence
[<User Story ID>] Add capitalized commit message
No limit to the length of maximum allowed characters, as we should describe our commit messages as detailed as possible for a better understanding
Start your commit message with a verb, so there’s a clear expectation of what action has been taken. This must be specified in the present tense
[<User Story ID>] Remove ... [<User Story ID>] Fix ...
Periods are only acceptable when our commit messages span over multiple sentences
Colons are verbose and break the sentence principle, so don’t use these
Commits of incomplete features must be appended with the suffix
wipat the end of the commit message
[<User Story ID>] Commit message wip
Once code is merged into the
master branch, we keep track of versions by using git tags.
- Add a tag locally corresponding to the version release from the
masterbranch. Push the local tag to the remote code repository
- Add changelog in the commit message for the tag following this convention:
- List changes as a bullet point list
- Use story title for new features
- As a user I can view the list of job positions
- Mark bug fixes with the prefix
- Fix: Login with LinkedIn
- Mark bug fixes with the prefix
- Chore: Set up staging environment
In order to release a new version, it is required to combine a few of the aforementioned techniques:
- Checkout a release branch from the
developmentbranch. Naming for the branch should follow the pattern
- Open a pull request with the release branch as origin and the
masterbranch as destination
- Once the pull request is approved and / or the test suite has run successfully, merge the release branch
- Add a git tag for the version e.g.
git tag -a 1.0.0with releases notes when entering the interactive mode
- Push newly added tag to the remote with
git push --tags