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 git stash store -m"autostash"-q$stash_sha1|| 157 die "$(eval_gettext "Cannot store \$stash_sha1")" 158gettext'Applying autostash resulted in conflicts. 159Your changes are safe in the stash. 160You can run "git stash pop" or "git stash drop" it at any time. 161' 162fi 163fi 164 git gc --auto&& 165rm-rf"$state_dir" 166} 167 168run_specific_rebase () { 169if["$interactive_rebase"= implied ];then 170 GIT_EDITOR=: 171export GIT_EDITOR 172 autosquash= 173fi 174 . git-rebase--$type 175 ret=$? 176iftest$ret-eq0 177then 178 finish_rebase 179fi 180exit$ret 181} 182 183run_pre_rebase_hook () { 184iftest -z"$ok_to_skip_pre_rebase"&& 185test -x"$GIT_DIR/hooks/pre-rebase" 186then 187"$GIT_DIR/hooks/pre-rebase"${1+"$@"}|| 188 die "$(gettext "The pre-rebase hook refused to rebase.")" 189fi 190} 191 192test -f"$apply_dir"/applying && 193 die "$(gettext "It looks like git-am is in progress. Cannot rebase.")" 194 195iftest -d"$apply_dir" 196then 197type=am 198 state_dir="$apply_dir" 199eliftest -d"$merge_dir" 200then 201iftest -f"$merge_dir"/interactive 202then 203type=interactive 204 interactive_rebase=explicit 205else 206type=merge 207fi 208 state_dir="$merge_dir" 209fi 210test -n"$type"&& in_progress=t 211 212total_argc=$# 213whiletest$#!=0 214do 215case"$1"in 216--no-verify) 217 ok_to_skip_pre_rebase=yes 218;; 219--verify) 220 ok_to_skip_pre_rebase= 221;; 222--continue|--skip|--abort|--edit-todo) 223test$total_argc-eq2|| usage 224 action=${1##--} 225;; 226--onto) 227test2-le"$#"|| usage 228 onto="$2" 229shift 230;; 231-x) 232test2-le"$#"|| usage 233 cmd="${cmd}exec$2${LF}" 234shift 235;; 236-i) 237 interactive_rebase=explicit 238;; 239-k) 240 keep_empty=yes 241;; 242-p) 243 preserve_merges=t 244test -z"$interactive_rebase"&& interactive_rebase=implied 245;; 246--autosquash) 247 autosquash=t 248;; 249--no-autosquash) 250 autosquash= 251;; 252-M|-m) 253 do_merge=t 254;; 255-X) 256shift 257 strategy_opts="$strategy_opts$(git rev-parse --sq-quote "--$1")" 258 do_merge=t 259test -z"$strategy"&& strategy=recursive 260;; 261-s) 262shift 263 strategy="$1" 264 do_merge=t 265;; 266-n) 267 diffstat= 268;; 269--stat) 270 diffstat=t 271;; 272--autostash) 273 autostash=true 274;; 275-v) 276 verbose=t 277 diffstat=t 278 GIT_QUIET= 279;; 280-q) 281 GIT_QUIET=t 282 git_am_opt="$git_am_opt-q" 283 verbose= 284 diffstat= 285;; 286--whitespace) 287shift 288 git_am_opt="$git_am_opt--whitespace=$1" 289case"$1"in 290 fix|strip) 291 force_rebase=t 292;; 293esac 294;; 295--ignore-whitespace) 296 git_am_opt="$git_am_opt$1" 297;; 298--committer-date-is-author-date|--ignore-date) 299 git_am_opt="$git_am_opt$1" 300 force_rebase=t 301;; 302-C) 303shift 304 git_am_opt="$git_am_opt-C$1" 305;; 306--root) 307 rebase_root=t 308;; 309-f|--no-ff) 310 force_rebase=t 311;; 312--rerere-autoupdate|--no-rerere-autoupdate) 313 allow_rerere_autoupdate="$1" 314;; 315--) 316shift 317break 318;; 319esac 320shift 321done 322test$#-gt2&& usage 323 324iftest -n"$cmd"&& 325test"$interactive_rebase"!= explicit 326then 327 die "$(gettext "The --exec option must be used with the --interactive option")" 328fi 329 330iftest -n"$action" 331then 332test -z"$in_progress"&& die "$(gettext "No rebase in progress?")" 333# Only interactive rebase uses detailed reflog messages 334iftest"$type"= interactive &&test"$GIT_REFLOG_ACTION"= rebase 335then 336 GIT_REFLOG_ACTION="rebase -i ($action)" 337export GIT_REFLOG_ACTION 338fi 339fi 340 341iftest"$action"="edit-todo"&&test"$type"!="interactive" 342then 343 die "$(gettext "The --edit-todo action can only be used during interactive rebase.")" 344fi 345 346case"$action"in 347continue) 348# Sanity check 349 git rev-parse --verify HEAD >/dev/null || 350 die "$(gettext "Cannot read HEAD")" 351 git update-index --ignore-submodules --refresh&& 352 git diff-files --quiet --ignore-submodules|| { 353echo"$(gettext "You must edit all merge conflicts and then 354mark them as resolved using git add")" 355exit1 356} 357 read_basic_state 358 run_specific_rebase 359;; 360skip) 361 output git reset--hard HEAD ||exit $? 362 read_basic_state 363 run_specific_rebase 364;; 365abort) 366 git rerere clear 367 read_basic_state 368case"$head_name"in 369 refs/*) 370 git symbolic-ref -m"rebase: aborting" HEAD $head_name|| 371 die "$(eval_gettext "Could not move back to \$head_name")" 372;; 373esac 374 output git reset--hard$orig_head 375 finish_rebase 376exit 377;; 378edit-todo) 379 run_specific_rebase 380;; 381esac 382 383# Make sure no rebase is in progress 384iftest -n"$in_progress" 385then 386 state_dir_base=${state_dir##*/} 387 cmd_live_rebase="git rebase (--continue | --abort | --skip)" 388 cmd_clear_stale_rebase="rm -fr\"$state_dir\"" 389 die " 390$(eval_gettext 'It seems that there is already a$state_dir_basedirectory, and 391I wonder if you are in the middle of another rebase. If that is the 392case, please try 393$cmd_live_rebase 394If that is not the case, please 395$cmd_clear_stale_rebase 396and run me again. I am stopping in case you still have something 397valuable there.')" 398fi 399 400iftest -n"$rebase_root"&&test -z"$onto" 401then 402test -z"$interactive_rebase"&& interactive_rebase=implied 403fi 404 405iftest -n"$interactive_rebase" 406then 407type=interactive 408 state_dir="$merge_dir" 409eliftest -n"$do_merge" 410then 411type=merge 412 state_dir="$merge_dir" 413else 414type=am 415 state_dir="$apply_dir" 416fi 417 418iftest -z"$rebase_root" 419then 420case"$#"in 4210) 422if! upstream_name=$(git rev-parse --symbolic-full-name \ 423--verify -q @{upstream}2>/dev/null) 424then 425 . git-parse-remote 426 error_on_missing_default_upstream "rebase""rebase" \ 427"against""git rebase <branch>" 428fi 429;; 430*) upstream_name="$1" 431shift 432;; 433esac 434 upstream=`git rev-parse --verify "${upstream_name}^0"`|| 435 die "$(eval_gettext "invalid upstream \$upstream_name")" 436 upstream_arg="$upstream_name" 437else 438iftest -z"$onto" 439then 440 empty_tree=`git hash-object -t tree /dev/null` 441 onto=`git commit-tree$empty_tree</dev/null` 442 squash_onto="$onto" 443fi 444unset upstream_name 445unset upstream 446test$#-gt1&& usage 447 upstream_arg=--root 448fi 449 450# Make sure the branch to rebase onto is valid. 451onto_name=${onto-"$upstream_name"} 452case"$onto_name"in 453*...*) 454if left=${onto_name%...*} right=${onto_name#*...}&& 455 onto=$(git merge-base --all ${left:-HEAD} ${right:-HEAD}) 456then 457case"$onto"in 458 ?*"$LF"?*) 459 die "$(eval_gettext "\$onto_name: there are more than one merge bases")" 460;; 461'') 462 die "$(eval_gettext "\$onto_name: there is no merge base")" 463;; 464esac 465else 466 die "$(eval_gettext "\$onto_name: there is no merge base")" 467fi 468;; 469*) 470 onto=$(git rev-parse --verify "${onto_name}^0")|| 471 die "$(eval_gettext "Does not point to a valid commit: \$onto_name")" 472;; 473esac 474 475# If the branch to rebase is given, that is the branch we will rebase 476# $branch_name -- branch being rebased, or HEAD (already detached) 477# $orig_head -- commit object name of tip of the branch before rebasing 478# $head_name -- refs/heads/<that-branch> or "detached HEAD" 479switch_to= 480case"$#"in 4811) 482# Is it "rebase other $branchname" or "rebase other $commit"? 483 branch_name="$1" 484 switch_to="$1" 485 486if git show-ref --verify --quiet --"refs/heads/$1"&& 487 orig_head=$(git rev-parse -q --verify "refs/heads/$1") 488then 489 head_name="refs/heads/$1" 490elif orig_head=$(git rev-parse -q --verify "$1") 491then 492 head_name="detached HEAD" 493else 494 die "$(eval_gettext "fatal: no such branch: \$branch_name")" 495fi 496;; 4970) 498# Do not need to switch branches, we are already on it. 499if branch_name=`git symbolic-ref -q HEAD` 500then 501 head_name=$branch_name 502 branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'` 503else 504 head_name="detached HEAD" 505 branch_name=HEAD ;# detached 506fi 507 orig_head=$(git rev-parse --verify HEAD)||exit 508;; 509*) 510 die "BUG: unexpected number of arguments left to parse" 511;; 512esac 513 514iftest"$autostash"= true && ! (require_clean_work_tree)2>/dev/null 515then 516 stash_sha1=$(git stash create "autostash")|| 517 die "$(gettext 'Cannot autostash')" 518 519mkdir-p"$state_dir"&& 520echo$stash_sha1>"$state_dir/autostash"&& 521 stash_abbrev=$(git rev-parse --short $stash_sha1)&& 522echo"$(eval_gettext 'Created autostash: $stash_abbrev')"&& 523 git reset--hard 524fi 525 526require_clean_work_tree "rebase""$(gettext "Please commit or stash them.")" 527 528# Now we are rebasing commits $upstream..$orig_head (or with --root, 529# everything leading up to $orig_head) on top of $onto 530 531# Check if we are already based on $onto with linear history, 532# but this should be done only when upstream and onto are the same 533# and if this is not an interactive rebase. 534mb=$(git merge-base "$onto" "$orig_head") 535iftest"$type"!= interactive &&test"$upstream"="$onto"&& 536test"$mb"="$onto"&& 537# linear history? 538! (git rev-list --parents"$onto".."$orig_head"| sane_grep " .* ") > /dev/null 539then 540iftest -z"$force_rebase" 541then 542# Lazily switch to the target branch if needed... 543test -z"$switch_to"|| git checkout "$switch_to"-- 544 say "$(eval_gettext "Current branch \$branch_name is up to date.")" 545exit0 546else 547 say "$(eval_gettext "Current branch \$branch_name is up to date, rebase forced.")" 548fi 549fi 550 551# If a hook exists, give it a chance to interrupt 552run_pre_rebase_hook "$upstream_arg""$@" 553 554iftest -n"$diffstat" 555then 556iftest -n"$verbose" 557then 558echo"$(eval_gettext "Changes from \$mb to \$onto:")" 559fi 560# We want color (if set), but no pager 561 GIT_PAGER='' git diff--stat --summary"$mb""$onto" 562fi 563 564test"$type"= interactive && run_specific_rebase 565 566# Detach HEAD and reset the tree 567say "$(gettext "First, rewinding head to replay your work on top of it...")" 568git checkout -q"$onto^0"|| die "could not detach HEAD" 569git update-ref ORIG_HEAD $orig_head 570 571# If the $onto is a proper descendant of the tip of the branch, then 572# we just fast-forwarded. 573iftest"$mb"="$orig_head" 574then 575 say "$(eval_gettext "Fast-forwarded \$branch_name to \$onto_name.")" 576 move_to_original_branch 577exit0 578fi 579 580iftest -n"$rebase_root" 581then 582 revisions="$onto..$orig_head" 583else 584 revisions="$upstream..$orig_head" 585fi 586 587run_specific_rebase