]> git.ipfire.org Git - thirdparty/git.git/blame - git-rebase.sh
Merge branch '2.16' of https://github.com/ChrisADR/git-po
[thirdparty/git.git] / git-rebase.sh
CommitLineData
59e6b23a
JH
1#!/bin/sh
2#
3# Copyright (c) 2005 Junio C Hamano.
4#
5
533b7039 6SUBDIRECTORY_OK=Yes
45e2acf3 7OPTIONS_KEEPDASHDASH=
b6e9e73e 8OPTIONS_STUCKLONG=t
45e2acf3 9OPTIONS_SPEC="\
c2145384 10git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
0cd993a7 11git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]
82cb775c 12git rebase --continue | --abort | --skip | --edit-todo
45e2acf3
MZ
13--
14 Available options are
15v,verbose! display a diffstat of what changed upstream
16q,quiet! be quiet. implies --no-stat
619e3604 17autostash automatically stash/stash pop before and after
ad8261d2 18fork-point use 'merge-base --fork-point' to refine upstream
45e2acf3
MZ
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
c2145384 25x,exec=! add exec lines after each commit of the editable list
90e1818f 26k,keep-empty preserve empty commits during rebase
45e2acf3
MZ
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'
9f79524a 37signoff passed to 'git am'
45e2acf3
MZ
38whitespace=! passed to 'git apply'
39ignore-whitespace! passed to 'git apply'
40C=! passed to 'git apply'
3ee5e540 41S,gpg-sign? GPG-sign commits
45e2acf3 42 Actions:
5960bc9d
MZ
43continue! continue
44abort! abort and check out the original branch
45skip! skip current patch and continue
eb9a7cb4 46edit-todo! edit the todo list during an interactive rebase
9512177b 47quit! abort but keep HEAD where it is
45e2acf3 48"
ae2b0f15 49. git-sh-setup
f9474132 50set_reflog_action rebase
035b5bf6 51require_work_tree_exists
533b7039 52cd_to_toplevel
4282c4fb 53
61dfa1bb
JH
54LF='
55'
6bb4e485
MZ
56ok_to_skip_pre_rebase=
57resolvemsg="
5fdacc17
WD
58$(gettext 'Resolve all conflicts manually, mark them as resolved with
59"git add/rm <conflicted_files>", then run "git rebase --continue".
60You can instead skip this commit: run "git rebase --skip".
61To abort and get back to the state before "git rebase", run "git rebase --abort".')
cc120056 62"
6bb4e485 63unset onto
1e0dacdb 64unset restrict_revision
c2145384 65cmd=
9765b6ab 66strategy=
93ce190c 67strategy_opts=
58634dbf 68do_merge=
69a636ad
MZ
69merge_dir="$GIT_DIR"/rebase-merge
70apply_dir="$GIT_DIR"/rebase-apply
b758789c 71verbose=
9474a029
MZ
72diffstat=
73test "$(git config --bool rebase.stat)" = true && diffstat=t
58794775 74autostash="$(git config --bool rebase.autostash || echo false)"
ad8261d2 75fork_point=auto
67dad687 76git_am_opt=
9eaa858e 77git_format_patch_opt=
190f5323 78rebase_root=
b2f82e05 79force_rebase=
cb6020bb 80allow_rerere_autoupdate=
99de0640
MZ
81# Non-empty if a rebase was in progress when 'git rebase' was invoked
82in_progress=
83# One of {am, merge, interactive}
84type=
85# One of {"$GIT_DIR"/rebase-apply, "$GIT_DIR"/rebase-merge}
86state_dir=
34262322
MZ
87# One of {'', continue, skip, abort}, as parsed from command line
88action=
cf432ca0
MZ
89preserve_merges=
90autosquash=
90e1818f 91keep_empty=
cf432ca0 92test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
66948561
JH
93case "$(git config --bool commit.gpgsign)" in
94true) gpg_sign_opt=-S ;;
95*) gpg_sign_opt= ;;
96esac
58634dbf 97
fa99c1e1 98read_basic_state () {
dc8ca912
RR
99 test -f "$state_dir/head-name" &&
100 test -f "$state_dir/onto" &&
02ac45fa
MZ
101 head_name=$(cat "$state_dir"/head-name) &&
102 onto=$(cat "$state_dir"/onto) &&
84df4560
MZ
103 # We always write to orig-head, but interactive rebase used to write to
104 # head. Fall back to reading from head to cover for the case that the
105 # user upgraded git with an ongoing interactive rebase.
106 if test -f "$state_dir"/orig-head
2959c283 107 then
2959c283 108 orig_head=$(cat "$state_dir"/orig-head)
84df4560
MZ
109 else
110 orig_head=$(cat "$state_dir"/head)
2959c283 111 fi &&
7b37a7c6
MZ
112 GIT_QUIET=$(cat "$state_dir"/quiet) &&
113 test -f "$state_dir"/verbose && verbose=t
80ff4795
MZ
114 test -f "$state_dir"/strategy && strategy="$(cat "$state_dir"/strategy)"
115 test -f "$state_dir"/strategy_opts &&
116 strategy_opts="$(cat "$state_dir"/strategy_opts)"
b3e4847e
MZ
117 test -f "$state_dir"/allow_rerere_autoupdate &&
118 allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)"
3ee5e540
NV
119 test -f "$state_dir"/gpg_sign_opt &&
120 gpg_sign_opt="$(cat "$state_dir"/gpg_sign_opt)"
02ac45fa
MZ
121}
122
84df4560
MZ
123write_basic_state () {
124 echo "$head_name" > "$state_dir"/head-name &&
125 echo "$onto" > "$state_dir"/onto &&
126 echo "$orig_head" > "$state_dir"/orig-head &&
7b37a7c6
MZ
127 echo "$GIT_QUIET" > "$state_dir"/quiet &&
128 test t = "$verbose" && : > "$state_dir"/verbose
80ff4795
MZ
129 test -n "$strategy" && echo "$strategy" > "$state_dir"/strategy
130 test -n "$strategy_opts" && echo "$strategy_opts" > \
131 "$state_dir"/strategy_opts
b3e4847e
MZ
132 test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \
133 "$state_dir"/allow_rerere_autoupdate
3ee5e540 134 test -n "$gpg_sign_opt" && echo "$gpg_sign_opt" > "$state_dir"/gpg_sign_opt
84df4560
MZ
135}
136
4974c2ca
MZ
137output () {
138 case "$verbose" in
139 '')
140 output=$("$@" 2>&1 )
141 status=$?
142 test $status != 0 && printf "%s\n" "$output"
143 return $status
144 ;;
145 *)
146 "$@"
147 ;;
148 esac
149}
150
6fd2f5e6 151move_to_original_branch () {
6fd2f5e6
JS
152 case "$head_name" in
153 refs/*)
154 message="rebase finished: $head_name onto $onto"
155 git update-ref -m "$message" \
156 $head_name $(git rev-parse HEAD) $orig_head &&
53f2ffa8
JK
157 git symbolic-ref \
158 -m "rebase finished: returning to $head_name" \
159 HEAD $head_name ||
24a6df48 160 die "$(eval_gettext "Could not move back to \$head_name")"
6fd2f5e6
JS
161 ;;
162 esac
163}
164
e4244eb3 165apply_autostash () {
58794775
RR
166 if test -f "$state_dir/autostash"
167 then
168 stash_sha1=$(cat "$state_dir/autostash")
eadf1c8f 169 if git stash apply $stash_sha1 >/dev/null 2>&1
58794775 170 then
cdb866b3 171 echo "$(gettext 'Applied autostash.')" >&2
58794775 172 else
20351bb0
RR
173 git stash store -m "autostash" -q $stash_sha1 ||
174 die "$(eval_gettext "Cannot store \$stash_sha1")"
58794775
RR
175 gettext 'Applying autostash resulted in conflicts.
176Your changes are safe in the stash.
ac1998de 177You can run "git stash pop" or "git stash drop" at any time.
cdb866b3 178' >&2
58794775
RR
179 fi
180 fi
e4244eb3
RR
181}
182
183finish_rebase () {
184 apply_autostash &&
8c24f5b0 185 { git gc --auto || true; } &&
58794775
RR
186 rm -rf "$state_dir"
187}
188
8cd65967 189run_specific_rebase () {
f8cca019
AE
190 if [ "$interactive_rebase" = implied ]; then
191 GIT_EDITOR=:
192 export GIT_EDITOR
8a6dae10 193 autosquash=
f8cca019 194 fi
46df82d5 195 . git-rebase--$type
f5f758a5
RR
196 ret=$?
197 if test $ret -eq 0
198 then
58794775 199 finish_rebase
e4244eb3
RR
200 elif test $ret -eq 2 # special exit status for rebase -i
201 then
202 apply_autostash &&
203 rm -rf "$state_dir" &&
204 die "Nothing to do"
f5f758a5
RR
205 fi
206 exit $ret
1b1dce4b
JS
207}
208
d70b4a8f 209run_pre_rebase_hook () {
6bb4e485 210 if test -z "$ok_to_skip_pre_rebase" &&
b849b954 211 test -x "$(git rev-parse --git-path hooks/pre-rebase)"
d70b4a8f 212 then
b849b954 213 "$(git rev-parse --git-path hooks/pre-rebase)" ${1+"$@"} ||
c7108bf9 214 die "$(gettext "The pre-rebase hook refused to rebase.")"
d70b4a8f
NS
215 fi
216}
217
69a636ad 218test -f "$apply_dir"/applying &&
82cb775c 219 die "$(gettext "It looks like 'git am' is in progress. Cannot rebase.")"
9b752a6e 220
99de0640
MZ
221if test -d "$apply_dir"
222then
223 type=am
224 state_dir="$apply_dir"
225elif test -d "$merge_dir"
226then
227 if test -f "$merge_dir"/interactive
228 then
229 type=interactive
230 interactive_rebase=explicit
231 else
232 type=merge
233 fi
234 state_dir="$merge_dir"
235fi
236test -n "$type" && in_progress=t
237
95135b06 238total_argc=$#
822f7c73 239while test $# != 0
e646c9c8
JH
240do
241 case "$1" in
c4427656 242 --no-verify)
6bb4e485 243 ok_to_skip_pre_rebase=yes
c4427656 244 ;;
7baf9c4b 245 --verify)
6bb4e485 246 ok_to_skip_pre_rebase=
7baf9c4b 247 ;;
9512177b 248 --continue|--skip|--abort|--quit|--edit-todo)
45e2acf3 249 test $total_argc -eq 2 || usage
34262322 250 action=${1##--}
031321c6 251 ;;
b6e9e73e
NV
252 --onto=*)
253 onto="${1#--onto=}"
e646c9c8 254 ;;
b6e9e73e
NV
255 --exec=*)
256 cmd="${cmd}exec ${1#--exec=}${LF}"
78ec2400 257 test -z "$interactive_rebase" && interactive_rebase=implied
c2145384 258 ;;
b6e9e73e 259 --interactive)
cf432ca0
MZ
260 interactive_rebase=explicit
261 ;;
b6e9e73e 262 --keep-empty)
90e1818f
NH
263 keep_empty=yes
264 ;;
b6e9e73e 265 --preserve-merges)
cf432ca0
MZ
266 preserve_merges=t
267 test -z "$interactive_rebase" && interactive_rebase=implied
268 ;;
269 --autosquash)
270 autosquash=t
271 ;;
272 --no-autosquash)
273 autosquash=
274 ;;
ad8261d2
JK
275 --fork-point)
276 fork_point=t
277 ;;
278 --no-fork-point)
279 fork_point=
280 ;;
b6e9e73e 281 --merge)
58634dbf
EW
282 do_merge=t
283 ;;
b6e9e73e
NV
284 --strategy-option=*)
285 strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--${1#--strategy-option=}")"
93ce190c 286 do_merge=t
9765b6ab 287 test -z "$strategy" && strategy=recursive
93ce190c 288 ;;
b6e9e73e
NV
289 --strategy=*)
290 strategy="${1#--strategy=}"
58634dbf
EW
291 do_merge=t
292 ;;
b6e9e73e 293 --no-stat)
a9c3821c
TAV
294 diffstat=
295 ;;
296 --stat)
297 diffstat=t
298 ;;
58794775
RR
299 --autostash)
300 autostash=true
301 ;;
619e3604
JK
302 --no-autostash)
303 autostash=false
304 ;;
b6e9e73e 305 --verbose)
b758789c 306 verbose=t
a9c3821c 307 diffstat=t
0e987a12
SB
308 GIT_QUIET=
309 ;;
b6e9e73e 310 --quiet)
0e987a12
SB
311 GIT_QUIET=t
312 git_am_opt="$git_am_opt -q"
313 verbose=
314 diffstat=
b758789c 315 ;;
b6e9e73e
NV
316 --whitespace=*)
317 git_am_opt="$git_am_opt --whitespace=${1#--whitespace=}"
318 case "${1#--whitespace=}" in
45e2acf3 319 fix|strip)
b2f82e05
SR
320 force_rebase=t
321 ;;
322 esac
059f446d 323 ;;
86c91f91
GB
324 --ignore-whitespace)
325 git_am_opt="$git_am_opt $1"
326 ;;
9f79524a 327 --committer-date-is-author-date|--ignore-date|--signoff|--no-signoff)
570ccad3
MB
328 git_am_opt="$git_am_opt $1"
329 force_rebase=t
330 ;;
b6e9e73e
NV
331 -C*)
332 git_am_opt="$git_am_opt $1"
67dad687 333 ;;
190f5323
TR
334 --root)
335 rebase_root=t
336 ;;
b6e9e73e 337 --force-rebase|--no-ff)
b2f82e05
SR
338 force_rebase=t
339 ;;
cb6020bb
JH
340 --rerere-autoupdate|--no-rerere-autoupdate)
341 allow_rerere_autoupdate="$1"
342 ;;
3ee5e540
NV
343 --gpg-sign)
344 gpg_sign_opt=-S
345 ;;
346 --gpg-sign=*)
347 gpg_sign_opt="-S${1#--gpg-sign=}"
348 ;;
45e2acf3
MZ
349 --)
350 shift
e646c9c8
JH
351 break
352 ;;
697bc885
BC
353 *)
354 usage
355 ;;
e646c9c8
JH
356 esac
357 shift
358done
51b2ead0 359test $# -gt 2 && usage
2db8aaec 360
cf432ca0
MZ
361if test -n "$action"
362then
c7108bf9 363 test -z "$in_progress" && die "$(gettext "No rebase in progress?")"
2959c283
MZ
364 # Only interactive rebase uses detailed reflog messages
365 if test "$type" = interactive && test "$GIT_REFLOG_ACTION" = rebase
366 then
367 GIT_REFLOG_ACTION="rebase -i ($action)"
368 export GIT_REFLOG_ACTION
369 fi
cf432ca0 370fi
34262322 371
eb9a7cb4
AW
372if test "$action" = "edit-todo" && test "$type" != "interactive"
373then
374 die "$(gettext "The --edit-todo action can only be used during interactive rebase.")"
375fi
376
34262322
MZ
377case "$action" in
378continue)
2959c283
MZ
379 # Sanity check
380 git rev-parse --verify HEAD >/dev/null ||
c7108bf9 381 die "$(gettext "Cannot read HEAD")"
34262322
MZ
382 git update-index --ignore-submodules --refresh &&
383 git diff-files --quiet --ignore-submodules || {
c7108bf9
JX
384 echo "$(gettext "You must edit all merge conflicts and then
385mark them as resolved using git add")"
34262322
MZ
386 exit 1
387 }
fa99c1e1
MZ
388 read_basic_state
389 run_specific_rebase
34262322
MZ
390 ;;
391skip)
4974c2ca 392 output git reset --hard HEAD || exit $?
fa99c1e1
MZ
393 read_basic_state
394 run_specific_rebase
34262322
MZ
395 ;;
396abort)
397 git rerere clear
fa99c1e1 398 read_basic_state
34262322
MZ
399 case "$head_name" in
400 refs/*)
ea69619c 401 git symbolic-ref -m "rebase: aborting" HEAD $head_name ||
c7108bf9 402 die "$(eval_gettext "Could not move back to \$head_name")"
34262322
MZ
403 ;;
404 esac
4974c2ca 405 output git reset --hard $orig_head
58794775 406 finish_rebase
34262322
MZ
407 exit
408 ;;
9512177b
NTND
409quit)
410 exec rm -rf "$state_dir"
411 ;;
eb9a7cb4
AW
412edit-todo)
413 run_specific_rebase
414 ;;
34262322
MZ
415esac
416
99de0640
MZ
417# Make sure no rebase is in progress
418if test -n "$in_progress"
7f4bd5d8 419then
c7108bf9
JX
420 state_dir_base=${state_dir##*/}
421 cmd_live_rebase="git rebase (--continue | --abort | --skip)"
422 cmd_clear_stale_rebase="rm -fr \"$state_dir\""
423 die "
424$(eval_gettext 'It seems that there is already a $state_dir_base directory, and
e39beac6 425I wonder if you are in the middle of another rebase. If that is the
99de0640 426case, please try
c7108bf9 427 $cmd_live_rebase
99de0640 428If that is not the case, please
c7108bf9 429 $cmd_clear_stale_rebase
9b752a6e 430and run me again. I am stopping in case you still have something
c7108bf9 431valuable there.')"
7f4bd5d8
JH
432fi
433
df5df20c
CW
434if test -n "$rebase_root" && test -z "$onto"
435then
436 test -z "$interactive_rebase" && interactive_rebase=implied
437fi
438
cf432ca0
MZ
439if test -n "$interactive_rebase"
440then
441 type=interactive
442 state_dir="$merge_dir"
443elif test -n "$do_merge"
444then
445 type=merge
446 state_dir="$merge_dir"
447else
448 type=am
449 state_dir="$apply_dir"
450fi
451
9eaa858e
KW
452if test -t 2 && test -z "$GIT_QUIET"
453then
454 git_format_patch_opt="$git_format_patch_opt --progress"
455fi
456
190f5323
TR
457if test -z "$rebase_root"
458then
15a147e6
MZ
459 case "$#" in
460 0)
461 if ! upstream_name=$(git rev-parse --symbolic-full-name \
462 --verify -q @{upstream} 2>/dev/null)
463 then
464 . git-parse-remote
465 error_on_missing_default_upstream "rebase" "rebase" \
c36d8eee 466 "against" "git rebase $(gettext '<branch>')"
15a147e6 467 fi
ad8261d2
JK
468
469 test "$fork_point" = auto && fork_point=t
15a147e6
MZ
470 ;;
471 *) upstream_name="$1"
4f407407
BG
472 if test "$upstream_name" = "-"
473 then
474 upstream_name="@{-1}"
475 fi
15a147e6
MZ
476 shift
477 ;;
478 esac
2e6e276d 479 upstream=$(peel_committish "${upstream_name}") ||
ca7de7b1 480 die "$(eval_gettext "invalid upstream '\$upstream_name'")"
190f5323
TR
481 upstream_arg="$upstream_name"
482else
df5df20c
CW
483 if test -z "$onto"
484 then
728fc79c
EP
485 empty_tree=$(git hash-object -t tree /dev/null)
486 onto=$(git commit-tree $empty_tree </dev/null)
df5df20c
CW
487 squash_onto="$onto"
488 fi
190f5323
TR
489 unset upstream_name
490 unset upstream
f2b6a199 491 test $# -gt 1 && usage
46df82d5 492 upstream_arg=--root
190f5323 493fi
32d99544 494
a1bf91e0 495# Make sure the branch to rebase onto is valid.
6bb4e485 496onto_name=${onto-"$upstream_name"}
9f21e97d
NS
497case "$onto_name" in
498*...*)
499 if left=${onto_name%...*} right=${onto_name#*...} &&
500 onto=$(git merge-base --all ${left:-HEAD} ${right:-HEAD})
501 then
502 case "$onto" in
503 ?*"$LF"?*)
c7108bf9 504 die "$(eval_gettext "\$onto_name: there are more than one merge bases")"
9f21e97d
NS
505 ;;
506 '')
c7108bf9 507 die "$(eval_gettext "\$onto_name: there is no merge base")"
9f21e97d
NS
508 ;;
509 esac
510 else
c7108bf9 511 die "$(eval_gettext "\$onto_name: there is no merge base")"
9f21e97d
NS
512 fi
513 ;;
514*)
2e6e276d 515 onto=$(peel_committish "$onto_name") ||
c7108bf9 516 die "$(eval_gettext "Does not point to a valid commit: \$onto_name")"
9f21e97d
NS
517 ;;
518esac
a1bf91e0 519
0cb06644 520# If the branch to rebase is given, that is the branch we will rebase
3a9156ad 521# $branch_name -- branch/commit being rebased, or HEAD (already detached)
0cb06644
JH
522# $orig_head -- commit object name of tip of the branch before rebasing
523# $head_name -- refs/heads/<that-branch> or "detached HEAD"
524switch_to=
59e6b23a 525case "$#" in
190f5323 5261)
0cb06644 527 # Is it "rebase other $branchname" or "rebase other $commit"?
190f5323
TR
528 branch_name="$1"
529 switch_to="$1"
0cb06644 530
3a9156ad
KS
531 # Is it a local branch?
532 if git show-ref --verify --quiet -- "refs/heads/$branch_name" &&
533 orig_head=$(git rev-parse -q --verify "refs/heads/$branch_name")
0cb06644 534 then
3a9156ad
KS
535 head_name="refs/heads/$branch_name"
536 # If not is it a valid ref (branch or commit)?
537 elif orig_head=$(git rev-parse -q --verify "$branch_name")
0cb06644
JH
538 then
539 head_name="detached HEAD"
3a9156ad 540
0cb06644 541 else
ca7de7b1 542 die "$(eval_gettext "fatal: no such branch/commit '\$branch_name'")"
0cb06644 543 fi
e646c9c8 544 ;;
f2b6a199 5450)
0cb06644 546 # Do not need to switch branches, we are already on it.
728fc79c 547 if branch_name=$(git symbolic-ref -q HEAD)
bcf31618 548 then
0cb06644 549 head_name=$branch_name
728fc79c 550 branch_name=$(expr "z$branch_name" : 'zrefs/heads/\(.*\)')
bcf31618 551 else
0cb06644 552 head_name="detached HEAD"
3a9156ad 553 branch_name=HEAD
bcf31618 554 fi
ea709800 555 orig_head=$(git rev-parse --verify HEAD) || exit
e646c9c8 556 ;;
f2b6a199
MZ
557*)
558 die "BUG: unexpected number of arguments left to parse"
559 ;;
59e6b23a
JH
560esac
561
ad8261d2
JK
562if test "$fork_point" = t
563then
bb3f4583
JK
564 new_upstream=$(git merge-base --fork-point "$upstream_name" \
565 "${switch_to:-HEAD}")
ad8261d2
JK
566 if test -n "$new_upstream"
567 then
1e0dacdb 568 restrict_revision=$new_upstream
ad8261d2
JK
569 fi
570fi
571
58794775
RR
572if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null
573then
574 stash_sha1=$(git stash create "autostash") ||
575 die "$(gettext 'Cannot autostash')"
576
577 mkdir -p "$state_dir" &&
578 echo $stash_sha1 >"$state_dir/autostash" &&
579 stash_abbrev=$(git rev-parse --short $stash_sha1) &&
580 echo "$(eval_gettext 'Created autostash: $stash_abbrev')" &&
581 git reset --hard
582fi
583
c7108bf9 584require_clean_work_tree "rebase" "$(gettext "Please commit or stash them.")"
8f9bfb64 585
cb82a05d
MZ
586# Now we are rebasing commits $upstream..$orig_head (or with --root,
587# everything leading up to $orig_head) on top of $onto
e646c9c8 588
1308c17b 589# Check if we are already based on $onto with linear history,
cc1453e1
MZ
590# but this should be done only when upstream and onto are the same
591# and if this is not an interactive rebase.
cb82a05d 592mb=$(git merge-base "$onto" "$orig_head")
cc1453e1 593if test "$type" != interactive && test "$upstream" = "$onto" &&
1e0dacdb 594 test "$mb" = "$onto" && test -z "$restrict_revision" &&
1308c17b 595 # linear history?
cb82a05d 596 ! (git rev-list --parents "$onto".."$orig_head" | sane_grep " .* ") > /dev/null
7f4bd5d8 597then
b2f82e05
SR
598 if test -z "$force_rebase"
599 then
600 # Lazily switch to the target branch if needed...
4b03df21
RR
601 test -z "$switch_to" ||
602 GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to" \
22946a94 603 git checkout -q "$switch_to" --
08e66700
KS
604 if test "$branch_name" = "HEAD" &&
605 ! git symbolic-ref -q HEAD
606 then
607 say "$(eval_gettext "HEAD is up to date.")"
608 else
609 say "$(eval_gettext "Current branch \$branch_name is up to date.")"
610 fi
96e2b99e 611 finish_rebase
b2f82e05
SR
612 exit 0
613 else
08e66700
KS
614 if test "$branch_name" = "HEAD" &&
615 ! git symbolic-ref -q HEAD
616 then
617 say "$(eval_gettext "HEAD is up to date, rebase forced.")"
618 else
619 say "$(eval_gettext "Current branch \$branch_name is up to date, rebase forced.")"
620 fi
b2f82e05 621 fi
7f4bd5d8
JH
622fi
623
8f9bfb64
MZ
624# If a hook exists, give it a chance to interrupt
625run_pre_rebase_hook "$upstream_arg" "$@"
626
a9c3821c
TAV
627if test -n "$diffstat"
628then
629 if test -n "$verbose"
630 then
c7108bf9 631 echo "$(eval_gettext "Changes from \$mb to \$onto:")"
a9c3821c
TAV
632 fi
633 # We want color (if set), but no pager
634 GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
635fi
636
fa99c1e1 637test "$type" = interactive && run_specific_rebase
f4107d9c
MZ
638
639# Detach HEAD and reset the tree
c7108bf9 640say "$(gettext "First, rewinding head to replay your work on top of it...")"
4b03df21
RR
641
642GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name" \
643 git checkout -q "$onto^0" || die "could not detach HEAD"
cb82a05d 644git update-ref ORIG_HEAD $orig_head
f4107d9c 645
e646c9c8 646# If the $onto is a proper descendant of the tip of the branch, then
a75d7b54 647# we just fast-forwarded.
cb82a05d 648if test "$mb" = "$orig_head"
32d99544 649then
c7108bf9 650 say "$(eval_gettext "Fast-forwarded \$branch_name to \$onto_name.")"
6fd2f5e6 651 move_to_original_branch
af2f0ebc 652 finish_rebase
32d99544
LS
653 exit 0
654fi
655
190f5323
TR
656if test -n "$rebase_root"
657then
658 revisions="$onto..$orig_head"
659else
1e0dacdb 660 revisions="${restrict_revision-$upstream}..$orig_head"
190f5323
TR
661fi
662
fa99c1e1 663run_specific_rebase