mirror of
https://github.com/git/git
synced 2024-08-28 20:20:07 +00:00
Merge branch 'mz/rebase'
* mz/rebase: (34 commits) rebase: define options in OPTIONS_SPEC Makefile: do not install sourced rebase scripts rebase: use @{upstream} if no upstream specified rebase -i: remove unnecessary state rebase-root rebase -i: don't read unused variable preserve_merges git-rebase--am: remove unnecessary --3way option rebase -m: don't print exit code 2 when merge fails rebase -m: remember allow_rerere_autoupdate option rebase: remember strategy and strategy options rebase: remember verbose option rebase: extract code for writing basic state rebase: factor out sub command handling rebase: make -v a tiny bit more verbose rebase -i: align variable names rebase: show consistent conflict resolution hint rebase: extract am code to new source file rebase: extract merge code to new source file rebase: remove $branch as synonym for $orig_head rebase -i: support --stat rebase: factor out call to pre-rebase hook ...
This commit is contained in:
commit
78c6e0f3fa
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -101,7 +101,9 @@
|
|||
/git-quiltimport
|
||||
/git-read-tree
|
||||
/git-rebase
|
||||
/git-rebase--am
|
||||
/git-rebase--interactive
|
||||
/git-rebase--merge
|
||||
/git-receive-pack
|
||||
/git-reflog
|
||||
/git-relink
|
||||
|
|
|
@ -641,7 +641,7 @@ branch.<name>.remote::
|
|||
|
||||
branch.<name>.merge::
|
||||
Defines, together with branch.<name>.remote, the upstream branch
|
||||
for the given branch. It tells 'git fetch'/'git pull' which
|
||||
for the given branch. It tells 'git fetch'/'git pull'/'git rebase' which
|
||||
branch to merge and can also affect 'git push' (see push.default).
|
||||
When in branch <name>, it tells 'git fetch' the default
|
||||
refspec to be marked for merging in FETCH_HEAD. The value is
|
||||
|
|
|
@ -9,7 +9,7 @@ SYNOPSIS
|
|||
--------
|
||||
[verse]
|
||||
'git rebase' [-i | --interactive] [options] [--onto <newbase>]
|
||||
<upstream> [<branch>]
|
||||
[<upstream>] [<branch>]
|
||||
'git rebase' [-i | --interactive] [options] --onto <newbase>
|
||||
--root [<branch>]
|
||||
|
||||
|
@ -21,6 +21,12 @@ If <branch> is specified, 'git rebase' will perform an automatic
|
|||
`git checkout <branch>` before doing anything else. Otherwise
|
||||
it remains on the current branch.
|
||||
|
||||
If <upstream> is not specified, the upstream configured in
|
||||
branch.<name>.remote and branch.<name>.merge options will be used; see
|
||||
linkgit:git-config[1] for details. If you are currently not on any
|
||||
branch or if the current branch does not have a configured upstream,
|
||||
the rebase will abort.
|
||||
|
||||
All changes made by commits in the current branch but that are not
|
||||
in <upstream> are saved to a temporary area. This is the same set
|
||||
of commits that would be shown by `git log <upstream>..HEAD` (or
|
||||
|
@ -217,7 +223,8 @@ leave out at most one of A and B, in which case it defaults to HEAD.
|
|||
|
||||
<upstream>::
|
||||
Upstream branch to compare against. May be any valid commit,
|
||||
not just an existing branch name.
|
||||
not just an existing branch name. Defaults to the configured
|
||||
upstream for the current branch.
|
||||
|
||||
<branch>::
|
||||
Working branch; defaults to HEAD.
|
||||
|
|
4
Makefile
4
Makefile
|
@ -368,7 +368,6 @@ SCRIPT_SH += git-merge-resolve.sh
|
|||
SCRIPT_SH += git-mergetool.sh
|
||||
SCRIPT_SH += git-pull.sh
|
||||
SCRIPT_SH += git-quiltimport.sh
|
||||
SCRIPT_SH += git-rebase--interactive.sh
|
||||
SCRIPT_SH += git-rebase.sh
|
||||
SCRIPT_SH += git-repack.sh
|
||||
SCRIPT_SH += git-request-pull.sh
|
||||
|
@ -378,6 +377,9 @@ SCRIPT_SH += git-web--browse.sh
|
|||
|
||||
SCRIPT_LIB += git-mergetool--lib
|
||||
SCRIPT_LIB += git-parse-remote
|
||||
SCRIPT_LIB += git-rebase--am
|
||||
SCRIPT_LIB += git-rebase--interactive
|
||||
SCRIPT_LIB += git-rebase--merge
|
||||
SCRIPT_LIB += git-sh-setup
|
||||
|
||||
SCRIPT_PERL += git-add--interactive.perl
|
||||
|
|
|
@ -50,3 +50,41 @@ get_remote_merge_branch () {
|
|||
esac
|
||||
esac
|
||||
}
|
||||
|
||||
error_on_missing_default_upstream () {
|
||||
cmd="$1"
|
||||
op_type="$2"
|
||||
op_prep="$3"
|
||||
example="$4"
|
||||
branch_name=$(git symbolic-ref -q HEAD)
|
||||
if test -z "$branch_name"
|
||||
then
|
||||
echo "You are not currently on a branch, so I cannot use any
|
||||
'branch.<branchname>.merge' in your configuration file.
|
||||
Please specify which branch you want to $op_type $op_prep on the command
|
||||
line and try again (e.g. '$example').
|
||||
See git-${cmd}(1) for details."
|
||||
else
|
||||
echo "You asked me to $cmd without telling me which branch you
|
||||
want to $op_type $op_prep, and 'branch.${branch_name#refs/heads/}.merge' in
|
||||
your configuration file does not tell me, either. Please
|
||||
specify which branch you want to use on the command line and
|
||||
try again (e.g. '$example').
|
||||
See git-${cmd}(1) for details.
|
||||
|
||||
If you often $op_type $op_prep the same branch, you may want to
|
||||
use something like the following in your configuration file:
|
||||
[branch \"${branch_name#refs/heads/}\"]
|
||||
remote = <nickname>
|
||||
merge = <remote-ref>"
|
||||
test rebase = "$op_type" &&
|
||||
echo " rebase = true"
|
||||
echo "
|
||||
[remote \"<nickname>\"]
|
||||
url = <url>
|
||||
fetch = <refspec>
|
||||
|
||||
See git-config(1) for details."
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
|
32
git-pull.sh
32
git-pull.sh
|
@ -168,34 +168,10 @@ error_on_no_merge_candidates () {
|
|||
echo "You asked to pull from the remote '$1', but did not specify"
|
||||
echo "a branch. Because this is not the default configured remote"
|
||||
echo "for your current branch, you must specify a branch on the command line."
|
||||
elif [ -z "$curr_branch" ]; then
|
||||
echo "You are not currently on a branch, so I cannot use any"
|
||||
echo "'branch.<branchname>.merge' in your configuration file."
|
||||
echo "Please specify which remote branch you want to use on the command"
|
||||
echo "line and try again (e.g. 'git pull <repository> <refspec>')."
|
||||
echo "See git-pull(1) for details."
|
||||
elif [ -z "$upstream" ]; then
|
||||
echo "You asked me to pull without telling me which branch you"
|
||||
echo "want to $op_type $op_prep, and 'branch.${curr_branch}.merge' in"
|
||||
echo "your configuration file does not tell me, either. Please"
|
||||
echo "specify which branch you want to use on the command line and"
|
||||
echo "try again (e.g. 'git pull <repository> <refspec>')."
|
||||
echo "See git-pull(1) for details."
|
||||
echo
|
||||
echo "If you often $op_type $op_prep the same branch, you may want to"
|
||||
echo "use something like the following in your configuration file:"
|
||||
echo
|
||||
echo " [branch \"${curr_branch}\"]"
|
||||
echo " remote = <nickname>"
|
||||
echo " merge = <remote-ref>"
|
||||
test rebase = "$op_type" &&
|
||||
echo " rebase = true"
|
||||
echo
|
||||
echo " [remote \"<nickname>\"]"
|
||||
echo " url = <url>"
|
||||
echo " fetch = <refspec>"
|
||||
echo
|
||||
echo "See git-config(1) for details."
|
||||
elif [ -z "$curr_branch" -o -z "$upstream" ]; then
|
||||
. git-parse-remote
|
||||
error_on_missing_default_upstream "pull" $op_type $op_prep \
|
||||
"git pull <repository> <refspec>"
|
||||
else
|
||||
echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'"
|
||||
echo "from the remote, but no such ref was fetched."
|
||||
|
|
30
git-rebase--am.sh
Normal file
30
git-rebase--am.sh
Normal file
|
@ -0,0 +1,30 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2010 Junio C Hamano.
|
||||
#
|
||||
|
||||
. git-sh-setup
|
||||
|
||||
case "$action" in
|
||||
continue)
|
||||
git am --resolved --resolvemsg="$resolvemsg" &&
|
||||
move_to_original_branch
|
||||
exit
|
||||
;;
|
||||
skip)
|
||||
git am --skip --resolvemsg="$resolvemsg" &&
|
||||
move_to_original_branch
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
|
||||
test -n "$rebase_root" && root_flag=--root
|
||||
|
||||
git format-patch -k --stdout --full-index --ignore-if-in-upstream \
|
||||
--src-prefix=a/ --dst-prefix=b/ \
|
||||
--no-renames $root_flag "$revisions" |
|
||||
git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" &&
|
||||
move_to_original_branch
|
||||
ret=$?
|
||||
test 0 != $ret -a -d "$state_dir" && write_basic_state
|
||||
exit $ret
|
753
git-rebase--interactive.sh
Executable file → Normal file
753
git-rebase--interactive.sh
Executable file → Normal file
File diff suppressed because it is too large
Load diff
151
git-rebase--merge.sh
Normal file
151
git-rebase--merge.sh
Normal file
|
@ -0,0 +1,151 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2010 Junio C Hamano.
|
||||
#
|
||||
|
||||
. git-sh-setup
|
||||
|
||||
prec=4
|
||||
|
||||
read_state () {
|
||||
onto_name=$(cat "$state_dir"/onto_name) &&
|
||||
end=$(cat "$state_dir"/end) &&
|
||||
msgnum=$(cat "$state_dir"/msgnum)
|
||||
}
|
||||
|
||||
continue_merge () {
|
||||
test -d "$state_dir" || die "$state_dir directory does not exist"
|
||||
|
||||
unmerged=$(git ls-files -u)
|
||||
if test -n "$unmerged"
|
||||
then
|
||||
echo "You still have unmerged paths in your index"
|
||||
echo "did you forget to use git add?"
|
||||
die "$resolvemsg"
|
||||
fi
|
||||
|
||||
cmt=`cat "$state_dir/current"`
|
||||
if ! git diff-index --quiet --ignore-submodules HEAD --
|
||||
then
|
||||
if ! git commit --no-verify -C "$cmt"
|
||||
then
|
||||
echo "Commit failed, please do not call \"git commit\""
|
||||
echo "directly, but instead do one of the following: "
|
||||
die "$resolvemsg"
|
||||
fi
|
||||
if test -z "$GIT_QUIET"
|
||||
then
|
||||
printf "Committed: %0${prec}d " $msgnum
|
||||
fi
|
||||
echo "$cmt $(git rev-parse HEAD^0)" >> "$state_dir/rewritten"
|
||||
else
|
||||
if test -z "$GIT_QUIET"
|
||||
then
|
||||
printf "Already applied: %0${prec}d " $msgnum
|
||||
fi
|
||||
fi
|
||||
test -z "$GIT_QUIET" &&
|
||||
GIT_PAGER='' git log --format=%s -1 "$cmt"
|
||||
|
||||
# onto the next patch:
|
||||
msgnum=$(($msgnum + 1))
|
||||
echo "$msgnum" >"$state_dir/msgnum"
|
||||
}
|
||||
|
||||
call_merge () {
|
||||
cmt="$(cat "$state_dir/cmt.$1")"
|
||||
echo "$cmt" > "$state_dir/current"
|
||||
hd=$(git rev-parse --verify HEAD)
|
||||
cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)
|
||||
msgnum=$(cat "$state_dir/msgnum")
|
||||
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
|
||||
eval GITHEAD_$hd='$onto_name'
|
||||
export GITHEAD_$cmt GITHEAD_$hd
|
||||
if test -n "$GIT_QUIET"
|
||||
then
|
||||
GIT_MERGE_VERBOSITY=1 && export GIT_MERGE_VERBOSITY
|
||||
fi
|
||||
test -z "$strategy" && strategy=recursive
|
||||
eval 'git-merge-$strategy' $strategy_opts '"$cmt^" -- "$hd" "$cmt"'
|
||||
rv=$?
|
||||
case "$rv" in
|
||||
0)
|
||||
unset GITHEAD_$cmt GITHEAD_$hd
|
||||
return
|
||||
;;
|
||||
1)
|
||||
git rerere $allow_rerere_autoupdate
|
||||
die "$resolvemsg"
|
||||
;;
|
||||
2)
|
||||
echo "Strategy: $strategy failed, try another" 1>&2
|
||||
die "$resolvemsg"
|
||||
;;
|
||||
*)
|
||||
die "Unknown exit code ($rv) from command:" \
|
||||
"git-merge-$strategy $cmt^ -- HEAD $cmt"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
finish_rb_merge () {
|
||||
move_to_original_branch
|
||||
git notes copy --for-rewrite=rebase < "$state_dir"/rewritten
|
||||
if test -x "$GIT_DIR"/hooks/post-rewrite &&
|
||||
test -s "$state_dir"/rewritten; then
|
||||
"$GIT_DIR"/hooks/post-rewrite rebase < "$state_dir"/rewritten
|
||||
fi
|
||||
rm -r "$state_dir"
|
||||
say All done.
|
||||
}
|
||||
|
||||
case "$action" in
|
||||
continue)
|
||||
read_state
|
||||
continue_merge
|
||||
while test "$msgnum" -le "$end"
|
||||
do
|
||||
call_merge "$msgnum"
|
||||
continue_merge
|
||||
done
|
||||
finish_rb_merge
|
||||
exit
|
||||
;;
|
||||
skip)
|
||||
read_state
|
||||
git rerere clear
|
||||
msgnum=$(($msgnum + 1))
|
||||
while test "$msgnum" -le "$end"
|
||||
do
|
||||
call_merge "$msgnum"
|
||||
continue_merge
|
||||
done
|
||||
finish_rb_merge
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
|
||||
mkdir -p "$state_dir"
|
||||
echo "$onto_name" > "$state_dir/onto_name"
|
||||
write_basic_state
|
||||
|
||||
msgnum=0
|
||||
for cmt in `git rev-list --reverse --no-merges "$revisions"`
|
||||
do
|
||||
msgnum=$(($msgnum + 1))
|
||||
echo "$cmt" > "$state_dir/cmt.$msgnum"
|
||||
done
|
||||
|
||||
echo 1 >"$state_dir/msgnum"
|
||||
echo $msgnum >"$state_dir/end"
|
||||
|
||||
end=$msgnum
|
||||
msgnum=1
|
||||
|
||||
while test "$msgnum" -le "$end"
|
||||
do
|
||||
call_merge "$msgnum"
|
||||
continue_merge
|
||||
done
|
||||
|
||||
finish_rb_merge
|
598
git-rebase.sh
598
git-rebase.sh
|
@ -3,7 +3,7 @@
|
|||
# Copyright (c) 2005 Junio C Hamano.
|
||||
#
|
||||
|
||||
USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] (<upstream>|--root) [<branch>] [--quiet | -q]'
|
||||
USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--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>
|
||||
|
@ -28,7 +28,39 @@ Example: git-rebase master~1 topic
|
|||
'
|
||||
|
||||
SUBDIRECTORY_OK=Yes
|
||||
OPTIONS_SPEC=
|
||||
OPTIONS_KEEPDASHDASH=
|
||||
OPTIONS_SPEC="\
|
||||
git rebase [-i] [options] [--onto <newbase>] [<upstream>] [<branch>]
|
||||
git rebase [-i] [options] --onto <newbase> --root [<branch>]
|
||||
git-rebase [-i] --continue | --abort | --skip
|
||||
--
|
||||
Available options are
|
||||
v,verbose! display a diffstat of what changed upstream
|
||||
q,quiet! be quiet. implies --no-stat
|
||||
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
|
||||
no-ff! cherry-pick all commits, even if unchanged
|
||||
m,merge! use merging strategies to rebase
|
||||
i,interactive! let the user edit the list of commits to rebase
|
||||
f,force-rebase! force rebase even if branch is up to date
|
||||
X,strategy-option=! pass the argument through to the merge strategy
|
||||
stat! display a diffstat of what changed upstream
|
||||
n,no-stat! do not show diffstat of what changed upstream
|
||||
verify allow pre-rebase hook to run
|
||||
rerere-autoupdate allow rerere to update index with resolved conflicts
|
||||
root! rebase all reachable commits up to the root(s)
|
||||
autosquash move commits that begin with squash!/fixup! under -i
|
||||
committer-date-is-author-date! passed to 'git am'
|
||||
ignore-date! passed to 'git am'
|
||||
whitespace=! passed to 'git apply'
|
||||
ignore-whitespace! passed to 'git apply'
|
||||
C=! passed to 'git apply'
|
||||
Actions:
|
||||
continue! continue rebasing process
|
||||
abort! abort rebasing process and restore original branch
|
||||
skip! skip current patch and continue rebasing process
|
||||
"
|
||||
. git-sh-setup
|
||||
set_reflog_action rebase
|
||||
require_work_tree
|
||||
|
@ -36,18 +68,18 @@ cd_to_toplevel
|
|||
|
||||
LF='
|
||||
'
|
||||
OK_TO_SKIP_PRE_REBASE=
|
||||
RESOLVEMSG="
|
||||
ok_to_skip_pre_rebase=
|
||||
resolvemsg="
|
||||
When you have resolved this problem run \"git rebase --continue\".
|
||||
If you would prefer to skip this patch, instead run \"git rebase --skip\".
|
||||
To restore the original branch and stop rebasing run \"git rebase --abort\".
|
||||
"
|
||||
unset newbase
|
||||
strategy=recursive
|
||||
unset onto
|
||||
strategy=
|
||||
strategy_opts=
|
||||
do_merge=
|
||||
dotest="$GIT_DIR"/rebase-merge
|
||||
prec=4
|
||||
merge_dir="$GIT_DIR"/rebase-merge
|
||||
apply_dir="$GIT_DIR"/rebase-apply
|
||||
verbose=
|
||||
diffstat=
|
||||
test "$(git config --bool rebase.stat)" = true && diffstat=t
|
||||
|
@ -55,92 +87,67 @@ git_am_opt=
|
|||
rebase_root=
|
||||
force_rebase=
|
||||
allow_rerere_autoupdate=
|
||||
# Non-empty if a rebase was in progress when 'git rebase' was invoked
|
||||
in_progress=
|
||||
# One of {am, merge, interactive}
|
||||
type=
|
||||
# One of {"$GIT_DIR"/rebase-apply, "$GIT_DIR"/rebase-merge}
|
||||
state_dir=
|
||||
# One of {'', continue, skip, abort}, as parsed from command line
|
||||
action=
|
||||
preserve_merges=
|
||||
autosquash=
|
||||
test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
|
||||
|
||||
continue_merge () {
|
||||
test -n "$prev_head" || die "prev_head must be defined"
|
||||
test -d "$dotest" || die "$dotest directory does not exist"
|
||||
|
||||
unmerged=$(git ls-files -u)
|
||||
if test -n "$unmerged"
|
||||
read_basic_state () {
|
||||
head_name=$(cat "$state_dir"/head-name) &&
|
||||
onto=$(cat "$state_dir"/onto) &&
|
||||
# We always write to orig-head, but interactive rebase used to write to
|
||||
# head. Fall back to reading from head to cover for the case that the
|
||||
# user upgraded git with an ongoing interactive rebase.
|
||||
if test -f "$state_dir"/orig-head
|
||||
then
|
||||
echo "You still have unmerged paths in your index"
|
||||
echo "did you forget to use git add?"
|
||||
die "$RESOLVEMSG"
|
||||
fi
|
||||
|
||||
cmt=`cat "$dotest/current"`
|
||||
if ! git diff-index --quiet --ignore-submodules HEAD --
|
||||
then
|
||||
if ! git commit --no-verify -C "$cmt"
|
||||
then
|
||||
echo "Commit failed, please do not call \"git commit\""
|
||||
echo "directly, but instead do one of the following: "
|
||||
die "$RESOLVEMSG"
|
||||
fi
|
||||
if test -z "$GIT_QUIET"
|
||||
then
|
||||
printf "Committed: %0${prec}d " $msgnum
|
||||
fi
|
||||
echo "$cmt $(git rev-parse HEAD^0)" >> "$dotest/rewritten"
|
||||
orig_head=$(cat "$state_dir"/orig-head)
|
||||
else
|
||||
if test -z "$GIT_QUIET"
|
||||
then
|
||||
printf "Already applied: %0${prec}d " $msgnum
|
||||
fi
|
||||
fi
|
||||
test -z "$GIT_QUIET" &&
|
||||
GIT_PAGER='' git log --format=%s -1 "$cmt"
|
||||
|
||||
prev_head=`git rev-parse HEAD^0`
|
||||
# save the resulting commit so we can read-tree on it later
|
||||
echo "$prev_head" > "$dotest/prev_head"
|
||||
|
||||
# onto the next patch:
|
||||
msgnum=$(($msgnum + 1))
|
||||
echo "$msgnum" >"$dotest/msgnum"
|
||||
orig_head=$(cat "$state_dir"/head)
|
||||
fi &&
|
||||
GIT_QUIET=$(cat "$state_dir"/quiet) &&
|
||||
test -f "$state_dir"/verbose && verbose=t
|
||||
test -f "$state_dir"/strategy && strategy="$(cat "$state_dir"/strategy)"
|
||||
test -f "$state_dir"/strategy_opts &&
|
||||
strategy_opts="$(cat "$state_dir"/strategy_opts)"
|
||||
test -f "$state_dir"/allow_rerere_autoupdate &&
|
||||
allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)"
|
||||
}
|
||||
|
||||
call_merge () {
|
||||
cmt="$(cat "$dotest/cmt.$1")"
|
||||
echo "$cmt" > "$dotest/current"
|
||||
hd=$(git rev-parse --verify HEAD)
|
||||
cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)
|
||||
msgnum=$(cat "$dotest/msgnum")
|
||||
end=$(cat "$dotest/end")
|
||||
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
|
||||
GIT_MERGE_VERBOSITY=1 && export GIT_MERGE_VERBOSITY
|
||||
fi
|
||||
eval 'git-merge-$strategy' $strategy_opts '"$cmt^" -- "$hd" "$cmt"'
|
||||
rv=$?
|
||||
case "$rv" in
|
||||
0)
|
||||
unset GITHEAD_$cmt GITHEAD_$hd
|
||||
return
|
||||
;;
|
||||
1)
|
||||
git rerere $allow_rerere_autoupdate
|
||||
die "$RESOLVEMSG"
|
||||
;;
|
||||
2)
|
||||
echo "Strategy: $rv $strategy failed, try another" 1>&2
|
||||
die "$RESOLVEMSG"
|
||||
write_basic_state () {
|
||||
echo "$head_name" > "$state_dir"/head-name &&
|
||||
echo "$onto" > "$state_dir"/onto &&
|
||||
echo "$orig_head" > "$state_dir"/orig-head &&
|
||||
echo "$GIT_QUIET" > "$state_dir"/quiet &&
|
||||
test t = "$verbose" && : > "$state_dir"/verbose
|
||||
test -n "$strategy" && echo "$strategy" > "$state_dir"/strategy
|
||||
test -n "$strategy_opts" && echo "$strategy_opts" > \
|
||||
"$state_dir"/strategy_opts
|
||||
test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \
|
||||
"$state_dir"/allow_rerere_autoupdate
|
||||
}
|
||||
|
||||
output () {
|
||||
case "$verbose" in
|
||||
'')
|
||||
output=$("$@" 2>&1 )
|
||||
status=$?
|
||||
test $status != 0 && printf "%s\n" "$output"
|
||||
return $status
|
||||
;;
|
||||
*)
|
||||
die "Unknown exit code ($rv) from command:" \
|
||||
"git-merge-$strategy $cmt^ -- HEAD $cmt"
|
||||
"$@"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
move_to_original_branch () {
|
||||
test -z "$head_name" &&
|
||||
head_name="$(cat "$dotest"/head-name)" &&
|
||||
onto="$(cat "$dotest"/onto)" &&
|
||||
orig_head="$(cat "$dotest"/orig-head)"
|
||||
case "$head_name" in
|
||||
refs/*)
|
||||
message="rebase finished: $head_name onto $onto"
|
||||
|
@ -152,42 +159,16 @@ move_to_original_branch () {
|
|||
esac
|
||||
}
|
||||
|
||||
finish_rb_merge () {
|
||||
move_to_original_branch
|
||||
git notes copy --for-rewrite=rebase < "$dotest"/rewritten
|
||||
if test -x "$GIT_DIR"/hooks/post-rewrite &&
|
||||
test -s "$dotest"/rewritten; then
|
||||
"$GIT_DIR"/hooks/post-rewrite rebase < "$dotest"/rewritten
|
||||
fi
|
||||
rm -r "$dotest"
|
||||
say All done.
|
||||
}
|
||||
|
||||
is_interactive () {
|
||||
while test $# != 0
|
||||
do
|
||||
case "$1" in
|
||||
-i|--interactive)
|
||||
interactive_rebase=explicit
|
||||
break
|
||||
;;
|
||||
-p|--preserve-merges)
|
||||
interactive_rebase=implied
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
run_specific_rebase () {
|
||||
if [ "$interactive_rebase" = implied ]; then
|
||||
GIT_EDITOR=:
|
||||
export GIT_EDITOR
|
||||
fi
|
||||
|
||||
test -n "$interactive_rebase" || test -f "$dotest"/interactive
|
||||
. git-rebase--$type
|
||||
}
|
||||
|
||||
run_pre_rebase_hook () {
|
||||
if test -z "$OK_TO_SKIP_PRE_REBASE" &&
|
||||
if test -z "$ok_to_skip_pre_rebase" &&
|
||||
test -x "$GIT_DIR/hooks/pre-rebase"
|
||||
then
|
||||
"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} ||
|
||||
|
@ -195,163 +176,94 @@ run_pre_rebase_hook () {
|
|||
fi
|
||||
}
|
||||
|
||||
test -f "$GIT_DIR"/rebase-apply/applying &&
|
||||
test -f "$apply_dir"/applying &&
|
||||
die 'It looks like git-am is in progress. Cannot rebase.'
|
||||
|
||||
is_interactive "$@" && exec git-rebase--interactive "$@"
|
||||
if test -d "$apply_dir"
|
||||
then
|
||||
type=am
|
||||
state_dir="$apply_dir"
|
||||
elif test -d "$merge_dir"
|
||||
then
|
||||
if test -f "$merge_dir"/interactive
|
||||
then
|
||||
type=interactive
|
||||
interactive_rebase=explicit
|
||||
else
|
||||
type=merge
|
||||
fi
|
||||
state_dir="$merge_dir"
|
||||
fi
|
||||
test -n "$type" && in_progress=t
|
||||
|
||||
total_argc=$#
|
||||
while test $# != 0
|
||||
do
|
||||
case "$1" in
|
||||
--no-verify)
|
||||
OK_TO_SKIP_PRE_REBASE=yes
|
||||
ok_to_skip_pre_rebase=yes
|
||||
;;
|
||||
--verify)
|
||||
OK_TO_SKIP_PRE_REBASE=
|
||||
ok_to_skip_pre_rebase=
|
||||
;;
|
||||
--continue)
|
||||
test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply ||
|
||||
die "No rebase in progress?"
|
||||
|
||||
git update-index --ignore-submodules --refresh &&
|
||||
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
|
||||
}
|
||||
if test -d "$dotest"
|
||||
then
|
||||
prev_head=$(cat "$dotest/prev_head")
|
||||
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
|
||||
call_merge "$msgnum"
|
||||
continue_merge
|
||||
done
|
||||
finish_rb_merge
|
||||
exit
|
||||
fi
|
||||
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
|
||||
;;
|
||||
--skip)
|
||||
test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply ||
|
||||
die "No rebase in progress?"
|
||||
|
||||
git reset --hard HEAD || exit $?
|
||||
if test -d "$dotest"
|
||||
then
|
||||
git rerere clear
|
||||
prev_head=$(cat "$dotest/prev_head")
|
||||
end=$(cat "$dotest/end")
|
||||
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"
|
||||
continue_merge
|
||||
done
|
||||
finish_rb_merge
|
||||
exit
|
||||
fi
|
||||
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
|
||||
;;
|
||||
--abort)
|
||||
test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply ||
|
||||
die "No rebase in progress?"
|
||||
|
||||
git rerere clear
|
||||
|
||||
test -d "$dotest" || dotest="$GIT_DIR"/rebase-apply
|
||||
|
||||
head_name="$(cat "$dotest"/head-name)" &&
|
||||
case "$head_name" in
|
||||
refs/*)
|
||||
git symbolic-ref HEAD $head_name ||
|
||||
die "Could not move back to $head_name"
|
||||
;;
|
||||
esac
|
||||
git reset --hard $(cat "$dotest/orig-head")
|
||||
rm -r "$dotest"
|
||||
exit
|
||||
--continue|--skip|--abort)
|
||||
test $total_argc -eq 2 || usage
|
||||
action=${1##--}
|
||||
;;
|
||||
--onto)
|
||||
test 2 -le "$#" || usage
|
||||
newbase="$2"
|
||||
onto="$2"
|
||||
shift
|
||||
;;
|
||||
-M|-m|--m|--me|--mer|--merg|--merge)
|
||||
-i)
|
||||
interactive_rebase=explicit
|
||||
;;
|
||||
-p)
|
||||
preserve_merges=t
|
||||
test -z "$interactive_rebase" && interactive_rebase=implied
|
||||
;;
|
||||
--autosquash)
|
||||
autosquash=t
|
||||
;;
|
||||
--no-autosquash)
|
||||
autosquash=
|
||||
;;
|
||||
-M|-m)
|
||||
do_merge=t
|
||||
;;
|
||||
-X*|--strategy-option*)
|
||||
case "$#,$1" in
|
||||
1,-X|1,--strategy-option)
|
||||
usage ;;
|
||||
*,-X|*,--strategy-option)
|
||||
newopt="$2"
|
||||
shift ;;
|
||||
*,--strategy-option=*)
|
||||
newopt="$(expr " $1" : ' --strategy-option=\(.*\)')" ;;
|
||||
*,-X*)
|
||||
newopt="$(expr " $1" : ' -X\(.*\)')" ;;
|
||||
1,*)
|
||||
usage ;;
|
||||
esac
|
||||
strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--$newopt")"
|
||||
-X)
|
||||
shift
|
||||
strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--$1")"
|
||||
do_merge=t
|
||||
test -z "$strategy" && strategy=recursive
|
||||
;;
|
||||
-s)
|
||||
shift
|
||||
strategy="$1"
|
||||
do_merge=t
|
||||
;;
|
||||
-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
|
||||
--strateg=*|--strategy=*|\
|
||||
-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
|
||||
case "$#,$1" in
|
||||
*,*=*)
|
||||
strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
|
||||
1,*)
|
||||
usage ;;
|
||||
*)
|
||||
strategy="$2"
|
||||
shift ;;
|
||||
esac
|
||||
do_merge=t
|
||||
;;
|
||||
-n|--no-stat)
|
||||
-n)
|
||||
diffstat=
|
||||
;;
|
||||
--stat)
|
||||
diffstat=t
|
||||
;;
|
||||
-v|--verbose)
|
||||
-v)
|
||||
verbose=t
|
||||
diffstat=t
|
||||
GIT_QUIET=
|
||||
;;
|
||||
-q|--quiet)
|
||||
-q)
|
||||
GIT_QUIET=t
|
||||
git_am_opt="$git_am_opt -q"
|
||||
verbose=
|
||||
diffstat=
|
||||
;;
|
||||
--whitespace=*)
|
||||
git_am_opt="$git_am_opt $1"
|
||||
--whitespace)
|
||||
shift
|
||||
git_am_opt="$git_am_opt --whitespace=$1"
|
||||
case "$1" in
|
||||
--whitespace=fix|--whitespace=strip)
|
||||
fix|strip)
|
||||
force_rebase=t
|
||||
;;
|
||||
esac
|
||||
|
@ -363,22 +275,21 @@ do
|
|||
git_am_opt="$git_am_opt $1"
|
||||
force_rebase=t
|
||||
;;
|
||||
-C*)
|
||||
git_am_opt="$git_am_opt $1"
|
||||
-C)
|
||||
shift
|
||||
git_am_opt="$git_am_opt -C$1"
|
||||
;;
|
||||
--root)
|
||||
rebase_root=t
|
||||
;;
|
||||
-f|--f|--fo|--for|--forc|--force|--force-r|--force-re|--force-reb|--force-reba|--force-rebas|--force-rebase|--no-ff)
|
||||
-f|--no-ff)
|
||||
force_rebase=t
|
||||
;;
|
||||
--rerere-autoupdate|--no-rerere-autoupdate)
|
||||
allow_rerere_autoupdate="$1"
|
||||
;;
|
||||
-*)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
|
@ -386,58 +297,106 @@ do
|
|||
done
|
||||
test $# -gt 2 && usage
|
||||
|
||||
if test $# -eq 0 && test -z "$rebase_root"
|
||||
if test -n "$action"
|
||||
then
|
||||
test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply || usage
|
||||
test -d "$dotest" -o -f "$GIT_DIR"/rebase-apply/rebasing &&
|
||||
die 'A rebase is in progress, try --continue, --skip or --abort.'
|
||||
test -z "$in_progress" && die "No rebase in progress?"
|
||||
# Only interactive rebase uses detailed reflog messages
|
||||
if test "$type" = interactive && test "$GIT_REFLOG_ACTION" = rebase
|
||||
then
|
||||
GIT_REFLOG_ACTION="rebase -i ($action)"
|
||||
export GIT_REFLOG_ACTION
|
||||
fi
|
||||
fi
|
||||
|
||||
# Make sure we do not have $GIT_DIR/rebase-apply
|
||||
if test -z "$do_merge"
|
||||
case "$action" in
|
||||
continue)
|
||||
# Sanity check
|
||||
git rev-parse --verify HEAD >/dev/null ||
|
||||
die "Cannot read HEAD"
|
||||
git update-index --ignore-submodules --refresh &&
|
||||
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
|
||||
}
|
||||
read_basic_state
|
||||
run_specific_rebase
|
||||
;;
|
||||
skip)
|
||||
output git reset --hard HEAD || exit $?
|
||||
read_basic_state
|
||||
run_specific_rebase
|
||||
;;
|
||||
abort)
|
||||
git rerere clear
|
||||
read_basic_state
|
||||
case "$head_name" in
|
||||
refs/*)
|
||||
git symbolic-ref HEAD $head_name ||
|
||||
die "Could not move back to $head_name"
|
||||
;;
|
||||
esac
|
||||
output git reset --hard $orig_head
|
||||
rm -r "$state_dir"
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
|
||||
# Make sure no rebase is in progress
|
||||
if test -n "$in_progress"
|
||||
then
|
||||
if mkdir "$GIT_DIR"/rebase-apply 2>/dev/null
|
||||
then
|
||||
rmdir "$GIT_DIR"/rebase-apply
|
||||
else
|
||||
echo >&2 '
|
||||
It seems that I cannot create a rebase-apply directory, and
|
||||
I wonder if you are in the middle of patch application or another
|
||||
rebase. If that is not the case, please
|
||||
rm -fr '"$GIT_DIR"'/rebase-apply
|
||||
die '
|
||||
It seems that there is already a '"${state_dir##*/}"' directory, and
|
||||
I wonder if you are in the middle of another rebase. If that is the
|
||||
case, please try
|
||||
git rebase (--continue | --abort | --skip)
|
||||
If that is not the case, please
|
||||
rm -fr '"$state_dir"'
|
||||
and run me again. I am stopping in case you still have something
|
||||
valuable there.'
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if test -d "$dotest"
|
||||
then
|
||||
die "previous rebase directory $dotest still exists." \
|
||||
'Try git rebase (--continue | --abort | --skip)'
|
||||
fi
|
||||
fi
|
||||
|
||||
require_clean_work_tree "rebase" "Please commit or stash them."
|
||||
if test -n "$interactive_rebase"
|
||||
then
|
||||
type=interactive
|
||||
state_dir="$merge_dir"
|
||||
elif test -n "$do_merge"
|
||||
then
|
||||
type=merge
|
||||
state_dir="$merge_dir"
|
||||
else
|
||||
type=am
|
||||
state_dir="$apply_dir"
|
||||
fi
|
||||
|
||||
if test -z "$rebase_root"
|
||||
then
|
||||
# The upstream head must be given. Make sure it is valid.
|
||||
upstream_name="$1"
|
||||
shift
|
||||
case "$#" in
|
||||
0)
|
||||
if ! upstream_name=$(git rev-parse --symbolic-full-name \
|
||||
--verify -q @{upstream} 2>/dev/null)
|
||||
then
|
||||
. git-parse-remote
|
||||
error_on_missing_default_upstream "rebase" "rebase" \
|
||||
"against" "git rebase <upstream branch>"
|
||||
fi
|
||||
;;
|
||||
*) upstream_name="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
upstream=`git rev-parse --verify "${upstream_name}^0"` ||
|
||||
die "invalid upstream $upstream_name"
|
||||
unset root_flag
|
||||
upstream_arg="$upstream_name"
|
||||
else
|
||||
test -z "$newbase" && die "--root must be used with --onto"
|
||||
test -z "$onto" && die "You must specify --onto when using --root"
|
||||
unset upstream_name
|
||||
unset upstream
|
||||
root_flag="--root"
|
||||
upstream_arg="$root_flag"
|
||||
upstream_arg=--root
|
||||
fi
|
||||
|
||||
# Make sure the branch to rebase onto is valid.
|
||||
onto_name=${newbase-"$upstream_name"}
|
||||
onto_name=${onto-"$upstream_name"}
|
||||
case "$onto_name" in
|
||||
*...*)
|
||||
if left=${onto_name%...*} right=${onto_name#*...} &&
|
||||
|
@ -456,13 +415,11 @@ case "$onto_name" in
|
|||
fi
|
||||
;;
|
||||
*)
|
||||
onto=$(git rev-parse --verify "${onto_name}^0") || exit
|
||||
onto=$(git rev-parse --verify "${onto_name}^0") ||
|
||||
die "Does not point to a valid commit: $1"
|
||||
;;
|
||||
esac
|
||||
|
||||
# If a hook exists, give it a chance to interrupt
|
||||
run_pre_rebase_hook "$upstream_arg" "$@"
|
||||
|
||||
# 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
|
||||
|
@ -475,10 +432,10 @@ case "$#" in
|
|||
switch_to="$1"
|
||||
|
||||
if git show-ref --verify --quiet -- "refs/heads/$1" &&
|
||||
branch=$(git rev-parse -q --verify "refs/heads/$1")
|
||||
orig_head=$(git rev-parse -q --verify "refs/heads/$1")
|
||||
then
|
||||
head_name="refs/heads/$1"
|
||||
elif branch=$(git rev-parse -q --verify "$1")
|
||||
elif orig_head=$(git rev-parse -q --verify "$1")
|
||||
then
|
||||
head_name="detached HEAD"
|
||||
else
|
||||
|
@ -496,20 +453,23 @@ case "$#" in
|
|||
head_name="detached HEAD"
|
||||
branch_name=HEAD ;# detached
|
||||
fi
|
||||
branch=$(git rev-parse --verify "${branch_name}^0") || exit
|
||||
orig_head=$(git rev-parse --verify "${branch_name}^0") || exit
|
||||
;;
|
||||
esac
|
||||
orig_head=$branch
|
||||
|
||||
# Now we are rebasing commits $upstream..$branch (or with --root,
|
||||
# everything leading up to $branch) on top of $onto
|
||||
require_clean_work_tree "rebase" "Please commit or stash them."
|
||||
|
||||
# Now we are rebasing commits $upstream..$orig_head (or with --root,
|
||||
# everything leading up to $orig_head) on top of $onto
|
||||
|
||||
# Check if we are already based on $onto with linear history,
|
||||
# but this should be done only when upstream and onto are the same.
|
||||
mb=$(git merge-base "$onto" "$branch")
|
||||
if test "$upstream" = "$onto" && test "$mb" = "$onto" &&
|
||||
# but this should be done only when upstream and onto are the same
|
||||
# and if this is not an interactive rebase.
|
||||
mb=$(git merge-base "$onto" "$orig_head")
|
||||
if test "$type" != interactive && test "$upstream" = "$onto" &&
|
||||
test "$mb" = "$onto" &&
|
||||
# linear history?
|
||||
! (git rev-list --parents "$onto".."$branch" | sane_grep " .* ") > /dev/null
|
||||
! (git rev-list --parents "$onto".."$orig_head" | sane_grep " .* ") > /dev/null
|
||||
then
|
||||
if test -z "$force_rebase"
|
||||
then
|
||||
|
@ -522,10 +482,8 @@ then
|
|||
fi
|
||||
fi
|
||||
|
||||
# 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 a hook exists, give it a chance to interrupt
|
||||
run_pre_rebase_hook "$upstream_arg" "$@"
|
||||
|
||||
if test -n "$diffstat"
|
||||
then
|
||||
|
@ -537,9 +495,16 @@ then
|
|||
GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
|
||||
fi
|
||||
|
||||
test "$type" = interactive && run_specific_rebase
|
||||
|
||||
# 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 $orig_head
|
||||
|
||||
# If the $onto is a proper descendant of the tip of the branch, then
|
||||
# we just fast-forwarded.
|
||||
if test "$mb" = "$branch"
|
||||
if test "$mb" = "$orig_head"
|
||||
then
|
||||
say "Fast-forwarded $branch_name to $onto_name."
|
||||
move_to_original_branch
|
||||
|
@ -553,51 +518,4 @@ else
|
|||
revisions="$upstream..$orig_head"
|
||||
fi
|
||||
|
||||
if test -z "$do_merge"
|
||||
then
|
||||
git format-patch -k --stdout --full-index --ignore-if-in-upstream \
|
||||
--src-prefix=a/ --dst-prefix=b/ \
|
||||
--no-renames $root_flag "$revisions" |
|
||||
git am $git_am_opt --rebasing --resolvemsg="$RESOLVEMSG" &&
|
||||
move_to_original_branch
|
||||
ret=$?
|
||||
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 "$GIT_QUIET" > "$GIT_DIR"/rebase-apply/quiet
|
||||
exit $ret
|
||||
fi
|
||||
|
||||
# start doing a rebase with git-merge
|
||||
# this is rename-aware if the recursive (default) strategy is used
|
||||
|
||||
mkdir -p "$dotest"
|
||||
echo "$onto" > "$dotest/onto"
|
||||
echo "$onto_name" > "$dotest/onto_name"
|
||||
prev_head=$orig_head
|
||||
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"`
|
||||
do
|
||||
msgnum=$(($msgnum + 1))
|
||||
echo "$cmt" > "$dotest/cmt.$msgnum"
|
||||
done
|
||||
|
||||
echo 1 >"$dotest/msgnum"
|
||||
echo $msgnum >"$dotest/end"
|
||||
|
||||
end=$msgnum
|
||||
msgnum=1
|
||||
|
||||
while test "$msgnum" -le "$end"
|
||||
do
|
||||
call_merge "$msgnum"
|
||||
continue_merge
|
||||
done
|
||||
|
||||
finish_rb_merge
|
||||
run_specific_rebase
|
||||
|
|
|
@ -158,15 +158,24 @@ test_expect_success 'Show verbose error when HEAD could not be detached' '
|
|||
'
|
||||
rm -f B
|
||||
|
||||
test_expect_success 'dump usage when upstream arg is missing' '
|
||||
git checkout -b usage topic &&
|
||||
test_must_fail git rebase 2>error1 &&
|
||||
grep "[Uu]sage" error1 &&
|
||||
test_must_fail git rebase --abort 2>error2 &&
|
||||
grep "No rebase in progress" error2 &&
|
||||
test_must_fail git rebase --onto master 2>error3 &&
|
||||
grep "[Uu]sage" error3 &&
|
||||
! grep "can.t shift" error3
|
||||
test_expect_success 'fail when upstream arg is missing and not on branch' '
|
||||
git checkout topic &&
|
||||
test_must_fail git rebase >output.out &&
|
||||
grep "You are not currently on a branch" output.out
|
||||
'
|
||||
|
||||
test_expect_success 'fail when upstream arg is missing and not configured' '
|
||||
git checkout -b no-config topic &&
|
||||
test_must_fail git rebase >output.out &&
|
||||
grep "branch.no-config.merge" output.out
|
||||
'
|
||||
|
||||
test_expect_success 'default to @{upstream} when upstream arg is missing' '
|
||||
git checkout -b default topic &&
|
||||
git config branch.default.remote .
|
||||
git config branch.default.merge refs/heads/master
|
||||
git rebase &&
|
||||
test "$(git rev-parse default~1)" = "$(git rev-parse master)"
|
||||
'
|
||||
|
||||
test_expect_success 'rebase -q is quiet' '
|
||||
|
|
|
@ -35,6 +35,11 @@ test_expect_success 'rebase with git am -3 (default)' '
|
|||
test_must_fail git rebase master
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --skip can not be used with other options' '
|
||||
test_must_fail git rebase -v --skip &&
|
||||
test_must_fail git rebase --skip -v
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --skip with am -3' '
|
||||
git rebase --skip
|
||||
'
|
||||
|
|
|
@ -84,6 +84,16 @@ testrebase() {
|
|||
test_cmp reflog_before reflog_after &&
|
||||
rm reflog_before reflog_after
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --abort can not be used with other options' '
|
||||
cd "$work_dir" &&
|
||||
# Clean up the state from the previous one
|
||||
git reset --hard pre-rebase &&
|
||||
test_must_fail git rebase$type master &&
|
||||
test_must_fail git rebase -v --abort &&
|
||||
test_must_fail git rebase --abort -v &&
|
||||
git rebase --abort
|
||||
'
|
||||
}
|
||||
|
||||
testrebase "" .git/rebase-apply
|
||||
|
|
|
@ -40,4 +40,59 @@ test_expect_success 'non-interactive rebase --continue works with touched file'
|
|||
git rebase --continue
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --continue can not be used with other options' '
|
||||
test_must_fail git rebase -v --continue &&
|
||||
test_must_fail git rebase --continue -v
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --continue remembers merge strategy and options' '
|
||||
rm -fr .git/rebase-* &&
|
||||
git reset --hard commit-new-file-F2-on-topic-branch &&
|
||||
test_commit "commit-new-file-F3-on-topic-branch" F3 32 &&
|
||||
test_when_finished "rm -fr test-bin funny.was.run" &&
|
||||
mkdir test-bin &&
|
||||
cat >test-bin/git-merge-funny <<-EOF
|
||||
#!$SHELL_PATH
|
||||
case "\$1" in --opt) ;; *) exit 2 ;; esac
|
||||
shift &&
|
||||
>funny.was.run &&
|
||||
exec git merge-recursive "\$@"
|
||||
EOF
|
||||
chmod +x test-bin/git-merge-funny &&
|
||||
(
|
||||
PATH=./test-bin:$PATH
|
||||
test_must_fail git rebase -s funny -Xopt master topic
|
||||
) &&
|
||||
test -f funny.was.run &&
|
||||
rm funny.was.run &&
|
||||
echo "Resolved" >F2 &&
|
||||
git add F2 &&
|
||||
(
|
||||
PATH=./test-bin:$PATH
|
||||
git rebase --continue
|
||||
) &&
|
||||
test -f funny.was.run
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --continue remembers --rerere-autoupdate' '
|
||||
rm -fr .git/rebase-* &&
|
||||
git reset --hard commit-new-file-F3-on-topic-branch &&
|
||||
git checkout master
|
||||
test_commit "commit-new-file-F3" F3 3 &&
|
||||
git config rerere.enabled true &&
|
||||
test_must_fail git rebase -m master topic &&
|
||||
echo "Resolved" >F2 &&
|
||||
git add F2 &&
|
||||
test_must_fail git rebase --continue &&
|
||||
echo "Resolved" >F3 &&
|
||||
git add F3 &&
|
||||
git rebase --continue &&
|
||||
git reset --hard topic@{1} &&
|
||||
test_must_fail git rebase -m --rerere-autoupdate master &&
|
||||
test "$(cat F2)" = "Resolved" &&
|
||||
test_must_fail git rebase --continue &&
|
||||
test "$(cat F3)" = "Resolved" &&
|
||||
git rebase --continue
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
Loading…
Reference in a new issue