# Copyright (c) 2005 Junio C Hamano.
#
-USAGE='[--interactive | -i] [-v] [--onto <newbase>] [<upstream>|--root] [<branch>]'
+USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
LONG_USAGE='git-rebase replaces <branch> with a new branch of the
same name. When the --onto option is provided the new branch starts
out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
dotest="$GIT_DIR"/rebase-merge
prec=4
verbose=
+diffstat=$(git config --bool rebase.stat)
git_am_opt=
rebase_root=
+force_rebase=
continue_merge () {
test -n "$prev_head" || die "prev_head must be defined"
echo "directly, but instead do one of the following: "
die "$RESOLVEMSG"
fi
- printf "Committed: %0${prec}d " $msgnum
+ if test -z "$GIT_QUIET"
+ then
+ printf "Committed: %0${prec}d " $msgnum
+ fi
else
- printf "Already applied: %0${prec}d " $msgnum
+ if test -z "$GIT_QUIET"
+ then
+ printf "Already applied: %0${prec}d " $msgnum
+ fi
+ fi
+ if test -z "$GIT_QUIET"
+ then
+ git rev-list --pretty=oneline -1 "$cmt" | sed -e 's/^[^ ]* //'
fi
- git rev-list --pretty=oneline -1 "$cmt" | sed -e 's/^[^ ]* //'
prev_head=`git rev-parse HEAD^0`
# save the resulting commit so we can read-tree on it later
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
eval GITHEAD_$hd='$(cat "$dotest/onto_name")'
export GITHEAD_$cmt GITHEAD_$hd
+ if test -n "$GIT_QUIET"
+ then
+ export GIT_MERGE_VERBOSITY=1
+ fi
git-merge-$strategy "$cmt^" -- "$hd" "$cmt"
rv=$?
case "$rv" in
finish_rb_merge () {
move_to_original_branch
rm -r "$dotest"
- echo "All done."
+ say All done.
}
is_interactive () {
if test -z "$OK_TO_SKIP_PRE_REBASE" &&
test -x "$GIT_DIR/hooks/pre-rebase"
then
- "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
- echo >&2 "The pre-rebase hook refused to rebase."
- exit 1
- }
+ "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} ||
+ die "The pre-rebase hook refused to rebase."
fi
}
end=$(cat "$dotest/end")
msgnum=$(cat "$dotest/msgnum")
onto=$(cat "$dotest/onto")
+ GIT_QUIET=$(cat "$dotest/quiet")
continue_merge
while test "$msgnum" -le "$end"
do
head_name=$(cat "$GIT_DIR"/rebase-apply/head-name) &&
onto=$(cat "$GIT_DIR"/rebase-apply/onto) &&
orig_head=$(cat "$GIT_DIR"/rebase-apply/orig-head) &&
+ GIT_QUIET=$(cat "$GIT_DIR"/rebase-apply/quiet)
git am --resolved --3way --resolvemsg="$RESOLVEMSG" &&
move_to_original_branch
exit
msgnum=$(cat "$dotest/msgnum")
msgnum=$(($msgnum + 1))
onto=$(cat "$dotest/onto")
+ GIT_QUIET=$(cat "$dotest/quiet")
while test "$msgnum" -le "$end"
do
call_merge "$msgnum"
head_name=$(cat "$GIT_DIR"/rebase-apply/head-name) &&
onto=$(cat "$GIT_DIR"/rebase-apply/onto) &&
orig_head=$(cat "$GIT_DIR"/rebase-apply/orig-head) &&
+ GIT_QUIET=$(cat "$GIT_DIR"/rebase-apply/quiet)
git am -3 --skip --resolvemsg="$RESOLVEMSG" &&
move_to_original_branch
exit
git rerere clear
if test -d "$dotest"
then
+ GIT_QUIET=$(cat "$dotest/quiet")
move_to_original_branch
else
dotest="$GIT_DIR"/rebase-apply
+ GIT_QUIET=$(cat "$dotest/quiet")
move_to_original_branch
fi
git reset --hard $(cat "$dotest/orig-head")
esac
do_merge=t
;;
+ -n|--no-stat)
+ diffstat=
+ ;;
+ --stat)
+ diffstat=t
+ ;;
-v|--verbose)
verbose=t
+ diffstat=t
+ GIT_QUIET=
+ ;;
+ -q|--quiet)
+ GIT_QUIET=t
+ git_am_opt="$git_am_opt -q"
+ verbose=
+ diffstat=
;;
--whitespace=*)
git_am_opt="$git_am_opt $1"
+ case "$1" in
+ --whitespace=fix|--whitespace=strip)
+ force_rebase=t
+ ;;
+ esac
+ ;;
+ --committer-date-is-author-date|--ignore-date)
+ git_am_opt="$git_am_opt $1"
+ force_rebase=t
;;
-C*)
git_am_opt="$git_am_opt $1"
--root)
rebase_root=t
;;
+ -f|--f|--fo|--for|--forc|force|--force-r|--force-re|--force-reb|--force-reba|--force-rebas|--force-rebase)
+ force_rebase=t
+ ;;
-*)
usage
;;
# The tree must be really really clean.
if ! git update-index --ignore-submodules --refresh; then
- echo >&2 "cannot rebase: you have unstaged changes"
- exit 1
+ die "cannot rebase: you have unstaged changes"
fi
diff=$(git diff-index --cached --name-status -r --ignore-submodules HEAD --)
case "$diff" in
# linear history?
! (git rev-list --parents "$onto".."$branch" | grep " .* ") > /dev/null
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
+ if test -z "$force_rebase"
+ then
+ # Lazily switch to the target branch if needed...
+ test -z "$switch_to" || git checkout "$switch_to"
+ say "Current branch $branch_name is up to date."
+ exit 0
+ else
+ say "Current branch $branch_name is up to date, rebase forced."
+ fi
fi
-if test -n "$verbose"
+# Detach HEAD and reset the tree
+say "First, rewinding head to replay your work on top of it..."
+git checkout -q "$onto^0" || die "could not detach HEAD"
+git update-ref ORIG_HEAD $branch
+
+if test -n "$diffstat"
then
- echo "Changes from $mb to $onto:"
+ if test -n "$verbose"
+ then
+ echo "Changes from $mb to $onto:"
+ fi
# We want color (if set), but no pager
GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
fi
-# Detach HEAD and reset the tree
-echo "First, rewinding head to replay your work on top of it..."
-git checkout -q "$onto^0" || die "could not detach HEAD"
-git update-ref ORIG_HEAD $branch
-
# If the $onto is a proper descendant of the tip of the branch, then
# we just fast forwarded.
if test "$mb" = "$branch"
then
- echo >&2 "Fast-forwarded $branch_name to $onto_name."
+ say "Fast-forwarded $branch_name to $onto_name."
move_to_original_branch
exit 0
fi
test 0 != $ret -a -d "$GIT_DIR"/rebase-apply &&
echo $head_name > "$GIT_DIR"/rebase-apply/head-name &&
echo $onto > "$GIT_DIR"/rebase-apply/onto &&
- echo $orig_head > "$GIT_DIR"/rebase-apply/orig-head
+ echo $orig_head > "$GIT_DIR"/rebase-apply/orig-head &&
+ echo "$GIT_QUIET" > "$GIT_DIR"/rebase-apply/quiet
exit $ret
fi
echo "$prev_head" > "$dotest/prev_head"
echo "$orig_head" > "$dotest/orig-head"
echo "$head_name" > "$dotest/head-name"
+echo "$GIT_QUIET" > "$dotest/quiet"
msgnum=0
for cmt in `git rev-list --reverse --no-merges "$revisions"`