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