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