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