Skip to content

Instantly share code, notes, and snippets.

@gianpaolof
Forked from smileyborg/detect_evil_merge.sh
Created May 7, 2020 09:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gianpaolof/347c83fcb51ae8c272d4e713e31225d3 to your computer and use it in GitHub Desktop.
Save gianpaolof/347c83fcb51ae8c272d4e713e31225d3 to your computer and use it in GitHub Desktop.
Two scripts that can be used to detect evil merges in Git. See http://stackoverflow.com/questions/27683077
#!/bin/bash
# A shell script to provide a meaningful diff output for a merge commit that can be used to determine whether the merge was evil.
# The script should be run from outside the git repository, with two arguments:
# 1 - the directory of the git repository
# 2 - the SHA for the merge commit to inspect
# The script will output one file:
# - the merge redone fresh without any conflicts resolved, diff'ed to the actual merge
output_file="diff.txt"
if [ "$#" -ne 2 ]
then
echo "ERROR: This script must be run with exactly two arguments: the directory for the Git repo, and the SHA for the merge commit to inspect." >&2
echo "Usage: $0 GIT_REPO_DIR MERGE_COMMIT_SHA" >&2
exit 1
fi
# Store the current HEAD so we can put the repository back into the original state when finished
if ! original_head=$(git -C $1 symbolic-ref --short -q HEAD) # get the branch name, if possible
then
original_head=$(git -C $1 rev-parse HEAD) # detached HEAD, get the commit SHA
fi
# Perform the merge again, without resolving conflicts. Then diff the result with the actual merge commit we're inspecting.
git -C $1 checkout $2~ &>/dev/null
git -C $1 -c merge.conflictstyle=diff3 merge --no-ff $2^2 --no-commit &>/dev/null
git -C $1 add $(git -C $1 status -s | cut -c 3-) &>/dev/null
git -C $1 commit --no-edit &>/dev/null
git -C $1 diff HEAD..$2 > $output_file
# Put the repository back in the original state
git -C $1 checkout $original_head &>/dev/null
#!/bin/bash
# A shell script to provide a meaningful diff output for a merge commit that can be used to determine whether the merge was evil.
# The script should be run from outside the git repository, with two arguments:
# 1 - the directory of the git repository
# 2 - the SHA for the merge commit to inspect
# The script will output two files:
# - the merge redone fresh with conflicts resolved using the first parent, diff'ed to the actual merge
# - the merge redone fresh with conflicts resolved using the second parent, diff'ed to the actual merge
output_fileA="diffA.txt"
output_fileB="diffB.txt"
if [ "$#" -ne 2 ]
then
echo "ERROR: This script must be run with exactly two arguments: the directory for the Git repo, and the SHA for the merge commit to inspect." >&2
echo "Usage: $0 GIT_REPO_DIR MERGE_COMMIT_SHA" >&2
exit 1
fi
# Store the current HEAD so we can put the repository back into the original state when finished
if ! original_head=$(git -C $1 symbolic-ref --short -q HEAD) # get the branch name, if possible
then
original_head=$(git -C $1 rev-parse HEAD) # detached HEAD, get the commit SHA
fi
# Perform the merge again, resolving conflicts using the version from the first parent.
# Then diff the result with the actual merge commit we're inspecting.
git -C $1 checkout $2~ &>/dev/null
git -C $1 merge --no-ff --no-edit -s recursive -Xours $2^2 &>/dev/null
git -C $1 diff HEAD..$2 > $output_fileA
# Perform the merge again, resolving conflicts using the version from the second parent.
# Then diff the result with the actual merge commit we're inspecting.
git -C $1 checkout $2~ &>/dev/null
git -C $1 merge --no-ff --no-edit -s recursive -Xtheirs $2^2 &>/dev/null
git -C $1 diff HEAD..$2 > $output_fileB
# Put the repository back in the original state
git -C $1 checkout $original_head &>/dev/null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment