# The original idea comes from Eric W. Biederman, in
# http://article.gmane.org/gmane.comp.version-control.git/22407
-USAGE='(--continue | --abort | --skip | [--preserve-merges] [--verbose]
- [--onto <branch>] <upstream> [<branch>])'
+OPTIONS_KEEPDASHDASH=
+OPTIONS_SPEC="\
+git-rebase [-i] [options] [--] <upstream> [<branch>]
+git-rebase [-i] (--continue | --abort | --skip)
+--
+ Available options are
+v,verbose display a diffstat of what changed upstream
+onto= rebase onto given branch instead of upstream
+p,preserve-merges try to recreate merges instead of ignoring them
+s,strategy= use the given merge strategy
+m,merge always used (no-op)
+i,interactive always used (no-op)
+ Actions:
+continue continue rebasing process
+abort abort rebasing process and restore original branch
+skip skip current patch and continue rebasing process
+"
-OPTIONS_SPEC=
. git-sh-setup
require_work_tree
-DOTEST="$GIT_DIR/.dotest-merge"
+DOTEST="$GIT_DIR/rebase-merge"
TODO="$DOTEST"/git-rebase-todo
DONE="$DOTEST"/done
MSG="$DOTEST"/message
REWRITTEN="$DOTEST"/rewritten
PRESERVE_MERGES=
STRATEGY=
+ONTO=
VERBOSE=
-test -d "$REWRITTEN" && PRESERVE_MERGES=t
-test -f "$DOTEST"/strategy && STRATEGY="$(cat "$DOTEST"/strategy)"
-test -f "$DOTEST"/verbose && VERBOSE=t
GIT_CHERRY_PICK_HELP=" After resolving the conflicts,
mark the corrected paths with 'git add <paths>', and
new_parents="$new_parents $new_p"
;;
esac
+ else
+ new_parents="$new_parents $p"
fi
done
case $fast_forward in
die_with_patch $sha1 "Could not apply $sha1... $rest"
make_patch $sha1
: > "$DOTEST"/amend
- warn
+ warn "Stopped at $sha1... $rest"
warn "You can amend the commit now, with"
warn
warn " git commit --amend"
done
}
+# check if no other options are set
+is_standalone () {
+ test $# -eq 2 -a "$2" = '--' &&
+ test -z "$ONTO" &&
+ test -z "$PRESERVE_MERGES" &&
+ test -z "$STRATEGY" &&
+ test -z "$VERBOSE"
+}
+
+get_saved_options () {
+ test -d "$REWRITTEN" && PRESERVE_MERGES=t
+ test -f "$DOTEST"/strategy && STRATEGY="$(cat "$DOTEST"/strategy)"
+ test -f "$DOTEST"/verbose && VERBOSE=t
+}
+
while test $# != 0
do
case "$1" in
--continue)
+ is_standalone "$@" || usage
+ get_saved_options
comment_for_reflog continue
test -d "$DOTEST" || die "No interactive rebase running"
do_rest
;;
--abort)
+ is_standalone "$@" || usage
+ get_saved_options
comment_for_reflog abort
git rerere clear
exit
;;
--skip)
+ is_standalone "$@" || usage
+ get_saved_options
comment_for_reflog skip
git rerere clear
output git reset --hard && do_rest
;;
- -s|--strategy)
+ -s)
case "$#,$1" in
*,*=*)
STRATEGY="-s "$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
shift ;;
esac
;;
- -m|--merge)
+ -m)
# we use merge anyway
;;
- -C*)
- die "Interactive rebase uses merge, so $1 does not make sense"
- ;;
- -v|--verbose)
+ -v)
VERBOSE=t
;;
- -p|--preserve-merges)
+ -p)
PRESERVE_MERGES=t
;;
- -i|--interactive)
+ -i)
# yeah, we know
;;
- ''|-h)
- usage
+ --onto)
+ shift
+ ONTO=$(git rev-parse --verify "$1") ||
+ die "Does not point to a valid commit: $1"
;;
- *)
+ --)
+ shift
+ test $# -eq 1 -o $# -eq 2 || usage
test -d "$DOTEST" &&
die "Interactive rebase already started"
comment_for_reflog start
- ONTO=
- case "$1" in
- --onto)
- ONTO=$(git rev-parse --verify "$2") ||
- die "Does not point to a valid commit: $2"
- shift; shift
- ;;
- esac
-
require_clean_work_tree
+ UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
+ test -z "$ONTO" && ONTO=$UPSTREAM
+
if test ! -z "$2"
then
output git show-ref --verify --quiet "refs/heads/$2" ||
fi
HEAD=$(git rev-parse --verify HEAD) || die "No HEAD?"
- UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
-
mkdir "$DOTEST" || die "Could not create temporary $DOTEST"
- test -z "$ONTO" && ONTO=$UPSTREAM
-
: > "$DOTEST"/interactive || die "Could not mark as interactive"
git symbolic-ref HEAD > "$DOTEST"/head-name 2> /dev/null ||
echo "detached HEAD" > "$DOTEST"/head-name
# Rebase $SHORTUPSTREAM..$SHORTHEAD onto $SHORTONTO
#
# Commands:
-# pick = use commit
-# edit = use commit, but stop for amending
-# squash = use commit, but meld into previous commit
+# p, pick = use commit
+# e, edit = use commit, but stop for amending
+# s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
has_action "$TODO" ||
die_abort "Nothing to do"
+ git update-ref ORIG_HEAD $HEAD
output git checkout $ONTO && do_rest
;;
esac