Last active
December 22, 2015 07:59
-
-
Save rickosborne/6441667 to your computer and use it in GitHub Desktop.
Rebase a bunch of branches in a safe(r) way.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Attempt to do the equivalent of: | |
# massrebase = "!sh -c 'for branch in $@; do git rebase $0 $branch; done;'" | |
if [[ -z "${SOURCE_BRANCH}" ]] ; then | |
SOURCE_BRANCH='origin/master' | |
fi | |
# Import some helper functions | |
. "$(git --exec-path)/git-sh-setup" | |
require_clean_work_tree 'catch up' 'Please commit or stash any changes.' | |
function usage { | |
echo "$0 branch1 branch2 ..." | |
echo "This script will attempt to catch-up the specified branches by:" | |
echo " 1. Checking out the branch." | |
echo " 2. Rebasing from $SOURCE_BRANCH." | |
echo " 3. Repeat as necessary." | |
echo "Branches can be globs, like foo*, and will catch-up all matches." | |
echo "Optional environment variables:" | |
echo " SOURCE_BRANCH='...' default: origin/master" | |
exit 1 | |
} | |
if [[ -z "$1" || "$1" = "--help" || "$1" = "help" || "$1" = "-h" || "$1" = "-?" ]] ; then | |
usage | |
fi | |
REMOTE='origin' | |
SOURCE="$SOURCE_BRANCH" | |
RESET=$'\033[0m' | |
ERR=$'\033[31m' | |
WARN=$'\033[35m' | |
if [[ -n $(echo "$SOURCE_BRANCH" | grep '/') ]] ; then | |
REMOTE=$(echo "$SOURCE_BRANCH" | cut -d / -f 1) | |
SOURCE=$(echo "$SOURCE_BRANCH" | cut -d / -f 2) | |
fi | |
git checkout -q "$BRANCH" | |
git pull -q "$REMOTE" "$BRANCH" | |
# for each command-line argument ... | |
while (( "$#" )) ; do | |
# list all of the matching branches, as it could be a glob | |
BRANCHES=$(git branch --list "$1") | |
# for each matching branch | |
if [[ -z "$BRANCHES" ]] ; then | |
printf "${ERR}No branches matched '$1'.${RESET}\n" | |
else | |
while read -r TARGET ; do | |
if [[ $(echo "$TARGET" | cut -c 1) = '*' ]] ; then | |
# Remove the leading * from the current branch | |
TARGET=$(echo "$TARGET" | cut -d ' ' -f 2) | |
fi | |
# One last check to ensure the branch exists | |
if [[ -z $(git branch --list "$TARGET") ]] ; then | |
printf "${ERR}Branch '$TARGET' does not exist.${RESET}\n" | |
else | |
MERGE_RESULT=$(git merge-tree `git merge-base "$TARGET" "$SOURCE"` "$SOURCE" "$TARGET") | |
if [[ -n $(echo "$MERGE_RESULT" | grep -A3 'changed in both') ]] ; then | |
printf "${ERR}There are conflicts between '$SOURCE' and '$TARGET'${RESET}\n" | |
else | |
if [[ -z "$MERGE_RESULT" ]] ; then | |
printf "${WARN}It looks like '$TARGET' is an old, merged branch that could be deleted.${RESET}\n Remove it with: ${WARN}git branch -d '$TARGET'${RESET}\n" | |
else | |
echo "Catching-up '$TARGET' from '$SOURCE'" | |
git checkout -q "$TARGET" | |
git rebase -q "$SOURCE_BRANCH" | |
git checkout -q "$SOURCE" | |
fi | |
fi | |
fi | |
done <<< "$BRANCHES" | |
fi | |
shift | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment