diff --git a/git-rebase.sh b/git-rebase.sh
index 60c458f201f8f98bb1c6e115c009525659c2ee20..e2d85eeeab79e60ef46a65cfee1fb4682dd4ba68 100755 (executable)
--- a/git-rebase.sh
+++ b/git-rebase.sh
fi
cmt=`cat "$dotest/current"`
fi
cmt=`cat "$dotest/current"`
- if ! git diff-index --quiet HEAD --
+ if ! git diff-index --quiet --ignore-submodules HEAD --
then
if ! git commit --no-verify -C "$cmt"
then
then
if ! git commit --no-verify -C "$cmt"
then
do
case "$1" in
--continue)
do
case "$1" in
--continue)
- git diff-files --quiet || {
+ test -d "$dotest" -o -d .dotest ||
+ die "No rebase in progress?"
+
+ git diff-files --quiet --ignore-submodules || {
echo "You must edit all merge conflicts and then"
echo "mark them as resolved using git add"
exit 1
echo "You must edit all merge conflicts and then"
echo "mark them as resolved using git add"
exit 1
exit
;;
--skip)
exit
;;
--skip)
+ test -d "$dotest" -o -d .dotest ||
+ die "No rebase in progress?"
+
git reset --hard HEAD || exit $?
if test -d "$dotest"
then
git reset --hard HEAD || exit $?
if test -d "$dotest"
then
exit
;;
--abort)
exit
;;
--abort)
+ test -d "$dotest" -o -d .dotest ||
+ die "No rebase in progress?"
+
git rerere clear
if test -d "$dotest"
then
move_to_original_branch
git rerere clear
if test -d "$dotest"
then
move_to_original_branch
- elif test -d .dotest
- then
+ else
dotest=.dotest
move_to_original_branch
dotest=.dotest
move_to_original_branch
- else
- die "No rebase in progress?"
fi
fi
- git reset --hard $(cat $dotest/orig-head)
+ git reset --hard $(cat "$dotest/orig-head")
rm -r "$dotest"
exit
;;
rm -r "$dotest"
exit
;;
fi
# The tree must be really really clean.
fi
# The tree must be really really clean.
-git update-index --refresh || exit
-diff=$(git diff-index --cached --name-status -r HEAD --)
+git update-index --ignore-submodules --refresh || exit
+diff=$(git diff-index --cached --name-status -r --ignore-submodules HEAD --)
case "$diff" in
?*) echo "cannot rebase: your index is not up-to-date"
echo "$diff"
case "$diff" in
?*) echo "cannot rebase: your index is not up-to-date"
echo "$diff"
}
fi
}
fi
-# If the branch to rebase is given, first switch to it.
+# If the branch to rebase is given, that is the branch we will rebase
+# $branch_name -- branch being rebased, or HEAD (already detached)
+# $orig_head -- commit object name of tip of the branch before rebasing
+# $head_name -- refs/heads/<that-branch> or "detached HEAD"
+switch_to=
case "$#" in
2)
case "$#" in
2)
+ # Is it "rebase other $branchname" or "rebase other $commit"?
branch_name="$2"
branch_name="$2"
- git-checkout "$2" || usage
+ switch_to="$2"
+
+ if git show-ref --verify --quiet -- "refs/heads/$2" &&
+ branch=$(git rev-parse --verify "refs/heads/$2" 2>/dev/null)
+ then
+ head_name="refs/heads/$2"
+ elif branch=$(git rev-parse --verify "$2" 2>/dev/null)
+ then
+ head_name="detached HEAD"
+ else
+ usage
+ fi
;;
*)
;;
*)
+ # Do not need to switch branches, we are already on it.
if branch_name=`git symbolic-ref -q HEAD`
then
if branch_name=`git symbolic-ref -q HEAD`
then
+ head_name=$branch_name
branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'`
else
branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'`
else
+ head_name="detached HEAD"
branch_name=HEAD ;# detached
fi
branch_name=HEAD ;# detached
fi
+ branch=$(git rev-parse --verify "${branch_name}^0") || exit
;;
esac
;;
esac
-branch=$(git rev-parse --verify "${branch_name}^0") || exit
+orig_head=$branch
# Now we are rebasing commits $upstream..$branch on top of $onto
# Now we are rebasing commits $upstream..$branch on top of $onto
mb=$(git merge-base "$onto" "$branch")
if test "$upstream" = "$onto" && test "$mb" = "$onto" &&
# linear history?
mb=$(git merge-base "$onto" "$branch")
if test "$upstream" = "$onto" && test "$mb" = "$onto" &&
# linear history?
- ! git rev-list --parents "$onto".."$branch" | grep " .* " > /dev/null
+ ! (git rev-list --parents "$onto".."$branch" | grep " .* ") > /dev/null
then
then
+ # Lazily switch to the target branch if needed...
+ test -z "$switch_to" || git checkout "$switch_to"
echo >&2 "Current branch $branch_name is up to date."
exit 0
fi
echo >&2 "Current branch $branch_name is up to date."
exit 0
fi
GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
fi
GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
fi
-# move to a detached HEAD
-orig_head=$(git rev-parse HEAD^0)
-head_name=$(git symbolic-ref HEAD 2> /dev/null)
-case "$head_name" in
-'')
- head_name="detached HEAD"
- ;;
-*)
- git checkout "$orig_head" > /dev/null 2>&1 ||
- die "could not detach HEAD"
- ;;
-esac
-
-# Rewind the head to "$onto"; this saves our current head in ORIG_HEAD.
+# Detach HEAD and reset the tree
echo "First, rewinding head to replay your work on top of it..."
echo "First, rewinding head to replay your work on top of it..."
-git-reset --hard "$onto"
+git checkout "$onto^0" >/dev/null 2>&1 ||
+ die "could not detach HEAD"
+# git reset --hard "$onto^0"
# If the $onto is a proper descendant of the tip of the branch, then
# we just fast forwarded.
# If the $onto is a proper descendant of the tip of the branch, then
# we just fast forwarded.
if test -z "$do_merge"
then
if test -z "$do_merge"
then
- git format-patch -k --stdout --full-index --ignore-if-in-upstream "$upstream"..ORIG_HEAD |
+ git format-patch -k --stdout --full-index --ignore-if-in-upstream \
+ "$upstream..$orig_head" |
git am $git_am_opt --rebasing --resolvemsg="$RESOLVEMSG" &&
move_to_original_branch
ret=$?
git am $git_am_opt --rebasing --resolvemsg="$RESOLVEMSG" &&
move_to_original_branch
ret=$?
echo "$head_name" > "$dotest/head-name"
msgnum=0
echo "$head_name" > "$dotest/head-name"
msgnum=0
-for cmt in `git rev-list --reverse --no-merges "$upstream"..ORIG_HEAD`
+for cmt in `git rev-list --reverse --no-merges "$upstream..$orig_head"`
do
msgnum=$(($msgnum + 1))
echo "$cmt" > "$dotest/cmt.$msgnum"
do
msgnum=$(($msgnum + 1))
echo "$cmt" > "$dotest/cmt.$msgnum"