mercurialhookmercurial-hookblame

Detect new lines in mercurial


We are studying to add precommit hooks to detect coding standards compliance with our company policy. We don't want to detect the legacy code, just the new lines added.

In git it's possible to detect the line numbers that are added before committing, since they are shown with the hash number 00000000000 when invoking git blame.

In mercurial the new lines are not shown in hg blame/annotate. Is there another mechanism to figure out that? Using hg diff can be really painful to do this.


Solution

  • Edit your repository (hg config --local) or your user config (hg config --edit) and enable a pre-commit hook (hg help config.hooks):

    [hooks]
    pre-commit=/path/to/check-added-lines
    

    In the pre-commit hook, run the following version of the annotate command with the wdir() revset and the modified() + added() filesets: (hg help revsets and hg help filesets):

    hg ann -r 'wdir()' 'set:modified() + added()'
    

    That will give you annotation output where just-added lines (i.e. lines that only exist in your working directory) have a + after the revision number. So in check-added-lines you can do something like, for example,

    #!/bin/bash
    IFS=$'\n'
    for line in $(hg ann -r 'wdir()' 'set:modified() + added()' | grep '^[0-9]*+' | sed 's/^[0-9]\++ *: //'); do
        if ! run_checker "$line"; then
            exit 1
        fi
    done
    exit 0
    

    with your choice of run_checker program.

    Although I hesitate to recommend this, if you're willing to tolerate bugs and potential API breakage (Mercurial considers its behaviour not explicitly documented as experimental, its CLI, and its stdout to be API, which we try to keep very stable), you might also be interested in the new and experimental fix extension, which I think was built with your use-case in mind (hg help --extension fix).