Dotfiles/site-modules/core/files/bin/git-merge-patch
Ade Attwood f386272007 feat(bin): detect merge conflicts in merge-patch
When merge patching it will now detect if there is an unresolved conflict in
your current branch and exit without doing anything.

This is useful when merging multiple branches at once, if you hit a conflict
half way though it would remove the "MERGE_PATCH" file and lose where you where
in the patch

Now the script will exit and not lose the position so you can `--continue`
correctly after fixing the conflicts
2022-02-15 20:24:45 +00:00

116 lines
2.7 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# Merges a remote branch into your current branch forcing a fast
# forward merge by rebasing first. This uses the rebase style of
# `--continue` and `--abort` when you have started to pick up where
# you left off
#
# Author: Ade Attwood <code@adeattwood.co.uk>
# Created: 2021-05-16
#
set -e
MERGE_BRANCH="$1";
#
# The merge branch argument is required
#
if [[ -z "$1" ]]; then
cat << HELP
Git Merge Patch
git merge-patch my-remote-branch
HELP
exit 1;
fi
#
# Test for merge conflicts can abort if any are found. Theses need to be
# resolved before you can continue
#
if [[ ! -z "$(git diff --name-only --diff-filter=U)" ]]; then
echo "ERROR: Conflicts found, you need to resolve them before you continue your"
echo "merge-patch. Use 'git am --show-current-patch' to see the failed patch. Then you"
echo "can continue the merge-patch with 'git merge-patch --continue'"
exit 1
fi
if [[ "$MERGE_BRANCH" == "--abort" ]]; then
#
# If we are in a rebase state then we want to abort that to
#
if [[ -f "$(git rev-parse --show-toplevel)/.git/REBASE_HEAD" ]]; then
git rebase --abort
fi
if [[ -f "$(git rev-parse --show-toplevel)/.git/MERGE_PATCH" ]]; then
rm "$(git rev-parse --show-toplevel)/.git/MERGE_PATCH"
fi
exit 0
fi
if [[ "$MERGE_BRANCH" != "--continue" ]]; then
branch=$(git rev-parse --abbrev-ref HEAD);
echo "$branch" > "$(git rev-parse --show-toplevel)/.git/MERGE_PATCH"
#
# Fetch from remove so every ting is upto date
#
git fetch
#
# Check out the merge branch from the origin
#
git checkout -b "$MERGE_BRANCH" "origin/$MERGE_BRANCH"
#
# Ensure the target branch is up to date
#
git checkout $branch
git pull origin $branch
git checkout $MERGE_BRANCH
#
# Rebase onto branch so we don't create a merge commit
#
git rebase $branch;
else
if [[ ! -f "$(git rev-parse --show-toplevel)/.git/MERGE_PATCH" ]]; then
echo "ERROR: Merge patch has not been started"
exit 1;
fi
#
# If we are still in the rebase from above then we need to
# continue with that before we finish merging the patch
#
if [[ -f "$(git rev-parse --show-toplevel)/.git/REBASE_HEAD" ]]; then
git rebase --continue
fi
MERGE_BRANCH=$(git rev-parse --abbrev-ref HEAD)
branch="$(cat $(git rev-parse --show-toplevel)/.git/MERGE_PATCH)"
fi
#
# Force push the rebased branch to the remove so Gitlab
# recognises the hash has been merged
#
git push origin "$MERGE_BRANCH" -f -o ci.skip
#
# Merge into the target branch ensuring its a fast forward merge
#
git checkout $branch
git merge --ff-only --log $MERGE_BRANCH;
#
# Clean up the MERGE_PATCH file now we have completed the merge
#
if [[ -f "$(git rev-parse --show-toplevel)/.git/MERGE_PATCH" ]]; then
rm "$(git rev-parse --show-toplevel)/.git/MERGE_PATCH"
fi