Committing Code

Hero image for Committing Code


  • Capitalize the first word as a commit message must be read like a sentence.

    [<User Story ID>] add capitalized commit messages
    [<User Story ID>] Add capitalized commit messages
  • Start commit messages with a verb, so there is a clear expectation of what action has been taken. This must be specified in the present tense.

    [<User Story ID>] Removed ...
    [<User Story ID>] I fixed ...
    [<User Story ID>] Remove ...
    [<User Story ID>] Fix ...
  • Periods are only acceptable when commit messages span over multiple sentences.

    [<User Story ID>] Remove unused dependencies.
    [<User Story ID>] Remove unused dependencies. These were breaking the staging server.
  • Colons are verbose and break the sentence principle, so don’t use them.

    [<User Story ID>] Remove unused dependencies: Ruby and JavaScript
    [<User Story ID>] Remove unused Ruby and JavaScript dependencies
  • No limit to the length of maximum allowed characters, as commit messages should be as detailed as possible for a better understanding.

Message Structure


  • Include the user story ID between brackets [ ] at the beginning of each commit message:

    [<User Story ID>] Add the list of job positions

    When the pull request references a GitHub issue, the user story ID must be prefixed with #:

    [#<User Story ID>] Add the list of job positions

    This serves two main purposes:

    1. Traceability of each commit is very useful when rebasing, cherry-picking, and merging.
    2. Integration with the team’s project management tool as commits will be displayed in the user story card.
  • Commits of incomplete features must be appended with the suffix wip at the end of the commit message.

    [<User Story ID>] Add the list of job positions wip

Skip CI

To not waste CI/CD resources, skip the build if it is expected to fail or be re-triggered again. To achieve that, a [skip ci] prefix can be included in the commit message structure. For example:

[skip ci] [<User Story ID>] Add the list of job positions
# or
[skip ci] [#<User Story ID>] Add the list of job positions

There are several tags to allow skipping builds supported by various CI/CD platforms such as [skip ci], [ci skip], or even [no ci], [skip actions], etc. depending on the platforms. For consistency purposes, let’s stick with the [skip ci] tag.

Later on, if there is a need to start a build back, simply use the Git command - amend to remove the [skip ci] tag from the most recent commit message.

Skipping builds via commit messages is more of a generic approach that most of the CI/CD services out there can support such as GitHub Actions, Bitbucket, GitLab CI/CD Pipeline, Codemagic, CircleCI, and even Bitrise, etc. but it requires more knowledge on handling commit messages to enable/disable.

When to skip the pipeline

  • When a pull request is marked as a draft pull request. → More commits can still be introduced later on and thus triggering the builds at this point is usually unnecessary.

  • When a pull request’s branch is based on a branch other than the primary develop branch. → This is more commonly seen in large teams where multiple branch implementations for the same feature depend on each other as explained here. Triggering a workflow at this point is unnecessary because more rebase actions/conflicts are introduced until the rebase happens on the latest develop branch.

  • When a pull request has a base branch as the develop branch, but the develop branch is going to be updated before the pull request can be merged. → This usually happens when multiple branches are ready for review and are based on the develop branch simultaneously. The Team Lead will normally merge pull requests with enough approvals ordered by the creation date. Triggering a workflow at this point is also unnecessary until the pull request is fully ready to be the first to get merged.

The above scenarios are just common examples that surfaced from most of the client projects. In the end, skipping CI builds can be performed whenever there is an actual need and is not limited or constrained to these cases.

Best Practices

  • Write clear, precise, and meaningful commit messages. Think that there is a high chance that the author 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 other developers?”

    [<User Story ID>] Implement change because ...
    [<User Story ID>] Fix the error triggered by ... in the following situation ...
    [<User Story ID>] Set up the build process so that ...
  • Do not write commit messages like Resolve feedback, Fix all comments or combine all unrelated code changes in one commit when taking care of reviewer feedback. Instead, write meaningful commit messages that reflect the 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 the commit message uses the word “and”, then this probably is a good indicator that the commit might need to be split it up into separate commits.

  • Commit regularly to avoid losing any massive amount of changes while working continuously on a large task.