In this page
Working with Git commit policies
Installing Git hooks
Installing Git hooks for remote verification
Installing Git hooks for local verification
Comparing remote (server-side) vs. local (client-side) verification
Git commits
Fixing the last Git commit
Fixing any earlier Git commit
Video tutorial: Rewriting Commit Messages in Git (2:34)
Fixing commits with TortoiseGit
Git branches
Fixing rejected branches
Git tags
Fixing rejected tags
Git merges
Git rebasing
Git cherry-picking
Further reading
How to implement GitOps secured by commit policies?
More about Git hooks
Further recommended apps
Overview
This page is about implementing Better Commit Policy with the Git version control system. For non-Git-specific information, please see the starting page of the user manual.
Working with Git commit policies
Installing Git hooks
Installing Git hooks for remote verification
The distributed nature of Git allows you to select between multiple workflows. Accordingly, you also have some flexibility in choosing where to install the hook scripts.
The hook script must be installed to the blessed repository, at least. The blessed repository is the central hub for the developers, and it contains the reference source code. It is absolutely critical to verify the commit policy there.
In addition, you can also install the hook script to:
- to the developer public and integration manager repositories, if you use the integration manager workflow
- to the dictator and lieutenant repositories, if you use the dictator and lieutenants workflow
- to all possible forks and in-between repositories, if you use some other type of workflow
- to local clone repositories on the developers' machines to verify commits as early as possible (before they happen!)
Installing the hook scripts to these additional repositories will make your policies more efficient, as they are verified earlier in the process. The sooner a commit gets rejected, the cheaper to fix it.
When the hook script is installed to multiple repositories, all the hook scripts should verify the same policy. This ensures that the rules are verified consistently in the blessed repository and all clones. You can modify the rules any time, and those changes will be immediately reflected in all the repositories referencing them.
Note: the earliest (thus best) opportunity to validate a commit policy is in the developer's local clone repositories, using so-called client-side hooks.
Installing Git hooks for local verification
Local (client-side) hook scripts make verification of changes possible at commit time, or more precisely, before commit time! They essentially do the same job that their server-side counterparts do at "push time", but they do it right on the developer's machine at "commit time".
The idea is that if an invalid commit is rejected before that is actually made, then there is no need to fix commits ever! This eliminates the efforts required to fix rejected commits, and makes your team faster and more productive. If your developers find it frustrating that their pushes are rejected, using local verification will drastically improve their experience.
How does it work? When a set of files is being committed and commit message is entered, the locally installed hook script contacts the Jira server to verify the commit against the configured policy. If the verification fails, a rejection message is shown and the commit gets aborted; if if succeeds, the commit passes silently.
Please note that Better Commit Policy is the only commit verifier app for Jira that enables local verification and allows working fast while enforcing a policy.
To install a client-side hook, go to Commits (in the top) → Commit Policies → click Apply to a repository at the policy, then choose the "commits are verified in my local repository (clone)" option in the Hook Script Wizard and follow the installation steps. This is a self-service procedure, that we made as fast and as painless as possible.
Please note that when using client-side hooks, you will need a working connection to the Jira instance, otherwise the commit will fail. If you are offline, git provides the --no-verify command-line option to skip the local verification process:
git commit --no-verify
Local verification do not replace server-side verifications, obviously. Server-side verification should be in place to implement the ultimate policy checking mechanism, and local verification should be used to save headache and to move faster.
Comparing remote (server-side) vs. local (client-side) verification
To see the difference between remote and local verification and to understand how the latter accelerates your team's work, watch this video:
Git commits
If you are using server-side hooks only, you can create multiple commits without pushing those to the blessed repository. In this case, the verification of the commit policy is delayed until the moment when you actually push your changes to the blessed repository. When it finally happens, all commits will be verified in one go and all will be rejected if there is at least one commit that violates the policy. You should then fix the problematic commit and push your changes again.
In the following sections we will explain how to fix various types of problems.
This is important to understand that if you also use local hooks, you will not be able to create commits that violate the policy. If you tried to create one, that would be immediately rejected. Therefore, there is no need to fix anything, you should re-create the commit, this time correctly. We definitely suggest using local hooks as those enable you work faster.
Fixing the last Git commit
If it was the last commit that needs to be fixed, you can easily rewrite its commit message like this:
git commit --amend -m "PLYR-419 fixed: close the video outstream"
You can also use the --amend option to modify the list of files in the commit. Just use git add and git rm to modify the index, then make a git commit --amend to re-commit the changes.
When using a Git GUI client, just commit again with selecting the "Amend" option. It will allow you to modify the previously made commit, and enter the correct commit message or select the correct file list.
Fixing any earlier Git commit
If you need to modify a commit that was made prior to the very last one, you will need to use interactive rebasing. It takes a couple of smaller steps, please read the related tutorial in official Git book.
For example, if you need to modify the commit message of the commit prior to the very last one, start the rebasing session with this command ("2" is the number of the commits you wanted to edit):
git rebase -i HEAD~2
When the editor opens, select the "r" (reword) command to edit the commit message.
Interactive rebasing is a super-powerful command: in addition to rewriting commit messages, it also allows you to reorder, squash or split commits. We strongly suggest to read the interactive rebasing tutorial, if a clear Git history is important to you (it should be).
Video tutorial: Rewriting Commit Messages in Git (2:34)
This YouTube video shows a two minute demo of the two methods described in the previous sections:
Fixing commits with TortoiseGit
TortoiseGit is a popular Windows shell interface for Git. It is fully supported by Better Commit Policy.
If you want to fix the last commit, simply open the Commit dialog and tick the Amend Last Commit checkbox right below the commit message box.
If you want to fix an earlier commits (by a full rebase), do the following steps:
- Right click in your working directory and choose TortoiseGit → Show log from the context menu.
- From the commit list, find the latest commit that you do not want to include in the rebase process.
- Right click on that commit and choose Rebase <branchname> onto this.
- Tick Force Rebase checkbox.
- For each commit, set the action you wish with the right-click menu (Pick, Squash, Skip, etc.)
- Click the Rebase button and after everything is done, click Commit.
Git branches
(since 3.0.0)
Git branches are supported since app version 3.0.0, while pre-3.0.0 app versions silently ignore branches.
Branches are verified by the branch rules when being pushed to the repository which has the hook script installed.
It is important to understand that branch conditions will verify both the branches themselves at creation and the commits on those branches any time later. For example, if you create branch with a disallowed name, then both the branch and all commits on that branch will be rejected. To resolve the situation, fix the branch name, no need to touch the commits, and push the result again.
Fixing rejected branches
Fixing a rejected branch is as simple as renaming it to satisfy the policy. To rename the rejected branch glogin to the more standard name feature/FOO-123-login-with-google which also incorporates the related issue's key:
git branch -m glogin feature/FOO-123-login-with-google
Note that it is perfectly safe to rename branches locally.
Git tags
(since 3.0.0)
Git tags (both lightweight and annotated tags) are supported since app version 3.0.0, while pre-3.0.0 app versions silently ignore tags.
Tags are verified by the tag rules when being pushed to the repository which has the hook script installed.
Fixing rejected tags
Fixing a rejected tag is as simple as renaming it to satisfy the policy. To rename the rejected tag v3-maintenance to the semantic version number 3.1.1, create the tag with the new name and then drop the old one:
git tag 3.1.1 v3-maintenance ## create the new name referencing the same commit as the old name git tag -d v3-maintenance ## delete the old name
Note that it is perfectly safe to rename tags locally.
Git merges
Git merges are fully supported by Better Commit Policy.
When merging, the commits originally created on the source branch will appear also on the target branch. Depending on the accept existing commits without verification option, those will or will not be verified again.
If there is no divergent work to merge, i.e. if it was a so-called "fast-forward merge", then that's it.
If there is actual work to merge, then an additional merge commit will be created. Depending on the accept merge commits without verification option, this will or will not be verified.
Git rebasing
Git rebasing is fully supported by Better Commit Policy.
The same rules apply as to Git merges, so please see that section.
Git cherry-picking
When cherry-picking changes, new commits will be created on the target branch. Git cherry-picking is fully supported by Better Commit Policy, with one important remark.
Depending on the hook script:
- Server-side hooks: cherry-picked commits will be verified the same way as any other "regular" commits.
- Client-side (local) hooks: cherry-picked commits will not be verified. This is due to a technical limitation in Git: Git will not trigger "pre-commit" hooks when cherry-picking.
Further reading
How to implement GitOps secured by commit policies?
GitOps is a set of practices that make Git the single source of truth and the central control mechanism in a software project. One of the key GitOps practices is to use automation wherever possible.
If you are using the Better Commit Policy app with Git, you can easily implement GitOps with its companion app called Better DevOps Automation.
With this combination:
- All code, infrastructure and configuration changes will be first verified by the Better Commit Policy app.
- Only if the changes were correct, the Better DevOps Automation app can trigger a CI/CD build, send a Slack or email notification, or execute a script that automatically deploys the changes from the repository to production.
More about Git hooks
The hook scripts that are auto-generated by Better Commit Policy can be easily installed into Git repositories, and the app guides you through the process.
Nevertheless, if you wanted to understand what happens under the hood, see the Customizing Git - Git Hooks chapter from the Pro Git book.
Further recommended apps
When you use Better Commit Policy to enforce issue keys in the commit messages, you should also try the Git Integration Plugin for Jira. That app will display the commits mentioning a specific issue key in the View Issue screen, giving you a nice history of Git commits related to that issue. They really play together really nicely: Better Commit Policy encourages a good practice, and then the result is made visible by Git Integration Plugin.
Questions?
Ask us any time.