Skip to content

Commit 3ee5538

Browse files
committed
Merge branch 'jc/rebase'
* jc/rebase: rebase [--onto O] A B: omit needless checkout
2 parents ce47dc0 + 0cb0664 commit 3ee5538

File tree

1 file changed

+32
-20
lines changed

1 file changed

+32
-20
lines changed

git-rebase.sh

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -309,22 +309,42 @@ then
309309
}
310310
fi
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=
313317
case "$#" in
314318
2)
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
;;
326346
esac
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
337357
then
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
340362
fi
@@ -346,22 +368,11 @@ then
346368
GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
347369
fi
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
363372
echo "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.
@@ -374,7 +385,8 @@ fi
374385

375386
if test -z "$do_merge"
376387
then
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"
397409
echo "$head_name" > "$dotest/head-name"
398410

399411
msgnum=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"`
401413
do
402414
msgnum=$(($msgnum + 1))
403415
echo "$cmt" > "$dotest/cmt.$msgnum"

0 commit comments

Comments
 (0)