Let’s explore pre-commit
a more structured way to commit history and how to make it easier for people to contribute to your projects
Photo by Yancy Min on Unsplash
In order to keep commits aligned across all repositories, we should use the Conventional Commits specification.
The Conventional Commits specification is a lightweight convention on top of commit messages. It provides an easy set of rules for creating an explicit commit history; which makes it easier to write automated tools on top of it.
Conventional Commit makes it easier for people to contribute to your projects, by allowing them to explore a more structured commit history.
Commit
Each code commit should have some basic details about the commit and the ticket description. It will be easier to track the ticket from commit. It will be easier for team members to understand and follow the pattern if each team member is following the same way.
Pull Request
Each PR should contain ticket details and the title of the PR. It should also contain the type of ticket so team members can check if it was a feature/enhancement or bug fix.
In general, the commit message should be structured as the following pattern:
<type>[optional scope]: [REFERENCE-1234] <description> [optional body] [optional footer(s)]
Real-world examples can look like this:
chore: [PRJ1-123] run tests on jenkins ci fix(server): [PRJ2-1234] send cors headers send CORS headers by reflecting the origin header in the request feat(blog): [PRJ2-1234] add comment section
Examples
Commit message with scope, description, and breaking change footer:
// without scope feat: allow provided config object to extend other configs BREAKING CHANGE: `extends` key in config file is now used for extending other config files // with scope feat(lang): add Polish language
Commit message with multi-paragraph body and multiple footers:
fix: prevent racing of requests Introduce a request id and a reference to latest request. Dismiss incoming responses other than from latest request. Remove timeouts which were used to mitigate the racing issue but are obsolete now. Reviewed-by: Z Refs: #123
One recommendation is to use the revert
type, and a footer that references the commit SHAs that are being reverted:
revert: let us never again speak of the noodle incident Refs: 676104e, a215868
Commit Types
Use the following as a guideline as to what types you could use for your commits.
Credit: Android Academics
Real-world examples can look like this:
How to setup for Android
To get commit linting going follow the below steps.
- Install the
pre-commit
package using brew:
brew install pre-commit //check version after installatio complete pre-commit --version
2. Run the following command in your project directory:
pre-commit install -t commit-msg -t pre-commit -t pre-push - allow-missing-config
3. Add pre-commit plugins to your project. Create the config file .pre-commit-config.yaml
in your project directory:
default_stages: [commit, push] repos: - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook rev: v2.1.0 hooks: - id: commitlint stages: [commit-msg] additional_dependencies: - "@commitlint/config-conventional" - conventional-changelog-conventionalcommits - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.4.0 hooks: - id: check-json - id: check-merge-conflict - id: detect-private-key - id: no-commit-to-branch - repo: https://github.com/jguttman94/pre-commit-gradle rev: v0.3.0 hooks: - id: gradle-spotless args: ['-w', --wrapper]
4. Add lint to your project. Create the config file commitlint.config.js
in your project directory:
module.exports = { extends: ["@commitlint/config-conventional"], // Validate for issue/ticket numbers parserPreset: { parserOpts: { // these are samples, add possible prefixes based on your project requirement issuePrefixes: ['ANDR-', 'TEST-','DSC-', 'ABC-', 'CO-'] } }, rules: { "body-leading-blank": [ 1, "always" ], "footer-leading-blank": [ 1, "always" ], "header-max-length": [ 2, "always", 72 ], "scope-case": [ 2, "always", "lower-case" ], "subject-case": [ 2, "never", [ "sentence-case", "start-case", "pascal-case", "upper-case" ] ], "subject-empty": [ 2, "never" ], "subject-full-stop": [ 2, "never", "." ], "type-case": [ 2, "always", "lower-case" ], "type-empty": [ 2, "never" ], "type-enum": [ 2, "always", [ "build", "chore", "ci", "docs", "feat", "feature", "fix", "perf", "refactor", "revert", "style", "test" ] ] } };
Job Offers
5. Commit the added files to your repository
The output should look like this:
> git commit -m 'fix: [TOL-6911] test lint' [INFO] Initializing environment for https://github.com/alessandrojcm /commitlint-pre-commit-hook:@commitlint/config-conventional, conventional-changelog-conventionalcommits. Fix End of Files.........................................................Passed Check JSON...........................................(no files to check) Skipped Check for merge conflicts................................................Passed Detect Private Key.......................................................Passed Don't commit to branch...................................................Passed [INFO] Installing environment for https://github.com/alessandrojcm /commitlint-pre-commit-hook. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... commitlint.............................................................. .Passed - hook id: commitlint - duration: 0.43s [branchify-devops-changes fde84e2] fix: [TOL-6911] test lint 1 file changed, 3 insertions(+), 3 deletions(-)
Done, you now have a commit message linting in place.
Moreover, since we have a detection of unexpected secrets, you would need to set up the first baseline:
- Install a detect-secrets tool (it is as easy as
pip install detect-secrets
). - Run
detect-secrets scan > .secrets.baseline
in your project directory. - Commit the added files to your repository.
Done, you now have a baseline for detecting unexpected changes related to secrets.
Try the following command to validate:
git commit --allow-empty -m ""
Let’s take a step to move to clean commit, Just the way we are moving to clean code 😉
More from the Author
Code Commit Guidelines using Conventional Commits
Resources
- IntelliJ plugins that support conventional commit
- https://plugins.jetbrains.com/plugin/13389-conventional-commit
- https://plugins.jetbrains.com/plugin/13477-git-commit-message-helper
Thanks for reading this article. Hope you would have liked it!. Please clap, share, and subscribe to my blog to support.
This article was previously published on proandroiddev.com