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