Skip to content

Instantly share code, notes, and snippets.

@christiannelson
Last active March 23, 2018 16:50
Show Gist options
  • Save christiannelson/c9e4e09403cac4505bd80ecc297c95fd to your computer and use it in GitHub Desktop.
Save christiannelson/c9e4e09403cac4505bd80ecc297c95fd to your computer and use it in GitHub Desktop.
A shell script that merges (--no-ff) a feature branch after rebasing it.
#!/bin/sh
# This script captures a series of git commands that emcompass merging a feature into a target branch, like
# development or master. It updates the target branch and rebases the feature before merging with --no-ff.
# The end result is that there's always a merge commit and all of the commits are at the top of the timeline.
# This makes for easier to read git histories, especially with active teams.
# Is this a git repo?
if [[ ! -d .git ]]; then
echo "\nDirectory is not a git repo. Exiting...\n"
exit 1
fi
# Are we on a branch that looks likes a feature branch?
FEATURE_BRANCH=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
if [[ $FEATURE_BRANCH = "" || $FEATURE_BRANCH = "master" || $FEATURE_BRANCH = "development" ]]; then
echo "\nInvoke this command from the branch you want to merge.\n"
exit 1
fi
# Which branch are we merging in to?
git branch | grep -q "development"
if [[ $? -eq 0 ]]; then
TARGET_BRANCH="development"
else
TARGET_BRANCH="master"
fi
# Is there a remote branch for this feature?
git ls-remote --heads --exit-code origin "$FEATURE_BRANCH" > /dev/null
if [[ $? -eq 2 ]]; then
TARGET_BRANCH_HAS_REMOTE=0
else
TARGET_BRANCH_HAS_REMOTE=1
fi
# Stop execution if any of the steps fail.
set -e
#set -x
echo "\nMerging '$FEATURE_BRANCH' in to '$TARGET_BRANCH'...\n"
sleep 2
SEPARATOR="\n-------------------------------------------------\n"
# Update the target branch (development|master)
git checkout $TARGET_BRANCH
echo $SEPARATOR
git pull
echo $SEPARATOR
# Go back to the feature branch and rebase on to the target branch
git checkout -
echo $SEPARATOR
git rebase $TARGET_BRANCH
echo $SEPARATOR
if [[ $TARGET_BRANCH_HAS_REMOTE -eq 1 ]]; then
git push --force-with-lease
echo $SEPARATOR
fi
# Now merge the feature branch into the target branch
git checkout $TARGET_BRANCH
echo $SEPARATOR
git merge --no-ff -
echo $SEPARATOR
# And push our target branch up, which now includes the merged feature.
git push
echo $SEPARATOR
# Delete the feature branch(es)?
read -n 1 -p "Delete branches [y]es, [n]o, [l]ocal, [r]emote? " answer
echo "\n"
case ${answer:0:1} in
y|Y|b|B )
git branch -d $FEATURE_BRANCH
if [[ $TARGET_BRANCH_HAS_REMOTE -eq 1 ]]; then
git push -d origin $FEATURE_BRANCH
fi
;;
l|L )
git branch -d $FEATURE_BRANCH
;;
r|R )
if [[ $TARGET_BRANCH_HAS_REMOTE -eq 1 ]]; then
git push -d origin $FEATURE_BRANCH
else
echo "Skipping remote because it doesn't exist."
fi
;;
* )
echo "Leaving branches intact."
;;
esac
echo "\nAll done!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment