detect git conflict markers in committed code

Viewed 163

Requirements

  • Inside a pipeline after code has been committed and pushed, I am looking to detect merge conflicts

Is there a way to detect conflict markers in committed and pushed code? I want a pipeline that is ran with a Pull Request to fail if any conflict markers are found inside committed code.

</div>
<<<<<<< HEAD
=======

>>>>>>> next
<div

note: I am not looking for helpful work-arounds. The source code is not 100% under my control.

But any robust alternative to grepping if a file has <<<<<<< ======= >>>>>>> on separate lines would be welcome. I seem to remember conflict markers can have a different format then just above.

Technology: Azure DevOps & Github yaml pipeline

Solution:

PowerShell/pwsh (TODO: check syntax, work-in progress)

$cd=Get-Location
$files = Get-ChildItem $cd
foreach ($f in $files) {
  $mergeConflictCounters = New-Object Collections.Generic.List[Int]
  foreach($line in [System.IO.File]::ReadLines($f.FullName)) {
    if ($line -like '*<<<<<<<*') {
      $mergeConflictCounters.Add(0)
    } else if ($mergeConflictCounters.Count -gt 0 -and $mergeConflictCounter -like '*=======*') {
      $mergeConflictCounters[$mergeConflictCounters.Count - 1] = $mergeConflictCounters[$mergeConflictCounters.Count - 1] + 1
    } else if ($mergeConflictCounters.Count -gt 0 -and $mergeConflictCounter -like '*>>>>>>>*') {
      $mergeConflictCounters[$mergeConflictCounters.Count - 1] = $mergeConflictCounters[$mergeConflictCounters.Count - 1] - 1
      if ($mergeConflictCounters[$mergeConflictCounters.Count - 1] -eq 0) {
      $mergeConflictCounters.RemoveAt($mergeConflictCounters.Count - 1)
      }
      if ($mergeConflictCounters.length -eq 0) {
        exit(1) // Merge conflict marker successfully aligned
      }
    }    
  }
}

TODO: Solutions for deno / node.js. And possibly another script to choose incoming or existing - as long as it is treated it as a prototype/experiment

2 Answers

My first inclination is to write a hook that greps for the lines you are trying to find. If you do this as a pre-commit hook, then you only need to grep the diffs, not the entire project. And you can prevent them from being added at all.

But any robust alternative to grepping if a file has <<<<<<< ======= >>>>>>> on separate lines would be welcome. I seem to remember conflict markers can have a different format then just above.

That's exactly the shape of conflict markers. It's documented that way (Documentation/git-merge.txt and merge-file.txt).

So, that's the robust way, nothing much to add.

Related