In this page

Overview

This page is about implementing the Commit Policy Plugin with the Mercurial version control system. For non-Mercurial-specific information, please see the starting page of the user manual.

Working with Mercurial commit policies

Installing Mercurial commit hooks

The distributed nature of Mercurial 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 all the developer forks and in-between repositories. 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.

It is important to note that the earliest (thus best) opportunity to validate a commit policy would be in the developer's local clone repositories, using so-called client-side hooks. This feature is not available in the app yet, but we're seriously considering this. Please read the next section.

Client-side scripts

Scripts executed by the hooks in the developers' local clones represent the earliest opportunity to verify commit policies. These allow to verify when the developer commits a change, that may be well before he pushes that!

Mercurial, unfortunately, does not clone the hook scripts when cloning a remote repository. Therefore, commit policies will not work automatically in a clone, after cloning a repository with the hook scripts set up.

Although Mercurial doesn't support this directly, we have several ideas to work around this limitation.

If this feature would be important to you, please vote and comment on this feature request.

Fixing rejected Mercurial commits

In Mercurial, you can create any number of commits without communicating with the blessed repository. Thus, the verification of the commit policy is delayed until you push your changes to the blessed repository. When you finally do push, all commits will be verified in one go. The whole set of commits will be rejected if there is only commit that doesn't satisfy the conditions prescribed by the policy.

Fixing the last Mercurial commit

If it was the last commit that needs to be fixed, you can easily rewrite its commit message like this:

hg commit --amend -m "PLYR-419 fixed: closing the video outstream"

You can also use the --amend option to modify the list of files in the commit. Just use hg add and hg rm to modify the index, then make a hg commit --amend to re-commit the changes.

When using a Mercurial 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 Mercurial commit

If you need to modify a commit that was made prior to the very last one, you will need to use the HistEdit extension. First you need to enable that by modifying your .hcrc file. Editing the history takes a couple of smaller steps, please read the related tutorial in the extension documentation.

For example, if you need to modify the commit message of an older commit (that is not pushed yet), start the history rewriting with this command:

hg histedit --outgoing
Alternatively, you can rewrite the history from a specific revision "17" this way:
hg histedit 17
When the editor opens, select the "m" (mess) command to edit the commit message.

Please note that Histedit allows you to rewrite only the commits in draft phase, i.e. the ones that are not published for your fellow developers yet. (Public phase commits, in contrary, should never be rewritten.)

Histedit is a super-powerful tool: in addition to rewriting commit messages, it also allows you to freely edit, combine, or delete commits. If clear Mercurial histories are critical to you, we strongly suggest to read the Histedit extension page.

For the sake of completeness, it should mentioned that there are other ways to rewrite commit histories with Mercurial: see the rollback command or the Evolve extension, for instance. Even with these, we recommend using the commit --amend command and the Histedit extensions as the battle-tested methods.

Using TortoiseHg

If you want to amend the very last commit, simply open the Commit dialog, and look for the Commit changes button in the bottom. Click the dropdown marker in the right part of this button and choose Amend current revision.

Options are not that good if you want to alter older commits. Histedit is unfortunately not yet available on the GUI. On the contrary, you may use older extensions like MQ but it is strongly discouraged. We recommend using the command line until that feature gets implemented in TortoiseHg: in TortoiseHg Workbench, choose View → Show Console from the menu.

Fixing commits with TortoiseHg

TortoiseHg is a popular Windows shell interface for Mercurial. It is fully supported by the Commit Policy Plugin.

If you want to fix the last commit, simply open the Commit dialog, and look for the Commit changes button in the bottom. Click the dropdown marker in the right part of this button, and choose Amend current revision.

Options are not that good if you want to fix earlier commits, unfortunately. The Histedit extension, which we primarily recommend for modifying Mercurial commits, is not available via the GUI yet. Although using other extensions like MQ could be an option, it is strongly discouraged. Until this feature gets implemented in TortoiseHg, we recommend using the command-line Mercurial client: in TortoiseHg Workbench, choose View → Show Console from the menu and then follow these instructions.

Mercurial bookmarks and branches

Mercurial bookmarks and named branches are fully supported by the Commit Policy Plugin.

Creating a new bookmark in Mercurial results in simply adding a new revision pointer. This is totally transparent for the Commit Policy Plugin: it will not be verified, as it does not create an actual commit.

Creating a new (effective) branch in Mercurial requires you to create commits on that branch, because the branch name is part of the change set metadata. These commits, obviously, will be verified by the Commit Policy Plugin.

The branch objects themselves are not verified by the Commit Policy Plugin, though. (If you need to verify branches for naming conventions or similar, please vote or comment for this feature request.)

Mercurial merges

Mercurial merges are fully supported by the Commit Policy Plugin.

When merging, new commits originally created on the source branch will appear on the target branch. Those will be (re-)verified on the target branch the same way as any other "regular" commit.

There will also be an additional merge commit created. Merge commits are not verified by the Commit Policy Plugin, by design. The idea is that merge commits are not introducing "actual" changes, they merely exist for administrative purposes and as containers for resolved conflicts.

Mercurial graft

Mercurial graft is fully supported by the Commit Policy Plugin.

When grafting (cherry-picking) changes, new commits will be created on the target branch. Those are verified by the Commit Policy Plugin the same way as any other "regular" commit.

Mercurial tags

Mercurial tags are fully supported by the Commit Policy Plugin, including both local and regular tags.

When you create local tags, those are stored in a file called .hg/localtags. This file is not under version control, thus working with local tags is transparent to the Commit Policy Plugin.

When you create regular tags though, those are stored in a version controlled file called .hgtags. As this file is under version control, working with tags results in new commits. The commits generated by adding tags are verified by the Commit Policy Plugin, and in case the policy is violated, those should be fixed the same way as regular commits.

The tag objects themselves are not verified by the Commit Policy Plugin. (If you need to verify tags for naming conventions or similar, please vote or comment for this feature request.)

Further reading

More about Mercurial hooks

The hook scripts that are auto-generated by the Commit Policy Plugin can be easily installed into Mercurial repositories, and the app guides you through the process.

Nevertheless, if you wanted to understand what happens under the hood, see the Handling repository events with hooks chapter from the Mercurial: The Definitive Guide book.

When you use the Commit Policy Plugin to enforce issue keys in the commit messages, you should also try the Jira DVCS Connector Plugin. That app will display the commits mentioning a specific issue key in the View Issue screen, giving you a nice history of Mercurial commits related to that issue. They really play together really nicely: Commit Policy Plugin encourages a good practice, and then the result is made visible by the DVCS Connector Plugin.

Questions?

Ask us any time.