13th January, 2019.5 minutes read time-Code

Bash Script - test merge conflicts

A reoccuring problem I run into at work is handling multiple branches on a dev environment comprised of Java, JavaScript, SQL, and SCSS files.

It's not an ideal scenario, but utilizing Jenkins, the task is fairly easy in the pipeline - you list the branches you want built, you tell it to deploy (or on a schedule) and it runs through and confirms there is no merge conflicts, before continuing on the pipeline to run the jasmine tests to verify everything is up to snuff on the front-end. Of course, since it's Jenkins, I can kick off the build, then head to the console output and watch for an error, or wait for it to fail.

But who has time for that? In that time, three new JavaScript frameworks were released, and one failed, and the other already replaced Angular!

Also, as the code example lives in a gist - my entry may not always match the code (which will be the most up-to-date version).

What this script does:

  • for my needs, it checks out develop and pulls to be sure it's up to date
  • create a branch test-merge that is appended with the day/month/seconds
  • we reference a branches.txt file that holds the branches (each branch on a new line)
  • for each branch:

    • ignores any # comments
    • fetches the branch
    • we merge (using refs/remotes/origin/ so we don't need to check out each branch locally)
  • output "SUCCESS" or "FAIL" to build-result.txt
  • output the content of build-result.txt
  • we grep against the file to check if "FAIL" is present
  • remove build-result.txt
  • checkout develop and delete test-merge

What it still needs to do:

  • Stash and save the current code (in case you haven't committed yet) and apply when you're done
  • run from the current branch (saving the current branch, switching to develop, and switching back to your original branch)
  • fix the issue where it's applying to develop, requiring a reset

#!/bin/bash
function git_merge_test() {
echo "test git branch merges";
RUN_UNIT_TESTS=0
while test $# -gt 0; do
case "$1" in
-h|--help)
echo "test the branches in branches.txt for merge conflicts"
echo " "
echo "git_merge_test [options]"
echo " "
echo "options:"
echo "-h, --help show brief help"
echo "-t, --test execute unit tests on successful merge"
return 0
;;
-t)
shift
RUN_UNIT_TESTS=1
;;
*)
break
;;
esac
done
# prune, pull and update develop
git prune && git checkout develop && git pull;
# create test merge branch
test_branch_name="test-merge$(date '+%d%m%S')";
echo "Creating local testing branch $test_branch_name";
git checkout -b $test_branch_name;
branches="branches.txt";
while IFS='' read -r branch || [[ -n "$branch" ]]; do
# strip out any hash comments
clean_branch=${branch%#*}
# trim whitepsace
trim_branch="$(echo -e "${clean_branch}" | tr -d '[:space:]')"
# only execute if there is a branch
if [ -n "$trim_branch" ]; then
echo "Merging $trim_branch"
(git merge --no-edit refs/remotes/origin/${trim_branch} && echo "$trim_branch: SUCCESS" >> build-result.txt) || (git merge --abort && echo "$trim_branch: FAIL" >> build-result.txt)
fi;
done < "$branches"
cat build-result.txt
if grep -F " FAIL" build-result.txt; then
echo "Stopping because of a merge conflict in one of the branches";
rm build-result.txt;
# switch back to develop and delete the test branch
git checkout develop;
git reset --hard origin/develop;
git branch -D $test_branch_name;
return 1;
fi
rm build-result.txt;
if [ $RUN_UNIT_TESTS == 1 ]; then
echo "Executing build and unit tests...";
grunt;
fi;
# switch back to develop and delete the test branch
git checkout develop;
git reset --hard origin/develop;
git branch -D $test_branch_name;
};
view raw git_merge_check.sh hosted with ❤ by GitHub