Parse git merge commit messages

Sometime traversing git history, I need to determine what branches were merged at some point.

By default git constructs merge commit message by itself.

And if nobody changes that it can be parsed to get the merged branch names.

Using history of our git repo for last two years, I took all the merge commit messages, and built up set of regexes to parse it

function Parse-MergeCommitMessage
{
    param
    (
        [string] $CommitMessage
    )

    $result = New-Object PSObject -Property `
    @{
        Parsed = $false;
        From = "N/A";
        Into = "N/A";
        SpecificCommit = $false
    }

    $patterns = `
    @(
        "^Merge branch '(?<from>\S*)'$",
        "^Merge remote branch '(?<from>\S*)'$",
        "^Merge remote-tracking branch '(?<from>\S*)'$",

        "^Merge (?<from>\S*) branch to (?<into>\S*)$",
        "^Merge (?<from>\S*) to (?<into>\S*)$",

        "^Merge branch '(?<from>\S*)' into (?<into>\S*)$",
        "^Merge remote branch '(?<from>\S*)' into (?<into>\S*)$",
        "^Merge remote-tracking branch '(?<from>\S*)' into (?<into>\S*)$",
        "^Merge branch (?<from>\S*) to (?<into>\S*)$",

        "^Merge branch '(?<from>\S*)' of (?<url>\S*)$",
        "^Merge branch '(?<from>\S*)' of (?<url>\S*) into (?<into>\S*)$",
        "^Merge branches '(?<into>\S*)' and '(?<from>\S*)'$",
        "^Merge branches '(?<into>\S*)' and '(?<from>\S*)' of (?<url>\S*)$"

        "(?<commit>^Merge commit '(?<from>\S*)'$)",
        "(?<commit>^Merge commit '(?<from>\S*)' into (?<into>\S*)$)"
    )

    foreach ($pattern in $patterns)
    {
        if ($CommitMessage -match $pattern)
        {
            $from = $Matches["from"]
            $into = $Matches["into"]
            $url = $Matches["url"]

            if (-not $into)
            {
                $into = "master"
            }

            if ($url)
            {
                $from = "origin/$from"
            }

            $result.From = $from
            $result.Into = $into
            $result.Parsed = $true
            $result.SpecificCommit = [bool] $Matches["commit"]

            break
        }
    }

    $result
}

For simplicity this function resolves all the remote branches as origin/… (line #54) however in my hooks I provided more accurate mapping for predefined set of urls. You can take a look for more details

Advertisements

About mnaoumov

Senior .NET Developer in Readify
This entry was posted in Uncategorized and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s