1#!/bin/sh 2# 3# Copyright (c) 2005 Junio C Hamano. 4# 5 6SUBDIRECTORY_OK=Yes 7OPTIONS_KEEPDASHDASH= 8OPTIONS_STUCKLONG=t 9OPTIONS_SPEC="\ 10git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>] 11git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>] 12git-rebase --continue | --abort | --skip | --edit-todo 13-- 14 Available options are 15v,verbose! display a diffstat of what changed upstream 16q,quiet! be quiet. implies --no-stat 17autostash! automatically stash/stash pop before and after 18fork-point use 'merge-base --fork-point' to refine upstream 19onto=! rebase onto given branch instead of upstream 20p,preserve-merges! try to recreate merges instead of ignoring them 21s,strategy=! use the given merge strategy 22no-ff! cherry-pick all commits, even if unchanged 23m,merge! use merging strategies to rebase 24i,interactive! let the user edit the list of commits to rebase 25x,exec=! add exec lines after each commit of the editable list 26k,keep-empty preserve empty commits during rebase 27f,force-rebase! force rebase even if branch is up to date 28X,strategy-option=! pass the argument through to the merge strategy 29stat! display a diffstat of what changed upstream 30n,no-stat! do not show diffstat of what changed upstream 31verify allow pre-rebase hook to run 32rerere-autoupdate allow rerere to update index with resolved conflicts 33root! rebase all reachable commits up to the root(s) 34autosquash move commits that begin with squash!/fixup! under -i 35committer-date-is-author-date! passed to 'git am' 36ignore-date! passed to 'git am' 37whitespace=! passed to 'git apply' 38ignore-whitespace! passed to 'git apply' 39C=! passed to 'git apply' 40S,gpg-sign? GPG-sign commits 41 Actions: 42continue! continue 43abort! abort and check out the original branch 44skip! skip current patch and continue 45edit-todo! edit the todo list during an interactive rebase 46" 47. git-sh-setup 48. git-sh-i18n 49set_reflog_action rebase 50require_work_tree_exists 51cd_to_toplevel 52 53LF=' 54' 55ok_to_skip_pre_rebase= 56resolvemsg=" 57$(gettext 'When you have resolved this problem, run "git rebase --continue". 58If you prefer to skip this patch, run "git rebase --skip" instead. 59To check out the original branch and stop rebasing, run "git rebase --abort".') 60" 61unset onto 62cmd= 63strategy= 64strategy_opts= 65do_merge= 66merge_dir="$GIT_DIR"/rebase-merge 67apply_dir="$GIT_DIR"/rebase-apply 68verbose= 69diffstat= 70test"$(git config --bool rebase.stat)"= true && diffstat=t 71autostash="$(git config --bool rebase.autostash || echo false)" 72fork_point=auto 73git_am_opt= 74rebase_root= 75force_rebase= 76allow_rerere_autoupdate= 77# Non-empty if a rebase was in progress when 'git rebase' was invoked 78in_progress= 79# One of {am, merge, interactive} 80type= 81# One of {"$GIT_DIR"/rebase-apply, "$GIT_DIR"/rebase-merge} 82state_dir= 83# One of {'', continue, skip, abort}, as parsed from command line 84action= 85preserve_merges= 86autosquash= 87keep_empty= 88test"$(git config --bool rebase.autosquash)"="true"&& autosquash=t 89gpg_sign_opt= 90 91read_basic_state () { 92test -f"$state_dir/head-name"&& 93test -f"$state_dir/onto"&& 94 head_name=$(cat "$state_dir"/head-name)&& 95 onto=$(cat "$state_dir"/onto)&& 96# We always write to orig-head, but interactive rebase used to write to 97# head. Fall back to reading from head to cover for the case that the 98# user upgraded git with an ongoing interactive rebase. 99iftest -f"$state_dir"/orig-head 100then 101 orig_head=$(cat "$state_dir"/orig-head) 102else 103 orig_head=$(cat "$state_dir"/head) 104fi&& 105 GIT_QUIET=$(cat "$state_dir"/quiet)&& 106test -f"$state_dir"/verbose && verbose=t 107test -f"$state_dir"/strategy && strategy="$(cat "$state_dir"/strategy)" 108test -f"$state_dir"/strategy_opts && 109 strategy_opts="$(cat "$state_dir"/strategy_opts)" 110test -f"$state_dir"/allow_rerere_autoupdate && 111 allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)" 112test -f"$state_dir"/gpg_sign_opt && 113 gpg_sign_opt="$(cat "$state_dir"/gpg_sign_opt)" 114} 115 116write_basic_state () { 117echo"$head_name">"$state_dir"/head-name&& 118echo"$onto">"$state_dir"/onto && 119echo"$orig_head">"$state_dir"/orig-head&& 120echo"$GIT_QUIET">"$state_dir"/quiet && 121test t ="$verbose"&& : >"$state_dir"/verbose 122test -n"$strategy"&&echo"$strategy">"$state_dir"/strategy 123test -n"$strategy_opts"&&echo"$strategy_opts"> \ 124"$state_dir"/strategy_opts 125test -n"$allow_rerere_autoupdate"&&echo"$allow_rerere_autoupdate"> \ 126"$state_dir"/allow_rerere_autoupdate 127test -n"$gpg_sign_opt"&&echo"$gpg_sign_opt">"$state_dir"/gpg_sign_opt 128} 129 130output () { 131case"$verbose"in 132'') 133 output=$("$@" 2>&1 ) 134 status=$? 135test$status!=0&&printf"%s\n""$output" 136return$status 137;; 138*) 139"$@" 140;; 141esac 142} 143 144move_to_original_branch () { 145case"$head_name"in 146 refs/*) 147 message="rebase finished:$head_nameonto$onto" 148 git update-ref -m"$message" \ 149$head_name $(git rev-parse HEAD) $orig_head&& 150 git symbolic-ref \ 151-m"rebase finished: returning to$head_name" \ 152 HEAD $head_name|| 153 die "$(gettext "Could not move back to $head_name")" 154;; 155esac 156} 157 158finish_rebase () { 159iftest -f"$state_dir/autostash" 160then 161 stash_sha1=$(cat "$state_dir/autostash") 162if git stash apply $stash_sha12>&1>/dev/null 163then 164echo"$(gettext 'Applied autostash.')" 165else 166 git stash store -m"autostash"-q$stash_sha1|| 167 die "$(eval_gettext "Cannot store \$stash_sha1")" 168gettext'Applying autostash resulted in conflicts. 169Your changes are safe in the stash. 170You can run "git stash pop" or "git stash drop" at any time. 171' 172fi 173fi 174 git gc --auto&& 175rm-rf"$state_dir" 176} 177 178run_specific_rebase () { 179if["$interactive_rebase"= implied ];then 180 GIT_EDITOR=: 181export GIT_EDITOR 182 autosquash= 183fi 184 . git-rebase--$type 185 ret=$? 186iftest$ret-eq0 187then 188 finish_rebase 189fi 190exit$ret 191} 192 193run_pre_rebase_hook () { 194iftest -z"$ok_to_skip_pre_rebase"&& 195test -x"$GIT_DIR/hooks/pre-rebase" 196then 197"$GIT_DIR/hooks/pre-rebase"${1+"$@"}|| 198 die "$(gettext "The pre-rebase hook refused to rebase.")" 199fi 200} 201 202test -f"$apply_dir"/applying && 203 die "$(gettext "It looks like git-am is in progress. Cannot rebase.")" 204 205iftest -d"$apply_dir" 206then 207type=am 208 state_dir="$apply_dir" 209eliftest -d"$merge_dir" 210then 211iftest -f"$merge_dir"/interactive 212then 213type=interactive 214 interactive_rebase=explicit 215else 216type=merge 217fi 218 state_dir="$merge_dir" 219fi 220test -n"$type"&& in_progress=t 221 222total_argc=$# 223whiletest$#!=0 224do 225case"$1"in 226--no-verify) 227 ok_to_skip_pre_rebase=yes 228;; 229--verify) 230 ok_to_skip_pre_rebase= 231;; 232--continue|--skip|--abort|--edit-todo) 233test$total_argc-eq2|| usage 234 action=${1##--} 235;; 236--onto=*) 237 onto="${1#--onto=}" 238;; 239--exec=*) 240 cmd="${cmd}exec${1#--exec=}${LF}" 241;; 242--interactive) 243 interactive_rebase=explicit 244;; 245--keep-empty) 246 keep_empty=yes 247;; 248--preserve-merges) 249 preserve_merges=t 250test -z"$interactive_rebase"&& interactive_rebase=implied 251;; 252--autosquash) 253 autosquash=t 254;; 255--no-autosquash) 256 autosquash= 257;; 258--fork-point) 259 fork_point=t 260;; 261--no-fork-point) 262 fork_point= 263;; 264--merge) 265 do_merge=t 266;; 267--strategy-option=*) 268 strategy_opts="$strategy_opts$(git rev-parse --sq-quote "--${1#--strategy-option=}")" 269 do_merge=t 270test -z"$strategy"&& strategy=recursive 271;; 272--strategy=*) 273 strategy="${1#--strategy=}" 274 do_merge=t 275;; 276--no-stat) 277 diffstat= 278;; 279--stat) 280 diffstat=t 281;; 282--autostash) 283 autostash=true 284;; 285--verbose) 286 verbose=t 287 diffstat=t 288 GIT_QUIET= 289;; 290--quiet) 291 GIT_QUIET=t 292 git_am_opt="$git_am_opt-q" 293 verbose= 294 diffstat= 295;; 296--whitespace=*) 297 git_am_opt="$git_am_opt--whitespace=${1#--whitespace=}" 298case"${1#--whitespace=}"in 299 fix|strip) 300 force_rebase=t 301;; 302esac 303;; 304--ignore-whitespace) 305 git_am_opt="$git_am_opt$1" 306;; 307--committer-date-is-author-date|--ignore-date) 308 git_am_opt="$git_am_opt$1" 309 force_rebase=t 310;; 311-C*) 312 git_am_opt="$git_am_opt$1" 313;; 314--root) 315 rebase_root=t 316;; 317--force-rebase|--no-ff) 318 force_rebase=t 319;; 320--rerere-autoupdate|--no-rerere-autoupdate) 321 allow_rerere_autoupdate="$1" 322;; 323--gpg-sign) 324 gpg_sign_opt=-S 325;; 326--gpg-sign=*) 327 gpg_sign_opt="-S${1#--gpg-sign=}" 328;; 329--) 330shift 331break 332;; 333esac 334shift 335done 336test$#-gt2&& usage 337 338iftest -n"$cmd"&& 339test"$interactive_rebase"!= explicit 340then 341 die "$(gettext "The --exec option must be used with the --interactive option")" 342fi 343 344iftest -n"$action" 345then 346test -z"$in_progress"&& die "$(gettext "No rebase in progress?")" 347# Only interactive rebase uses detailed reflog messages 348iftest"$type"= interactive &&test"$GIT_REFLOG_ACTION"= rebase 349then 350 GIT_REFLOG_ACTION="rebase -i ($action)" 351export GIT_REFLOG_ACTION 352fi 353fi 354 355iftest"$action"="edit-todo"&&test"$type"!="interactive" 356then 357 die "$(gettext "The --edit-todo action can only be used during interactive rebase.")" 358fi 359 360case"$action"in 361continue) 362# Sanity check 363 git rev-parse --verify HEAD >/dev/null || 364 die "$(gettext "Cannot read HEAD")" 365 git update-index --ignore-submodules --refresh&& 366 git diff-files --quiet --ignore-submodules|| { 367echo"$(gettext "You must edit all merge conflicts and then 368mark them as resolved using git add")" 369exit1 370} 371 read_basic_state 372 run_specific_rebase 373;; 374skip) 375 output git reset--hard HEAD ||exit $? 376 read_basic_state 377 run_specific_rebase 378;; 379abort) 380 git rerere clear 381 read_basic_state 382case"$head_name"in 383 refs/*) 384 git symbolic-ref -m"rebase: aborting" HEAD $head_name|| 385 die "$(eval_gettext "Could not move back to \$head_name")" 386;; 387esac 388 output git reset--hard$orig_head 389 finish_rebase 390exit 391;; 392edit-todo) 393 run_specific_rebase 394;; 395esac 396 397# Make sure no rebase is in progress 398iftest -n"$in_progress" 399then 400 state_dir_base=${state_dir##*/} 401 cmd_live_rebase="git rebase (--continue | --abort | --skip)" 402 cmd_clear_stale_rebase="rm -fr\"$state_dir\"" 403 die " 404$(eval_gettext 'It seems that there is already a$state_dir_basedirectory, and 405I wonder if you are in the middle of another rebase. If that is the 406case, please try 407$cmd_live_rebase 408If that is not the case, please 409$cmd_clear_stale_rebase 410and run me again. I am stopping in case you still have something 411valuable there.')" 412fi 413 414iftest -n"$rebase_root"&&test -z"$onto" 415then 416test -z"$interactive_rebase"&& interactive_rebase=implied 417fi 418 419iftest -n"$interactive_rebase" 420then 421type=interactive 422 state_dir="$merge_dir" 423eliftest -n"$do_merge" 424then 425type=merge 426 state_dir="$merge_dir" 427else 428type=am 429 state_dir="$apply_dir" 430fi 431 432iftest -z"$rebase_root" 433then 434case"$#"in 4350) 436if! upstream_name=$(git rev-parse --symbolic-full-name \ 437--verify -q @{upstream}2>/dev/null) 438then 439 . git-parse-remote 440 error_on_missing_default_upstream "rebase""rebase" \ 441"against""git rebase <branch>" 442fi 443 444test"$fork_point"= auto && fork_point=t 445;; 446*) upstream_name="$1" 447iftest"$upstream_name"="-" 448then 449 upstream_name="@{-1}" 450fi 451shift 452;; 453esac 454 upstream=$(peel_committish "${upstream_name}")|| 455 die "$(eval_gettext "invalid upstream \$upstream_name")" 456 upstream_arg="$upstream_name" 457else 458iftest -z"$onto" 459then 460 empty_tree=$(git hash-object -t tree /dev/null) 461 onto=$(git commit-tree $empty_tree </dev/null) 462 squash_onto="$onto" 463fi 464unset upstream_name 465unset upstream 466test$#-gt1&& usage 467 upstream_arg=--root 468fi 469 470# Make sure the branch to rebase onto is valid. 471onto_name=${onto-"$upstream_name"} 472case"$onto_name"in 473*...*) 474if left=${onto_name%...*} right=${onto_name#*...}&& 475 onto=$(git merge-base --all ${left:-HEAD} ${right:-HEAD}) 476then 477case"$onto"in 478 ?*"$LF"?*) 479 die "$(eval_gettext "\$onto_name: there are more than one merge bases")" 480;; 481'') 482 die "$(eval_gettext "\$onto_name: there is no merge base")" 483;; 484esac 485else 486 die "$(eval_gettext "\$onto_name: there is no merge base")" 487fi 488;; 489*) 490 onto=$(peel_committish "$onto_name")|| 491 die "$(eval_gettext "Does not point to a valid commit: \$onto_name")" 492;; 493esac 494 495# If the branch to rebase is given, that is the branch we will rebase 496# $branch_name -- branch being rebased, or HEAD (already detached) 497# $orig_head -- commit object name of tip of the branch before rebasing 498# $head_name -- refs/heads/<that-branch> or "detached HEAD" 499switch_to= 500case"$#"in 5011) 502# Is it "rebase other $branchname" or "rebase other $commit"? 503 branch_name="$1" 504 switch_to="$1" 505 506if git show-ref --verify --quiet --"refs/heads/$1"&& 507 orig_head=$(git rev-parse -q --verify "refs/heads/$1") 508then 509 head_name="refs/heads/$1" 510elif orig_head=$(git rev-parse -q --verify "$1") 511then 512 head_name="detached HEAD" 513else 514 die "$(eval_gettext "fatal: no such branch: \$branch_name")" 515fi 516;; 5170) 518# Do not need to switch branches, we are already on it. 519if branch_name=$(git symbolic-ref -q HEAD) 520then 521 head_name=$branch_name 522 branch_name=$(expr "z$branch_name" : 'zrefs/heads/\(.*\)') 523 else 524 head_name="detached HEAD" 525 branch_name=HEAD ;# detached 526 fi 527 orig_head=$(git rev-parse --verify HEAD)|| exit 528 ;; 529*) 530 die "BUG: unexpected number of arguments left to parse" 531 ;; 532esac 533 534if test "$fork_point" = t 535then 536 new_upstream=$(git merge-base --fork-point "$upstream_name" \ 537 "${switch_to:-HEAD}") 538 if test -n "$new_upstream" 539 then 540 upstream=$new_upstream 541 fi 542fi 543 544if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null 545then 546 stash_sha1=$(git stash create "autostash")|| 547 die "$(gettext 'Cannot autostash')" 548 549 mkdir -p "$state_dir" && 550 echo$stash_sha1>"$state_dir/autostash" && 551 stash_abbrev=$(git rev-parse --short $stash_sha1)&& 552 echo "$(eval_gettext 'Created autostash: $stash_abbrev')" && 553 git reset --hard 554fi 555 556require_clean_work_tree "rebase" "$(gettext "Please commit or stash them.")" 557 558# Now we are rebasing commits$upstream..$orig_head(or with --root, 559# everything leading up to$orig_head) on top of$onto 560 561# Check if we are already based on$ontowith linear history, 562# but this should be done only when upstream and onto are the same 563# and if this is not an interactive rebase. 564mb=$(git merge-base "$onto" "$orig_head") 565if test "$type" != interactive && test "$upstream" = "$onto" && 566 test "$mb" = "$onto" && 567 # linear history? 568 ! (git rev-list --parents "$onto".."$orig_head" | sane_grep " .* ") > /dev/null 569then 570 if test -z "$force_rebase" 571 then 572 # Lazily switch to the target branch if needed... 573 test -z "$switch_to" || 574 GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout$switch_to" \ 575 git checkout "$switch_to" -- 576 say "$(eval_gettext "Current branch \$branch_name is up to date.")" 577 finish_rebase 578 exit 0 579 else 580 say "$(eval_gettext "Current branch \$branch_name is up to date, rebase forced.")" 581 fi 582fi 583 584# If a hook exists, give it a chance to interrupt 585run_pre_rebase_hook "$upstream_arg" "$@" 586 587if test -n "$diffstat" 588then 589 if test -n "$verbose" 590 then 591 echo "$(eval_gettext "Changes from \$mb to \$onto:")" 592 fi 593 # We want color (if set), but no pager 594 GIT_PAGER='' git diff --stat --summary "$mb" "$onto" 595fi 596 597test "$type" = interactive && run_specific_rebase 598 599# Detach HEAD and reset the tree 600say "$(gettext "First, rewinding head to replay your work on top of it...")" 601 602GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout$onto_name" \ 603 git checkout -q "$onto^0" || die "could not detach HEAD" 604git update-ref ORIG_HEAD$orig_head 605 606# If the$ontois a proper descendant of the tip of the branch, then 607# we just fast-forwarded. 608if test "$mb" = "$orig_head" 609then 610 say "$(eval_gettext "Fast-forwarded \$branch_name to \$onto_name.")" 611 move_to_original_branch 612 finish_rebase 613 exit 0 614fi 615 616if test -n "$rebase_root" 617then 618 revisions="$onto..$orig_head" 619else 620 revisions="$upstream..$orig_head" 621fi 622 623run_specific_rebase