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