Code

"rebase --onto A...B" replays history on the merge base between A and B
[git.git] / git-rebase.sh
index 6ec155cf03c98f2e075f298039037d0e099311b1..6503113a84e6e01e15bfcddd427c359c597cd7d1 100755 (executable)
@@ -34,6 +34,8 @@ set_reflog_action rebase
 require_work_tree
 cd_to_toplevel
 
+LF='
+'
 OK_TO_SKIP_PRE_REBASE=
 RESOLVEMSG="
 When you have resolved this problem run \"git rebase --continue\".
@@ -417,7 +419,22 @@ fi
 
 # Make sure the branch to rebase onto is valid.
 onto_name=${newbase-"$upstream_name"}
-onto=$(git rev-parse --verify "${onto_name}^0") || exit
+if     left=$(expr "$onto_name" : '\(.*\)\.\.\.') &&
+       right=$(expr "$onto_name" : '\.\.\.\(.*\)$') &&
+       : ${left:=HEAD} ${right:=HEAD} &&
+       onto=$(git merge-base "$left" "$right")
+then
+       case "$onto" in
+       ?*"$LF"?*)
+               die "$onto_name: there are more than one merge bases"
+               ;;
+       '')
+               die "$onto_name: there is no merge base"
+               ;;
+       esac
+else
+       onto=$(git rev-parse --verify "${onto_name}^0") || exit
+fi
 
 # If a hook exists, give it a chance to interrupt
 run_pre_rebase_hook "$upstream_arg" "$@"