@@ -309,22 +309,42 @@ then
309309 }
310310fi
311311
312- # If the branch to rebase is given, first switch to it.
312+ # If the branch to rebase is given, that is the branch we will rebase
313+ # $branch_name -- branch being rebased, or HEAD (already detached)
314+ # $orig_head -- commit object name of tip of the branch before rebasing
315+ # $head_name -- refs/heads/<that-branch> or "detached HEAD"
316+ switch_to=
313317case " $# " in
3143182)
319+ # Is it "rebase other $branchname" or "rebase other $commit"?
315320 branch_name=" $2 "
316- git-checkout " $2 " || usage
321+ switch_to=" $2 "
322+
323+ if git show-ref --verify --quiet -- " refs/heads/$2 " &&
324+ branch=$( git rev-parse --verify " refs/heads/$2 " 2> /dev/null)
325+ then
326+ head_name=" refs/heads/$2 "
327+ elif branch=$( git rev-parse --verify " $2 " 2> /dev/null)
328+ then
329+ head_name=" detached HEAD"
330+ else
331+ usage
332+ fi
317333 ;;
318334* )
335+ # Do not need to switch branches, we are already on it.
319336 if branch_name=` git symbolic-ref -q HEAD`
320337 then
338+ head_name=$branch_name
321339 branch_name=` expr " z$branch_name " : ' zrefs/heads/\(.*\)' `
322340 else
341+ head_name=" detached HEAD"
323342 branch_name=HEAD ; # detached
324343 fi
344+ branch=$( git rev-parse --verify " ${branch_name} ^0" ) || exit
325345 ;;
326346esac
327- branch= $( git rev-parse --verify " ${branch_name} ^0 " ) || exit
347+ orig_head= $branch
328348
329349# Now we are rebasing commits $upstream..$branch on top of $onto
330350
@@ -335,6 +355,8 @@ if test "$upstream" = "$onto" && test "$mb" = "$onto" &&
335355 # linear history?
336356 ! git rev-list --parents " $onto " .." $branch " | grep " .* " > /dev/null
337357then
358+ # Lazily switch to the target branch if needed...
359+ test -z " $switch_to " || git checkout " $switch_to "
338360 echo >&2 " Current branch $branch_name is up to date."
339361 exit 0
340362fi
@@ -346,22 +368,11 @@ then
346368 GIT_PAGER=' ' git diff --stat --summary " $mb " " $onto "
347369fi
348370
349- # move to a detached HEAD
350- orig_head=$( git rev-parse HEAD^0)
351- head_name=$( git symbolic-ref HEAD 2> /dev/null)
352- case " $head_name " in
353- ' ' )
354- head_name=" detached HEAD"
355- ;;
356- * )
357- git checkout " $orig_head " > /dev/null 2>&1 ||
358- die " could not detach HEAD"
359- ;;
360- esac
361-
362- # Rewind the head to "$onto"; this saves our current head in ORIG_HEAD.
371+ # Detach HEAD and reset the tree
363372echo " First, rewinding head to replay your work on top of it..."
364- git-reset --hard " $onto "
373+ git checkout " $onto ^0" > /dev/null 2>&1 ||
374+ die " could not detach HEAD"
375+ # git reset --hard "$onto^0"
365376
366377# If the $onto is a proper descendant of the tip of the branch, then
367378# we just fast forwarded.
374385
375386if test -z " $do_merge "
376387then
377- git format-patch -k --stdout --full-index --ignore-if-in-upstream " $upstream " ..ORIG_HEAD |
388+ git format-patch -k --stdout --full-index --ignore-if-in-upstream \
389+ " $upstream ..$orig_head " |
378390 git am $git_am_opt --rebasing --resolvemsg=" $RESOLVEMSG " &&
379391 move_to_original_branch
380392 ret=$?
@@ -397,7 +409,7 @@ echo "$orig_head" > "$dotest/orig-head"
397409echo " $head_name " > " $dotest /head-name"
398410
399411msgnum=0
400- for cmt in ` git rev-list --reverse --no-merges " $upstream " ..ORIG_HEAD `
412+ for cmt in ` git rev-list --reverse --no-merges " $upstream .. $orig_head " `
401413do
402414 msgnum=$(( $msgnum + 1 ))
403415 echo " $cmt " > " $dotest /cmt.$msgnum "
0 commit comments