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