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.
target_branch=$1echoRebasingonto$target_branch# Find the first commit that is common between the target branch and the current branchbranch_point=$(diff--old-line-format=''--new-line-format=''<(gitrev-list--first-parent"${target_branch}")<(gitrev-list--first-parent"HEAD")|head-n1)# Just try a rebaseechoTryingtheeasyway...
ifgitrebase$target_branch>/dev/null2>&1;thenechothatwaseasy!
exit0fi# If the simple rebase failed, roll it back
gitrebase--abort>/dev/null2>&1echothatdidnotwork.
# Find the number of commits which are candidates to rebase your branch tonumber_of_commits=$(gitrev-list$branch_point..$target_branch|wc-l)if[$number_of_commits==1];then# There is one single commit left and that one failed...echoThereisnowaytogofurther.
exit1fiechoThereare$number_of_commitsleft!
# Find the middle commitmiddle_commit_nr=$(($number_of_commits/2+1))middle_commit=$(gitrev-list$branch_point..$target_branch|awk-ne"NR==${middle_commit_nr}p")# And recursivly rebase onto the middle commitif$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_branchelse# If it failed, it will have tried every possible branching point. Return an errorexit1fi