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