diff options
Diffstat (limited to 'git-rebase.sh')
-rwxr-xr-x | git-rebase.sh | 105 |
1 files changed, 67 insertions, 38 deletions
diff --git a/git-rebase.sh b/git-rebase.sh index 9eb276ba20..47ca3b990b 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -5,6 +5,7 @@ SUBDIRECTORY_OK=Yes OPTIONS_KEEPDASHDASH= +OPTIONS_STUCKLONG=t OPTIONS_SPEC="\ git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>] git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>] @@ -14,6 +15,7 @@ git-rebase --continue | --abort | --skip | --edit-todo v,verbose! display a diffstat of what changed upstream q,quiet! be quiet. implies --no-stat autostash! automatically stash/stash pop before and after +fork-point use 'merge-base --fork-point' to refine 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 @@ -35,6 +37,7 @@ ignore-date! passed to 'git am' whitespace=! passed to 'git apply' ignore-whitespace! passed to 'git apply' C=! passed to 'git apply' +S,gpg-sign? GPG-sign commits Actions: continue! continue abort! abort and check out the original branch @@ -66,6 +69,7 @@ verbose= diffstat= test "$(git config --bool rebase.stat)" = true && diffstat=t autostash="$(git config --bool rebase.autostash || echo false)" +fork_point=auto git_am_opt= rebase_root= force_rebase= @@ -82,6 +86,7 @@ preserve_merges= autosquash= keep_empty= test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t +gpg_sign_opt= read_basic_state () { test -f "$state_dir/head-name" && @@ -104,6 +109,8 @@ read_basic_state () { strategy_opts="$(cat "$state_dir"/strategy_opts)" test -f "$state_dir"/allow_rerere_autoupdate && allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)" + test -f "$state_dir"/gpg_sign_opt && + gpg_sign_opt="$(cat "$state_dir"/gpg_sign_opt)" } write_basic_state () { @@ -117,6 +124,7 @@ write_basic_state () { "$state_dir"/strategy_opts test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \ "$state_dir"/allow_rerere_autoupdate + test -n "$gpg_sign_opt" && echo "$gpg_sign_opt" > "$state_dir"/gpg_sign_opt } output () { @@ -155,11 +163,8 @@ apply_autostash () { then echo "$(gettext 'Applied autostash.')" else - ref_stash=refs/stash && - >>"$GIT_DIR/logs/$ref_stash" && - git update-ref -m "autostash" $ref_stash $stash_sha1 || - die "$(eval_gettext 'Cannot store $stash_sha1')" - + git stash store -m "autostash" -q $stash_sha1 || + die "$(eval_gettext "Cannot store \$stash_sha1")" gettext 'Applying autostash resulted in conflicts. Your changes are safe in the stash. You can run "git stash pop" or "git stash drop" at any time. @@ -237,23 +242,19 @@ do test $total_argc -eq 2 || usage action=${1##--} ;; - --onto) - test 2 -le "$#" || usage - onto="$2" - shift + --onto=*) + onto="${1#--onto=}" ;; - -x) - test 2 -le "$#" || usage - cmd="${cmd}exec $2${LF}" - shift + --exec=*) + cmd="${cmd}exec ${1#--exec=}${LF}" ;; - -i) + --interactive) interactive_rebase=explicit ;; - -k) + --keep-empty) keep_empty=yes ;; - -p) + --preserve-merges) preserve_merges=t test -z "$interactive_rebase" && interactive_rebase=implied ;; @@ -263,21 +264,25 @@ do --no-autosquash) autosquash= ;; - -M|-m) + --fork-point) + fork_point=t + ;; + --no-fork-point) + fork_point= + ;; + --merge) do_merge=t ;; - -X) - shift - strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--$1")" + --strategy-option=*) + strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--${1#--strategy-option=}")" do_merge=t test -z "$strategy" && strategy=recursive ;; - -s) - shift - strategy="$1" + --strategy=*) + strategy="${1#--strategy=}" do_merge=t ;; - -n) + --no-stat) diffstat= ;; --stat) @@ -286,21 +291,20 @@ do --autostash) autostash=true ;; - -v) + --verbose) verbose=t diffstat=t GIT_QUIET= ;; - -q) + --quiet) GIT_QUIET=t git_am_opt="$git_am_opt -q" verbose= diffstat= ;; - --whitespace) - shift - git_am_opt="$git_am_opt --whitespace=$1" - case "$1" in + --whitespace=*) + git_am_opt="$git_am_opt --whitespace=${1#--whitespace=}" + case "${1#--whitespace=}" in fix|strip) force_rebase=t ;; @@ -313,19 +317,24 @@ do git_am_opt="$git_am_opt $1" force_rebase=t ;; - -C) - shift - git_am_opt="$git_am_opt -C$1" + -C*) + git_am_opt="$git_am_opt $1" ;; --root) rebase_root=t ;; - -f|--no-ff) + --force-rebase|--no-ff) force_rebase=t ;; --rerere-autoupdate|--no-rerere-autoupdate) allow_rerere_autoupdate="$1" ;; + --gpg-sign) + gpg_sign_opt=-S + ;; + --gpg-sign=*) + gpg_sign_opt="-S${1#--gpg-sign=}" + ;; --) shift break @@ -440,12 +449,18 @@ then error_on_missing_default_upstream "rebase" "rebase" \ "against" "git rebase <branch>" fi + + test "$fork_point" = auto && fork_point=t ;; *) upstream_name="$1" + if test "$upstream_name" = "-" + then + upstream_name="@{-1}" + fi shift ;; esac - upstream=`git rev-parse --verify "${upstream_name}^0"` || + upstream=$(peel_committish "${upstream_name}") || die "$(eval_gettext "invalid upstream \$upstream_name")" upstream_arg="$upstream_name" else @@ -481,7 +496,7 @@ case "$onto_name" in fi ;; *) - onto=$(git rev-parse --verify "${onto_name}^0") || + onto=$(peel_committish "$onto_name") || die "$(eval_gettext "Does not point to a valid commit: \$onto_name")" ;; esac @@ -525,6 +540,16 @@ case "$#" in ;; esac +if test "$fork_point" = t +then + new_upstream=$(git merge-base --fork-point "$upstream_name" \ + "${switch_to:-HEAD}") + if test -n "$new_upstream" + then + upstream=$new_upstream + fi +fi + if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null then stash_sha1=$(git stash create "autostash") || @@ -554,7 +579,9 @@ then if test -z "$force_rebase" then # Lazily switch to the target branch if needed... - test -z "$switch_to" || git checkout "$switch_to" -- + test -z "$switch_to" || + GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to" \ + git checkout "$switch_to" -- say "$(eval_gettext "Current branch \$branch_name is up to date.")" finish_rebase exit 0 @@ -580,7 +607,9 @@ test "$type" = interactive && run_specific_rebase # Detach HEAD and reset the tree say "$(gettext "First, rewinding head to replay your work on top of it...")" -git checkout -q "$onto^0" || die "could not detach HEAD" + +GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name" \ + 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 |