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