git: Moving a feature branch up the main-line until it has a conflict
So you all know the drill: You are hacking away on a pet feature and all around you the work goes on. Sometimes you yourself are changing the master branch, sometimes its your colleagues and your feature branch sits a few hundred commits behind. Rebasing it onto the master fails and you do not know which commit is the top-most one you can actually automatically rebase to.
Enter the following script:
#!bash
target_branch=$1
echo Rebasing onto $target_branch
# Find the first commit that is common between the target branch and the current branch
branch_point=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${target_branch}") <(git rev-list --first-parent "HEAD") | head -n 1)
# Just try a rebase
echo Trying the easy way...
if git rebase $target_branch > /dev/null 2>&1; then
echo that was easy!
exit 0
fi
# If the simple rebase failed, roll it back
git rebase --abort > /dev/null 2>&1
echo that did not work.
# Find the number of commits which are candidates to rebase your branch to
number_of_commits=$(git rev-list $branch_point..$target_branch | wc -l)
if [ $number_of_commits == 1 ]; then
# There is one single commit left and that one failed...
echo There is no way to go further.
exit 1
fi
echo There are $number_of_commits left!
# Find the middle commit
middle_commit_nr=$(($number_of_commits/2 + 1))
middle_commit=$(git rev-list $branch_point..$target_branch | awk -ne "NR==${middle_commit_nr}p")
# And recursivly rebase onto the middle commit
if $0 $middle_commit; then
# If that succeeded, we moved the current branch further up the tree;
# Recursivly retry rebasing onto the real target branch
$0 $target_branch
else
# If it failed, it will have tried every possible branching point. Return an error
exit 1
fi
That’s it!