t/t5528-push-default: generalize test_push_*
[git/gitweb.git] / git-rebase.sh
blobd0c11a910a69603ac19c83a5d29af9f32f780267
1 #!/bin/sh
3 # Copyright (c) 2005 Junio C Hamano.
6 SUBDIRECTORY_OK=Yes
7 OPTIONS_KEEPDASHDASH=
8 OPTIONS_SPEC="\
9 git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
10 git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]
11 git-rebase --continue | --abort | --skip | --edit-todo
13 Available options are
14 v,verbose! display a diffstat of what changed upstream
15 q,quiet! be quiet. implies --no-stat
16 autostash! automatically stash/stash pop before and after
17 onto=! rebase onto given branch instead of upstream
18 p,preserve-merges! try to recreate merges instead of ignoring them
19 s,strategy=! use the given merge strategy
20 no-ff! cherry-pick all commits, even if unchanged
21 m,merge! use merging strategies to rebase
22 i,interactive! let the user edit the list of commits to rebase
23 x,exec=! add exec lines after each commit of the editable list
24 k,keep-empty preserve empty commits during rebase
25 f,force-rebase! force rebase even if branch is up to date
26 X,strategy-option=! pass the argument through to the merge strategy
27 stat! display a diffstat of what changed upstream
28 n,no-stat! do not show diffstat of what changed upstream
29 verify allow pre-rebase hook to run
30 rerere-autoupdate allow rerere to update index with resolved conflicts
31 root! rebase all reachable commits up to the root(s)
32 autosquash move commits that begin with squash!/fixup! under -i
33 committer-date-is-author-date! passed to 'git am'
34 ignore-date! passed to 'git am'
35 whitespace=! passed to 'git apply'
36 ignore-whitespace! passed to 'git apply'
37 C=! passed to 'git apply'
38 Actions:
39 continue! continue
40 abort! abort and check out the original branch
41 skip! skip current patch and continue
42 edit-todo! edit the todo list during an interactive rebase
44 . git-sh-setup
45 . git-sh-i18n
46 set_reflog_action rebase
47 require_work_tree_exists
48 cd_to_toplevel
50 LF='
52 ok_to_skip_pre_rebase=
53 resolvemsg="
54 $(gettext 'When you have resolved this problem, run "git rebase --continue".
55 If you prefer to skip this patch, run "git rebase --skip" instead.
56 To check out the original branch and stop rebasing, run "git rebase --abort".')
58 unset onto
59 cmd=
60 strategy=
61 strategy_opts=
62 do_merge=
63 merge_dir="$GIT_DIR"/rebase-merge
64 apply_dir="$GIT_DIR"/rebase-apply
65 verbose=
66 diffstat=
67 test "$(git config --bool rebase.stat)" = true && diffstat=t
68 autostash="$(git config --bool rebase.autostash || echo false)"
69 git_am_opt=
70 rebase_root=
71 force_rebase=
72 allow_rerere_autoupdate=
73 # Non-empty if a rebase was in progress when 'git rebase' was invoked
74 in_progress=
75 # One of {am, merge, interactive}
76 type=
77 # One of {"$GIT_DIR"/rebase-apply, "$GIT_DIR"/rebase-merge}
78 state_dir=
79 # One of {'', continue, skip, abort}, as parsed from command line
80 action=
81 preserve_merges=
82 autosquash=
83 keep_empty=
84 test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
86 read_basic_state () {
87 head_name=$(cat "$state_dir"/head-name) &&
88 onto=$(cat "$state_dir"/onto) &&
89 # We always write to orig-head, but interactive rebase used to write to
90 # head. Fall back to reading from head to cover for the case that the
91 # user upgraded git with an ongoing interactive rebase.
92 if test -f "$state_dir"/orig-head
93 then
94 orig_head=$(cat "$state_dir"/orig-head)
95 else
96 orig_head=$(cat "$state_dir"/head)
97 fi &&
98 GIT_QUIET=$(cat "$state_dir"/quiet) &&
99 test -f "$state_dir"/verbose && verbose=t
100 test -f "$state_dir"/strategy && strategy="$(cat "$state_dir"/strategy)"
101 test -f "$state_dir"/strategy_opts &&
102 strategy_opts="$(cat "$state_dir"/strategy_opts)"
103 test -f "$state_dir"/allow_rerere_autoupdate &&
104 allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)"
107 write_basic_state () {
108 echo "$head_name" > "$state_dir"/head-name &&
109 echo "$onto" > "$state_dir"/onto &&
110 echo "$orig_head" > "$state_dir"/orig-head &&
111 echo "$GIT_QUIET" > "$state_dir"/quiet &&
112 test t = "$verbose" && : > "$state_dir"/verbose
113 test -n "$strategy" && echo "$strategy" > "$state_dir"/strategy
114 test -n "$strategy_opts" && echo "$strategy_opts" > \
115 "$state_dir"/strategy_opts
116 test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \
117 "$state_dir"/allow_rerere_autoupdate
120 output () {
121 case "$verbose" in
123 output=$("$@" 2>&1 )
124 status=$?
125 test $status != 0 && printf "%s\n" "$output"
126 return $status
129 "$@"
131 esac
134 move_to_original_branch () {
135 case "$head_name" in
136 refs/*)
137 message="rebase finished: $head_name onto $onto"
138 git update-ref -m "$message" \
139 $head_name $(git rev-parse HEAD) $orig_head &&
140 git symbolic-ref \
141 -m "rebase finished: returning to $head_name" \
142 HEAD $head_name ||
143 die "$(gettext "Could not move back to $head_name")"
145 esac
148 finish_rebase () {
149 if test -f "$state_dir/autostash"
150 then
151 stash_sha1=$(cat "$state_dir/autostash")
152 if git stash apply $stash_sha1 2>&1 >/dev/null
153 then
154 echo "$(gettext 'Applied autostash.')"
155 else
156 ref_stash=refs/stash &&
157 >>"$GIT_DIR/logs/$ref_stash" &&
158 git update-ref -m "autostash" $ref_stash $stash_sha1 ||
159 die "$(eval_gettext 'Cannot store $stash_sha1')"
161 gettext 'Applying autostash resulted in conflicts.
162 Your changes are safe in the stash.
163 You can run "git stash pop" or "git stash drop" it at any time.
167 git gc --auto &&
168 rm -rf "$state_dir"
171 run_specific_rebase () {
172 if [ "$interactive_rebase" = implied ]; then
173 GIT_EDITOR=:
174 export GIT_EDITOR
175 autosquash=
177 . git-rebase--$type
178 ret=$?
179 if test $ret -eq 0
180 then
181 finish_rebase
183 exit $ret
186 run_pre_rebase_hook () {
187 if test -z "$ok_to_skip_pre_rebase" &&
188 test -x "$GIT_DIR/hooks/pre-rebase"
189 then
190 "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} ||
191 die "$(gettext "The pre-rebase hook refused to rebase.")"
195 test -f "$apply_dir"/applying &&
196 die "$(gettext "It looks like git-am is in progress. Cannot rebase.")"
198 if test -d "$apply_dir"
199 then
200 type=am
201 state_dir="$apply_dir"
202 elif test -d "$merge_dir"
203 then
204 if test -f "$merge_dir"/interactive
205 then
206 type=interactive
207 interactive_rebase=explicit
208 else
209 type=merge
211 state_dir="$merge_dir"
213 test -n "$type" && in_progress=t
215 total_argc=$#
216 while test $# != 0
218 case "$1" in
219 --no-verify)
220 ok_to_skip_pre_rebase=yes
222 --verify)
223 ok_to_skip_pre_rebase=
225 --continue|--skip|--abort|--edit-todo)
226 test $total_argc -eq 2 || usage
227 action=${1##--}
229 --onto)
230 test 2 -le "$#" || usage
231 onto="$2"
232 shift
235 test 2 -le "$#" || usage
236 cmd="${cmd}exec $2${LF}"
237 shift
240 interactive_rebase=explicit
243 keep_empty=yes
246 preserve_merges=t
247 test -z "$interactive_rebase" && interactive_rebase=implied
249 --autosquash)
250 autosquash=t
252 --no-autosquash)
253 autosquash=
255 -M|-m)
256 do_merge=t
259 shift
260 strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--$1")"
261 do_merge=t
262 test -z "$strategy" && strategy=recursive
265 shift
266 strategy="$1"
267 do_merge=t
270 diffstat=
272 --stat)
273 diffstat=t
275 --autostash)
276 autostash=true
279 verbose=t
280 diffstat=t
281 GIT_QUIET=
284 GIT_QUIET=t
285 git_am_opt="$git_am_opt -q"
286 verbose=
287 diffstat=
289 --whitespace)
290 shift
291 git_am_opt="$git_am_opt --whitespace=$1"
292 case "$1" in
293 fix|strip)
294 force_rebase=t
296 esac
298 --ignore-whitespace)
299 git_am_opt="$git_am_opt $1"
301 --committer-date-is-author-date|--ignore-date)
302 git_am_opt="$git_am_opt $1"
303 force_rebase=t
306 shift
307 git_am_opt="$git_am_opt -C$1"
309 --root)
310 rebase_root=t
312 -f|--no-ff)
313 force_rebase=t
315 --rerere-autoupdate|--no-rerere-autoupdate)
316 allow_rerere_autoupdate="$1"
319 shift
320 break
322 esac
323 shift
324 done
325 test $# -gt 2 && usage
327 if test -n "$cmd" &&
328 test "$interactive_rebase" != explicit
329 then
330 die "$(gettext "The --exec option must be used with the --interactive option")"
333 if test -n "$action"
334 then
335 test -z "$in_progress" && die "$(gettext "No rebase in progress?")"
336 # Only interactive rebase uses detailed reflog messages
337 if test "$type" = interactive && test "$GIT_REFLOG_ACTION" = rebase
338 then
339 GIT_REFLOG_ACTION="rebase -i ($action)"
340 export GIT_REFLOG_ACTION
344 if test "$action" = "edit-todo" && test "$type" != "interactive"
345 then
346 die "$(gettext "The --edit-todo action can only be used during interactive rebase.")"
349 case "$action" in
350 continue)
351 # Sanity check
352 git rev-parse --verify HEAD >/dev/null ||
353 die "$(gettext "Cannot read HEAD")"
354 git update-index --ignore-submodules --refresh &&
355 git diff-files --quiet --ignore-submodules || {
356 echo "$(gettext "You must edit all merge conflicts and then
357 mark them as resolved using git add")"
358 exit 1
360 read_basic_state
361 run_specific_rebase
363 skip)
364 output git reset --hard HEAD || exit $?
365 read_basic_state
366 run_specific_rebase
368 abort)
369 git rerere clear
370 read_basic_state
371 case "$head_name" in
372 refs/*)
373 git symbolic-ref -m "rebase: aborting" HEAD $head_name ||
374 die "$(eval_gettext "Could not move back to \$head_name")"
376 esac
377 output git reset --hard $orig_head
378 finish_rebase
379 exit
381 edit-todo)
382 run_specific_rebase
384 esac
386 # Make sure no rebase is in progress
387 if test -n "$in_progress"
388 then
389 state_dir_base=${state_dir##*/}
390 cmd_live_rebase="git rebase (--continue | --abort | --skip)"
391 cmd_clear_stale_rebase="rm -fr \"$state_dir\""
392 die "
393 $(eval_gettext 'It seems that there is already a $state_dir_base directory, and
394 I wonder if you are in the middle of another rebase. If that is the
395 case, please try
396 $cmd_live_rebase
397 If that is not the case, please
398 $cmd_clear_stale_rebase
399 and run me again. I am stopping in case you still have something
400 valuable there.')"
403 if test -n "$rebase_root" && test -z "$onto"
404 then
405 test -z "$interactive_rebase" && interactive_rebase=implied
408 if test -n "$interactive_rebase"
409 then
410 type=interactive
411 state_dir="$merge_dir"
412 elif test -n "$do_merge"
413 then
414 type=merge
415 state_dir="$merge_dir"
416 else
417 type=am
418 state_dir="$apply_dir"
421 if test -z "$rebase_root"
422 then
423 case "$#" in
425 if ! upstream_name=$(git rev-parse --symbolic-full-name \
426 --verify -q @{upstream} 2>/dev/null)
427 then
428 . git-parse-remote
429 error_on_missing_default_upstream "rebase" "rebase" \
430 "against" "git rebase <branch>"
433 *) upstream_name="$1"
434 shift
436 esac
437 upstream=`git rev-parse --verify "${upstream_name}^0"` ||
438 die "$(eval_gettext "invalid upstream \$upstream_name")"
439 upstream_arg="$upstream_name"
440 else
441 if test -z "$onto"
442 then
443 empty_tree=`git hash-object -t tree /dev/null`
444 onto=`git commit-tree $empty_tree </dev/null`
445 squash_onto="$onto"
447 unset upstream_name
448 unset upstream
449 test $# -gt 1 && usage
450 upstream_arg=--root
453 # Make sure the branch to rebase onto is valid.
454 onto_name=${onto-"$upstream_name"}
455 case "$onto_name" in
456 *...*)
457 if left=${onto_name%...*} right=${onto_name#*...} &&
458 onto=$(git merge-base --all ${left:-HEAD} ${right:-HEAD})
459 then
460 case "$onto" in
461 ?*"$LF"?*)
462 die "$(eval_gettext "\$onto_name: there are more than one merge bases")"
465 die "$(eval_gettext "\$onto_name: there is no merge base")"
467 esac
468 else
469 die "$(eval_gettext "\$onto_name: there is no merge base")"
473 onto=$(git rev-parse --verify "${onto_name}^0") ||
474 die "$(eval_gettext "Does not point to a valid commit: \$onto_name")"
476 esac
478 # If the branch to rebase is given, that is the branch we will rebase
479 # $branch_name -- branch being rebased, or HEAD (already detached)
480 # $orig_head -- commit object name of tip of the branch before rebasing
481 # $head_name -- refs/heads/<that-branch> or "detached HEAD"
482 switch_to=
483 case "$#" in
485 # Is it "rebase other $branchname" or "rebase other $commit"?
486 branch_name="$1"
487 switch_to="$1"
489 if git show-ref --verify --quiet -- "refs/heads/$1" &&
490 orig_head=$(git rev-parse -q --verify "refs/heads/$1")
491 then
492 head_name="refs/heads/$1"
493 elif orig_head=$(git rev-parse -q --verify "$1")
494 then
495 head_name="detached HEAD"
496 else
497 die "$(eval_gettext "fatal: no such branch: \$branch_name")"
501 # Do not need to switch branches, we are already on it.
502 if branch_name=`git symbolic-ref -q HEAD`
503 then
504 head_name=$branch_name
505 branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'`
506 else
507 head_name="detached HEAD"
508 branch_name=HEAD ;# detached
510 orig_head=$(git rev-parse --verify HEAD) || exit
513 die "BUG: unexpected number of arguments left to parse"
515 esac
517 if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null
518 then
519 stash_sha1=$(git stash create "autostash") ||
520 die "$(gettext 'Cannot autostash')"
522 mkdir -p "$state_dir" &&
523 echo $stash_sha1 >"$state_dir/autostash" &&
524 stash_abbrev=$(git rev-parse --short $stash_sha1) &&
525 echo "$(eval_gettext 'Created autostash: $stash_abbrev')" &&
526 git reset --hard
529 require_clean_work_tree "rebase" "$(gettext "Please commit or stash them.")"
531 # Now we are rebasing commits $upstream..$orig_head (or with --root,
532 # everything leading up to $orig_head) on top of $onto
534 # Check if we are already based on $onto with linear history,
535 # but this should be done only when upstream and onto are the same
536 # and if this is not an interactive rebase.
537 mb=$(git merge-base "$onto" "$orig_head")
538 if test "$type" != interactive && test "$upstream" = "$onto" &&
539 test "$mb" = "$onto" &&
540 # linear history?
541 ! (git rev-list --parents "$onto".."$orig_head" | sane_grep " .* ") > /dev/null
542 then
543 if test -z "$force_rebase"
544 then
545 # Lazily switch to the target branch if needed...
546 test -z "$switch_to" || git checkout "$switch_to" --
547 say "$(eval_gettext "Current branch \$branch_name is up to date.")"
548 exit 0
549 else
550 say "$(eval_gettext "Current branch \$branch_name is up to date, rebase forced.")"
554 # If a hook exists, give it a chance to interrupt
555 run_pre_rebase_hook "$upstream_arg" "$@"
557 if test -n "$diffstat"
558 then
559 if test -n "$verbose"
560 then
561 echo "$(eval_gettext "Changes from \$mb to \$onto:")"
563 # We want color (if set), but no pager
564 GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
567 test "$type" = interactive && run_specific_rebase
569 # Detach HEAD and reset the tree
570 say "$(gettext "First, rewinding head to replay your work on top of it...")"
571 git checkout -q "$onto^0" || die "could not detach HEAD"
572 git update-ref ORIG_HEAD $orig_head
574 # If the $onto is a proper descendant of the tip of the branch, then
575 # we just fast-forwarded.
576 if test "$mb" = "$orig_head"
577 then
578 say "$(eval_gettext "Fast-forwarded \$branch_name to \$onto_name.")"
579 move_to_original_branch
580 exit 0
583 if test -n "$rebase_root"
584 then
585 revisions="$onto..$orig_head"
586 else
587 revisions="$upstream..$orig_head"
590 run_specific_rebase