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