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