Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I find all the merges that had conflicts in a Git repository?

I am working on a research to study merges in open source projects.

I recently asked How can I find all the commits that have more than one parent in a Git repository?, and got very good answers.

Now I need to narrow my query to only find the commits that had conflicts.

With conflicts I mean that the same file was modified in two contributing commits.

Also, it would be very useful if I can find a git or bash (grep, awk?) command that gives me only those commits in which the same line was modified by two contributors.

The idea is to find commits that cannot be auto-resolved.

So, How can I find all the merges that had conflicts in a git repository?

like image 512
macrobug Avatar asked Mar 29 '13 16:03

macrobug


1 Answers

Once a merge commit is created, the information how the merge was performed is unfortunately lost. This is important because git merge accepts a number of options, such as strategy and per-strategy options, that affect appearance of conflicts. However, if your goal is to cover the reasonable case of finding merges that would have produced conflicts with the default merge options, it is possible to brute-force it: go over merge commits, recreate their merges, and flag the ones where git reports.

Note: this script checks out many different commits, and runs git reset --hard and even git clean -fdx in every iteration. Be sure to only run it in a checkout that contains no important files unknown to git!

#!/bin/bash

old_branch=$(git symbolic-ref --short HEAD)
for commit in `git rev-list --merges HEAD`
do
  # find the parents of the merge commit
  parents=$(git log -1 --format=%P $commit)
  fst=${parents%% *}
  rest=${parents#* }
  # check out the first parent
  git checkout -q $fst
  # merge with the rest of them
  git merge --no-commit $rest >/dev/null 2>&1
  # if there are any conflicts, print the commit and abort the merge
  if git ls-files --unmerged | grep -q '^'; then
    echo $commit
    git merge --abort
  fi
  # get rid of changes so the next checkout doesnt complain
  git reset -q --hard
  git clean -fdxq
done
git checkout -q $old_branch
like image 130
user4815162342 Avatar answered Oct 21 '22 05:10

user4815162342