Dotfiles/site-modules/core/files/bin/git-merge-patch
Ade Attwood 7c184d8616 feat: ask to remove branch in git-merge-patch
When trying to merge-patch it will fail if the branch you are trying to merge is
already on the local machine.

This will ask if you want to remove it. The branch will be removed locally and
then pulled from the remote to ensure you are not merging any un-pushed local
changes.
2022-03-13 20:33:15 +00:00

130 lines
3.2 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" ]] || [[ "$MERGE_BRANCH" == "--skip" ]]; 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 $MERGE_BRANCH
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
#
# Ask the user if they would like to remove the local branch if it exists locally
#
if [[ ! -z "$(git branch --list $MERGE_BRANCH)" ]]; then
while true; do
read -p "Branch '$MERGE_BRANCH' exists locally would you like to remove it? " yn
case $yn in
[Yy]* ) git branch -D "$MERGE_BRANCH"; break;;
[Nn]* ) echo "Exiting you need to remove branch '$MERGE_BRANCH' manually before merge-patching"; exit;;
* ) echo "Please answer yes or no.";;
esac
done
fi
#
# 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