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