blob: b2f1c76dc3ede707870564a8ba73af6d1753e95c [file] [log] [blame]
Junio C Hamano59e6b232005-06-25 02:23:43 -07001#!/bin/sh
2#
3# Copyright (c) 2005 Junio C Hamano.
4#
5
Junio C Hamano533b7032007-01-12 12:52:03 -08006SUBDIRECTORY_OK=Yes
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -05007OPTIONS_KEEPDASHDASH=
8OPTIONS_SPEC="\
Lucien Kongc2145382012-06-12 10:05:12 +02009git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
Junio C Hamano0cd993a2012-07-15 21:38:41 -070010git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]
Andrew Wongeb9a7cb2012-09-17 21:28:09 -040011git-rebase --continue | --abort | --skip | --edit-todo
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -050012--
13 Available options are
14v,verbose! display a diffstat of what changed upstream
15q,quiet! be quiet. implies --no-stat
16onto=! rebase onto given branch instead of upstream
17p,preserve-merges! try to recreate merges instead of ignoring them
18s,strategy=! use the given merge strategy
19no-ff! cherry-pick all commits, even if unchanged
20m,merge! use merging strategies to rebase
21i,interactive! let the user edit the list of commits to rebase
Lucien Kongc2145382012-06-12 10:05:12 +020022x,exec=! add exec lines after each commit of the editable list
Neil Horman90e18182012-04-20 10:36:17 -040023k,keep-empty preserve empty commits during rebase
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -050024f,force-rebase! force rebase even if branch is up to date
25X,strategy-option=! pass the argument through to the merge strategy
26stat! display a diffstat of what changed upstream
27n,no-stat! do not show diffstat of what changed upstream
28verify allow pre-rebase hook to run
29rerere-autoupdate allow rerere to update index with resolved conflicts
30root! rebase all reachable commits up to the root(s)
31autosquash move commits that begin with squash!/fixup! under -i
32committer-date-is-author-date! passed to 'git am'
33ignore-date! passed to 'git am'
34whitespace=! passed to 'git apply'
35ignore-whitespace! passed to 'git apply'
36C=! passed to 'git apply'
37 Actions:
Martin von Zweigbergk5960bc92011-07-13 23:47:06 -040038continue! continue
39abort! abort and check out the original branch
40skip! skip current patch and continue
Andrew Wongeb9a7cb2012-09-17 21:28:09 -040041edit-todo! edit the todo list during an interactive rebase
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -050042"
Junio C Hamanoae2b0f12005-11-24 00:12:11 -080043. git-sh-setup
Jiang Xinc7108bf2012-07-25 22:53:08 +080044. git-sh-i18n
Shawn O. Pearcef9474132006-12-28 02:34:48 -050045set_reflog_action rebase
Jeff King035b5bf2011-10-13 11:59:24 -040046require_work_tree_exists
Junio C Hamano533b7032007-01-12 12:52:03 -080047cd_to_toplevel
Junio C Hamano4282c4f2005-08-07 15:51:09 -070048
Junio C Hamano61dfa1b2009-11-20 03:02:44 -080049LF='
50'
Martin von Zweigbergk6bb4e482011-02-06 13:43:37 -050051ok_to_skip_pre_rebase=
52resolvemsg="
Jiang Xinc7108bf2012-07-25 22:53:08 +080053$(gettext 'When you have resolved this problem, run "git rebase --continue".
54If you prefer to skip this patch, run "git rebase --skip" instead.
55To check out the original branch and stop rebasing, run "git rebase --abort".')
Seancc120052006-05-13 23:34:08 -040056"
Martin von Zweigbergk6bb4e482011-02-06 13:43:37 -050057unset onto
Lucien Kongc2145382012-06-12 10:05:12 +020058cmd=
Martin von Zweigbergk9765b6a2011-02-06 13:43:38 -050059strategy=
Mike Lundy93ce1902010-07-29 00:04:29 +020060strategy_opts=
Eric Wong58634db2006-06-21 03:04:41 -070061do_merge=
Martin von Zweigbergk69a636a2011-02-06 13:43:30 -050062merge_dir="$GIT_DIR"/rebase-merge
63apply_dir="$GIT_DIR"/rebase-apply
Robert Shearmanb7587892006-10-03 17:29:31 +010064verbose=
Martin von Zweigbergk9474a022010-11-09 21:59:00 +010065diffstat=
66test "$(git config --bool rebase.stat)" = true && diffstat=t
Michael S. Tsirkin67dad682007-02-08 15:57:08 +020067git_am_opt=
Thomas Rast190f5322009-01-05 18:35:16 +010068rebase_root=
Sverre Rabbelierb2f82e02009-02-13 23:48:01 +010069force_rebase=
Junio C Hamanocb6020b2009-12-04 00:20:48 -080070allow_rerere_autoupdate=
Martin von Zweigbergk99de0642011-02-06 13:43:34 -050071# Non-empty if a rebase was in progress when 'git rebase' was invoked
72in_progress=
73# One of {am, merge, interactive}
74type=
75# One of {"$GIT_DIR"/rebase-apply, "$GIT_DIR"/rebase-merge}
76state_dir=
Martin von Zweigbergk34262322011-02-06 13:43:35 -050077# One of {'', continue, skip, abort}, as parsed from command line
78action=
Martin von Zweigbergkcf432ca2011-02-06 13:43:39 -050079preserve_merges=
80autosquash=
Neil Horman90e18182012-04-20 10:36:17 -040081keep_empty=
Martin von Zweigbergkcf432ca2011-02-06 13:43:39 -050082test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
Eric Wong58634db2006-06-21 03:04:41 -070083
Martin von Zweigbergkfa99c1e2011-02-06 13:43:47 -050084read_basic_state () {
Martin von Zweigbergk02ac45f2011-02-06 13:43:31 -050085 head_name=$(cat "$state_dir"/head-name) &&
86 onto=$(cat "$state_dir"/onto) &&
Martin von Zweigbergk84df4562011-02-06 13:43:53 -050087 # We always write to orig-head, but interactive rebase used to write to
88 # head. Fall back to reading from head to cover for the case that the
89 # user upgraded git with an ongoing interactive rebase.
90 if test -f "$state_dir"/orig-head
Martin von Zweigbergk2959c282011-02-06 13:43:52 -050091 then
Martin von Zweigbergk2959c282011-02-06 13:43:52 -050092 orig_head=$(cat "$state_dir"/orig-head)
Martin von Zweigbergk84df4562011-02-06 13:43:53 -050093 else
94 orig_head=$(cat "$state_dir"/head)
Martin von Zweigbergk2959c282011-02-06 13:43:52 -050095 fi &&
Martin von Zweigbergk7b37a7c2011-02-06 13:43:54 -050096 GIT_QUIET=$(cat "$state_dir"/quiet) &&
97 test -f "$state_dir"/verbose && verbose=t
Martin von Zweigbergk80ff4792011-02-06 13:43:55 -050098 test -f "$state_dir"/strategy && strategy="$(cat "$state_dir"/strategy)"
99 test -f "$state_dir"/strategy_opts &&
100 strategy_opts="$(cat "$state_dir"/strategy_opts)"
Martin von Zweigbergkb3e48472011-02-06 13:43:56 -0500101 test -f "$state_dir"/allow_rerere_autoupdate &&
102 allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)"
Martin von Zweigbergk02ac45f2011-02-06 13:43:31 -0500103}
104
Martin von Zweigbergk84df4562011-02-06 13:43:53 -0500105write_basic_state () {
106 echo "$head_name" > "$state_dir"/head-name &&
107 echo "$onto" > "$state_dir"/onto &&
108 echo "$orig_head" > "$state_dir"/orig-head &&
Martin von Zweigbergk7b37a7c2011-02-06 13:43:54 -0500109 echo "$GIT_QUIET" > "$state_dir"/quiet &&
110 test t = "$verbose" && : > "$state_dir"/verbose
Martin von Zweigbergk80ff4792011-02-06 13:43:55 -0500111 test -n "$strategy" && echo "$strategy" > "$state_dir"/strategy
112 test -n "$strategy_opts" && echo "$strategy_opts" > \
113 "$state_dir"/strategy_opts
Martin von Zweigbergkb3e48472011-02-06 13:43:56 -0500114 test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \
115 "$state_dir"/allow_rerere_autoupdate
Martin von Zweigbergk84df4562011-02-06 13:43:53 -0500116}
117
Martin von Zweigbergk4974c2c2011-02-06 13:43:51 -0500118output () {
119 case "$verbose" in
120 '')
121 output=$("$@" 2>&1 )
122 status=$?
123 test $status != 0 && printf "%s\n" "$output"
124 return $status
125 ;;
126 *)
127 "$@"
128 ;;
129 esac
130}
131
Johannes Schindelin6fd2f5e2007-11-08 18:19:08 +0000132move_to_original_branch () {
Johannes Schindelin6fd2f5e2007-11-08 18:19:08 +0000133 case "$head_name" in
134 refs/*)
135 message="rebase finished: $head_name onto $onto"
136 git update-ref -m "$message" \
137 $head_name $(git rev-parse HEAD) $orig_head &&
Jeff King53f2ffa2011-05-27 16:16:14 -0400138 git symbolic-ref \
139 -m "rebase finished: returning to $head_name" \
140 HEAD $head_name ||
Jiang Xinc7108bf2012-07-25 22:53:08 +0800141 die "$(gettext "Could not move back to $head_name")"
Johannes Schindelin6fd2f5e2007-11-08 18:19:08 +0000142 ;;
143 esac
144}
145
Martin von Zweigbergkfa99c1e2011-02-06 13:43:47 -0500146run_specific_rebase () {
Andreas Ericssonf8cca012008-09-29 22:28:57 +0200147 if [ "$interactive_rebase" = implied ]; then
148 GIT_EDITOR=:
149 export GIT_EDITOR
Vincent van Ravesteijn8a6dae12012-05-24 13:57:26 +0000150 autosquash=
Andreas Ericssonf8cca012008-09-29 22:28:57 +0200151 fi
Martin von Zweigbergk46df82d2011-02-06 13:43:48 -0500152 . git-rebase--$type
Johannes Schindelin1b1dce42007-06-25 01:11:14 +0100153}
154
Nanako Shiraishid70b4a82008-10-06 14:14:24 +0900155run_pre_rebase_hook () {
Martin von Zweigbergk6bb4e482011-02-06 13:43:37 -0500156 if test -z "$ok_to_skip_pre_rebase" &&
Nanako Shiraishic4427652008-10-06 14:14:29 +0900157 test -x "$GIT_DIR/hooks/pre-rebase"
Nanako Shiraishid70b4a82008-10-06 14:14:24 +0900158 then
Stephen Boydbc2bbc42009-06-14 16:08:56 -0700159 "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} ||
Jiang Xinc7108bf2012-07-25 22:53:08 +0800160 die "$(gettext "The pre-rebase hook refused to rebase.")"
Nanako Shiraishid70b4a82008-10-06 14:14:24 +0900161 fi
162}
163
Martin von Zweigbergk69a636a2011-02-06 13:43:30 -0500164test -f "$apply_dir"/applying &&
Jiang Xinc7108bf2012-07-25 22:53:08 +0800165 die "$(gettext "It looks like git-am is in progress. Cannot rebase.")"
Stephan Beyer9b752a62008-08-17 06:25:43 +0200166
Martin von Zweigbergk99de0642011-02-06 13:43:34 -0500167if test -d "$apply_dir"
168then
169 type=am
170 state_dir="$apply_dir"
171elif test -d "$merge_dir"
172then
173 if test -f "$merge_dir"/interactive
174 then
175 type=interactive
176 interactive_rebase=explicit
177 else
178 type=merge
179 fi
180 state_dir="$merge_dir"
181fi
182test -n "$type" && in_progress=t
183
Martin von Zweigbergk95135b02011-02-06 13:43:36 -0500184total_argc=$#
David Kastrup822f7c72007-09-23 22:42:08 +0200185while test $# != 0
Junio C Hamanoe646c9c2006-02-14 14:42:05 -0800186do
187 case "$1" in
Nanako Shiraishic4427652008-10-06 14:14:29 +0900188 --no-verify)
Martin von Zweigbergk6bb4e482011-02-06 13:43:37 -0500189 ok_to_skip_pre_rebase=yes
Nanako Shiraishic4427652008-10-06 14:14:29 +0900190 ;;
Martin von Zweigbergk7baf9c42010-11-22 21:21:01 +0100191 --verify)
Martin von Zweigbergk6bb4e482011-02-06 13:43:37 -0500192 ok_to_skip_pre_rebase=
Martin von Zweigbergk7baf9c42010-11-22 21:21:01 +0100193 ;;
Andrew Wongeb9a7cb2012-09-17 21:28:09 -0400194 --continue|--skip|--abort|--edit-todo)
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500195 test $total_argc -eq 2 || usage
Martin von Zweigbergk34262322011-02-06 13:43:35 -0500196 action=${1##--}
sean031321c2006-04-26 10:49:38 -0400197 ;;
Junio C Hamanoe646c9c2006-02-14 14:42:05 -0800198 --onto)
199 test 2 -le "$#" || usage
Martin von Zweigbergk6bb4e482011-02-06 13:43:37 -0500200 onto="$2"
Junio C Hamanoe646c9c2006-02-14 14:42:05 -0800201 shift
202 ;;
Lucien Kongc2145382012-06-12 10:05:12 +0200203 -x)
204 test 2 -le "$#" || usage
205 cmd="${cmd}exec $2${LF}"
206 shift
207 ;;
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500208 -i)
Martin von Zweigbergkcf432ca2011-02-06 13:43:39 -0500209 interactive_rebase=explicit
210 ;;
Neil Horman90e18182012-04-20 10:36:17 -0400211 -k)
212 keep_empty=yes
213 ;;
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500214 -p)
Martin von Zweigbergkcf432ca2011-02-06 13:43:39 -0500215 preserve_merges=t
216 test -z "$interactive_rebase" && interactive_rebase=implied
217 ;;
218 --autosquash)
219 autosquash=t
220 ;;
221 --no-autosquash)
222 autosquash=
223 ;;
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500224 -M|-m)
Eric Wong58634db2006-06-21 03:04:41 -0700225 do_merge=t
226 ;;
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500227 -X)
228 shift
229 strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--$1")"
Mike Lundy93ce1902010-07-29 00:04:29 +0200230 do_merge=t
Martin von Zweigbergk9765b6a2011-02-06 13:43:38 -0500231 test -z "$strategy" && strategy=recursive
Mike Lundy93ce1902010-07-29 00:04:29 +0200232 ;;
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500233 -s)
234 shift
235 strategy="$1"
Eric Wong58634db2006-06-21 03:04:41 -0700236 do_merge=t
237 ;;
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500238 -n)
Tor Arne Vestbøa9c38212009-03-01 23:11:38 +0100239 diffstat=
240 ;;
241 --stat)
242 diffstat=t
243 ;;
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500244 -v)
Robert Shearmanb7587892006-10-03 17:29:31 +0100245 verbose=t
Tor Arne Vestbøa9c38212009-03-01 23:11:38 +0100246 diffstat=t
Stephen Boyd0e987a12009-06-16 15:33:01 -0700247 GIT_QUIET=
248 ;;
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500249 -q)
Stephen Boyd0e987a12009-06-16 15:33:01 -0700250 GIT_QUIET=t
251 git_am_opt="$git_am_opt -q"
252 verbose=
253 diffstat=
Robert Shearmanb7587892006-10-03 17:29:31 +0100254 ;;
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500255 --whitespace)
256 shift
257 git_am_opt="$git_am_opt --whitespace=$1"
Sverre Rabbelierb2f82e02009-02-13 23:48:01 +0100258 case "$1" in
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500259 fix|strip)
Sverre Rabbelierb2f82e02009-02-13 23:48:01 +0100260 force_rebase=t
261 ;;
262 esac
J. Bruce Fields059f4462007-09-07 10:20:50 -0400263 ;;
Giuseppe Bilotta86c91f92009-08-04 13:16:49 +0200264 --ignore-whitespace)
265 git_am_opt="$git_am_opt $1"
266 ;;
Michele Ballabio570ccad2009-03-18 21:53:49 +0100267 --committer-date-is-author-date|--ignore-date)
268 git_am_opt="$git_am_opt $1"
269 force_rebase=t
270 ;;
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500271 -C)
272 shift
273 git_am_opt="$git_am_opt -C$1"
Michael S. Tsirkin67dad682007-02-08 15:57:08 +0200274 ;;
Thomas Rast190f5322009-01-05 18:35:16 +0100275 --root)
276 rebase_root=t
277 ;;
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500278 -f|--no-ff)
Sverre Rabbelierb2f82e02009-02-13 23:48:01 +0100279 force_rebase=t
280 ;;
Junio C Hamanocb6020b2009-12-04 00:20:48 -0800281 --rerere-autoupdate|--no-rerere-autoupdate)
282 allow_rerere_autoupdate="$1"
283 ;;
Martin von Zweigbergk45e2acf2011-02-28 20:59:26 -0500284 --)
285 shift
Junio C Hamanoe646c9c2006-02-14 14:42:05 -0800286 break
287 ;;
288 esac
289 shift
290done
Jay Soffian51b2ead2009-02-18 08:44:02 -0500291test $# -gt 2 && usage
Junio C Hamano2db8aae2005-12-14 03:11:37 -0800292
Lucien Kongc2145382012-06-12 10:05:12 +0200293if test -n "$cmd" &&
294 test "$interactive_rebase" != explicit
295then
Jiang Xin465d6a02012-07-25 22:53:09 +0800296 die "$(gettext "The --exec option must be used with the --interactive option")"
Lucien Kongc2145382012-06-12 10:05:12 +0200297fi
298
Martin von Zweigbergkcf432ca2011-02-06 13:43:39 -0500299if test -n "$action"
300then
Jiang Xinc7108bf2012-07-25 22:53:08 +0800301 test -z "$in_progress" && die "$(gettext "No rebase in progress?")"
Martin von Zweigbergk2959c282011-02-06 13:43:52 -0500302 # Only interactive rebase uses detailed reflog messages
303 if test "$type" = interactive && test "$GIT_REFLOG_ACTION" = rebase
304 then
305 GIT_REFLOG_ACTION="rebase -i ($action)"
306 export GIT_REFLOG_ACTION
307 fi
Martin von Zweigbergkcf432ca2011-02-06 13:43:39 -0500308fi
Martin von Zweigbergk34262322011-02-06 13:43:35 -0500309
Andrew Wongeb9a7cb2012-09-17 21:28:09 -0400310if test "$action" = "edit-todo" && test "$type" != "interactive"
311then
312 die "$(gettext "The --edit-todo action can only be used during interactive rebase.")"
313fi
314
Martin von Zweigbergk34262322011-02-06 13:43:35 -0500315case "$action" in
316continue)
Martin von Zweigbergk2959c282011-02-06 13:43:52 -0500317 # Sanity check
318 git rev-parse --verify HEAD >/dev/null ||
Jiang Xinc7108bf2012-07-25 22:53:08 +0800319 die "$(gettext "Cannot read HEAD")"
Martin von Zweigbergk34262322011-02-06 13:43:35 -0500320 git update-index --ignore-submodules --refresh &&
321 git diff-files --quiet --ignore-submodules || {
Jiang Xinc7108bf2012-07-25 22:53:08 +0800322 echo "$(gettext "You must edit all merge conflicts and then
323mark them as resolved using git add")"
Martin von Zweigbergk34262322011-02-06 13:43:35 -0500324 exit 1
325 }
Martin von Zweigbergkfa99c1e2011-02-06 13:43:47 -0500326 read_basic_state
327 run_specific_rebase
Martin von Zweigbergk34262322011-02-06 13:43:35 -0500328 ;;
329skip)
Martin von Zweigbergk4974c2c2011-02-06 13:43:51 -0500330 output git reset --hard HEAD || exit $?
Martin von Zweigbergkfa99c1e2011-02-06 13:43:47 -0500331 read_basic_state
332 run_specific_rebase
Martin von Zweigbergk34262322011-02-06 13:43:35 -0500333 ;;
334abort)
335 git rerere clear
Martin von Zweigbergkfa99c1e2011-02-06 13:43:47 -0500336 read_basic_state
Martin von Zweigbergk34262322011-02-06 13:43:35 -0500337 case "$head_name" in
338 refs/*)
Csaba Henkea696192011-05-27 16:13:02 -0400339 git symbolic-ref -m "rebase: aborting" HEAD $head_name ||
Jiang Xinc7108bf2012-07-25 22:53:08 +0800340 die "$(eval_gettext "Could not move back to \$head_name")"
Martin von Zweigbergk34262322011-02-06 13:43:35 -0500341 ;;
342 esac
Martin von Zweigbergk4974c2c2011-02-06 13:43:51 -0500343 output git reset --hard $orig_head
Martin von Zweigbergk34262322011-02-06 13:43:35 -0500344 rm -r "$state_dir"
345 exit
346 ;;
Andrew Wongeb9a7cb2012-09-17 21:28:09 -0400347edit-todo)
348 run_specific_rebase
349 ;;
Martin von Zweigbergk34262322011-02-06 13:43:35 -0500350esac
351
Martin von Zweigbergk99de0642011-02-06 13:43:34 -0500352# Make sure no rebase is in progress
353if test -n "$in_progress"
Jonathan Niederbffd7502010-05-31 17:51:32 -0500354then
Jiang Xinc7108bf2012-07-25 22:53:08 +0800355 state_dir_base=${state_dir##*/}
356 cmd_live_rebase="git rebase (--continue | --abort | --skip)"
357 cmd_clear_stale_rebase="rm -fr \"$state_dir\""
358 die "
359$(eval_gettext 'It seems that there is already a $state_dir_base directory, and
Ralf Thielowe39beac2012-08-01 19:09:09 +0200360I wonder if you are in the middle of another rebase. If that is the
Martin von Zweigbergk99de0642011-02-06 13:43:34 -0500361case, please try
Jiang Xinc7108bf2012-07-25 22:53:08 +0800362 $cmd_live_rebase
Martin von Zweigbergk99de0642011-02-06 13:43:34 -0500363If that is not the case, please
Jiang Xinc7108bf2012-07-25 22:53:08 +0800364 $cmd_clear_stale_rebase
Stephan Beyer9b752a62008-08-17 06:25:43 +0200365and run me again. I am stopping in case you still have something
Jiang Xinc7108bf2012-07-25 22:53:08 +0800366valuable there.')"
Junio C Hamano7f4bd5d2005-11-28 13:00:31 -0800367fi
368
Chris Webbdf5df202012-06-26 22:55:23 +0100369if test -n "$rebase_root" && test -z "$onto"
370then
371 test -z "$interactive_rebase" && interactive_rebase=implied
372fi
373
Martin von Zweigbergkcf432ca2011-02-06 13:43:39 -0500374if test -n "$interactive_rebase"
375then
376 type=interactive
377 state_dir="$merge_dir"
378elif test -n "$do_merge"
379then
380 type=merge
381 state_dir="$merge_dir"
382else
383 type=am
384 state_dir="$apply_dir"
385fi
386
Thomas Rast190f5322009-01-05 18:35:16 +0100387if test -z "$rebase_root"
388then
Martin von Zweigbergk15a147e2011-02-09 20:54:02 -0500389 case "$#" in
390 0)
391 if ! upstream_name=$(git rev-parse --symbolic-full-name \
392 --verify -q @{upstream} 2>/dev/null)
393 then
394 . git-parse-remote
395 error_on_missing_default_upstream "rebase" "rebase" \
Carlos Martín Nieto3c023962012-03-04 05:41:26 +0100396 "against" "git rebase <branch>"
Martin von Zweigbergk15a147e2011-02-09 20:54:02 -0500397 fi
398 ;;
399 *) upstream_name="$1"
400 shift
401 ;;
402 esac
Thomas Rast190f5322009-01-05 18:35:16 +0100403 upstream=`git rev-parse --verify "${upstream_name}^0"` ||
Jiang Xinc7108bf2012-07-25 22:53:08 +0800404 die "$(eval_gettext "invalid upstream \$upstream_name")"
Thomas Rast190f5322009-01-05 18:35:16 +0100405 upstream_arg="$upstream_name"
406else
Chris Webbdf5df202012-06-26 22:55:23 +0100407 if test -z "$onto"
408 then
409 empty_tree=`git hash-object -t tree /dev/null`
410 onto=`git commit-tree $empty_tree </dev/null`
411 squash_onto="$onto"
412 fi
Thomas Rast190f5322009-01-05 18:35:16 +0100413 unset upstream_name
414 unset upstream
Martin von Zweigbergkf2b6a192012-06-26 07:51:55 -0700415 test $# -gt 1 && usage
Martin von Zweigbergk46df82d2011-02-06 13:43:48 -0500416 upstream_arg=--root
Thomas Rast190f5322009-01-05 18:35:16 +0100417fi
Lukas Sandström32d99542005-12-15 00:36:35 +0100418
Junio C Hamanoa1bf91e2007-03-22 02:54:59 -0700419# Make sure the branch to rebase onto is valid.
Martin von Zweigbergk6bb4e482011-02-06 13:43:37 -0500420onto_name=${onto-"$upstream_name"}
Nanako Shiraishi9f21e972010-01-07 20:05:02 +0900421case "$onto_name" in
422*...*)
423 if left=${onto_name%...*} right=${onto_name#*...} &&
424 onto=$(git merge-base --all ${left:-HEAD} ${right:-HEAD})
425 then
426 case "$onto" in
427 ?*"$LF"?*)
Jiang Xinc7108bf2012-07-25 22:53:08 +0800428 die "$(eval_gettext "\$onto_name: there are more than one merge bases")"
Nanako Shiraishi9f21e972010-01-07 20:05:02 +0900429 ;;
430 '')
Jiang Xinc7108bf2012-07-25 22:53:08 +0800431 die "$(eval_gettext "\$onto_name: there is no merge base")"
Nanako Shiraishi9f21e972010-01-07 20:05:02 +0900432 ;;
433 esac
434 else
Jiang Xinc7108bf2012-07-25 22:53:08 +0800435 die "$(eval_gettext "\$onto_name: there is no merge base")"
Nanako Shiraishi9f21e972010-01-07 20:05:02 +0900436 fi
437 ;;
438*)
Martin von Zweigbergk71786f52011-02-06 13:43:42 -0500439 onto=$(git rev-parse --verify "${onto_name}^0") ||
Jiang Xinc7108bf2012-07-25 22:53:08 +0800440 die "$(eval_gettext "Does not point to a valid commit: \$onto_name")"
Nanako Shiraishi9f21e972010-01-07 20:05:02 +0900441 ;;
442esac
Junio C Hamanoa1bf91e2007-03-22 02:54:59 -0700443
Junio C Hamano0cb06642008-03-15 13:17:42 -0700444# If the branch to rebase is given, that is the branch we will rebase
445# $branch_name -- branch being rebased, or HEAD (already detached)
446# $orig_head -- commit object name of tip of the branch before rebasing
447# $head_name -- refs/heads/<that-branch> or "detached HEAD"
448switch_to=
Junio C Hamano7f59dbb2005-11-14 00:41:53 -0800449case "$#" in
Thomas Rast190f5322009-01-05 18:35:16 +01004501)
Junio C Hamano0cb06642008-03-15 13:17:42 -0700451 # Is it "rebase other $branchname" or "rebase other $commit"?
Thomas Rast190f5322009-01-05 18:35:16 +0100452 branch_name="$1"
453 switch_to="$1"
Junio C Hamano0cb06642008-03-15 13:17:42 -0700454
Thomas Rast190f5322009-01-05 18:35:16 +0100455 if git show-ref --verify --quiet -- "refs/heads/$1" &&
Martin von Zweigbergkcb82a052011-02-06 13:43:46 -0500456 orig_head=$(git rev-parse -q --verify "refs/heads/$1")
Junio C Hamanobcf31612007-01-20 19:11:29 -0800457 then
Thomas Rast190f5322009-01-05 18:35:16 +0100458 head_name="refs/heads/$1"
Martin von Zweigbergkcb82a052011-02-06 13:43:46 -0500459 elif orig_head=$(git rev-parse -q --verify "$1")
Junio C Hamano0cb06642008-03-15 13:17:42 -0700460 then
461 head_name="detached HEAD"
Junio C Hamanobcf31612007-01-20 19:11:29 -0800462 else
Jiang Xinc7108bf2012-07-25 22:53:08 +0800463 die "$(eval_gettext "fatal: no such branch: \$branch_name")"
Junio C Hamanobcf31612007-01-20 19:11:29 -0800464 fi
Junio C Hamanoe646c9c2006-02-14 14:42:05 -0800465 ;;
Martin von Zweigbergkf2b6a192012-06-26 07:51:55 -07004660)
Junio C Hamano0cb06642008-03-15 13:17:42 -0700467 # Do not need to switch branches, we are already on it.
468 if branch_name=`git symbolic-ref -q HEAD`
469 then
470 head_name=$branch_name
471 branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'`
472 else
473 head_name="detached HEAD"
474 branch_name=HEAD ;# detached
475 fi
Martin von Zweigbergkcb82a052011-02-06 13:43:46 -0500476 orig_head=$(git rev-parse --verify "${branch_name}^0") || exit
Junio C Hamano0cb06642008-03-15 13:17:42 -0700477 ;;
Martin von Zweigbergkf2b6a192012-06-26 07:51:55 -0700478*)
479 die "BUG: unexpected number of arguments left to parse"
480 ;;
Junio C Hamano7f59dbb2005-11-14 00:41:53 -0800481esac
Junio C Hamano99a92f92005-08-17 15:19:57 -0700482
Jiang Xinc7108bf2012-07-25 22:53:08 +0800483require_clean_work_tree "rebase" "$(gettext "Please commit or stash them.")"
Martin von Zweigbergk8f9bfb62011-02-06 13:43:41 -0500484
Martin von Zweigbergkcb82a052011-02-06 13:43:46 -0500485# Now we are rebasing commits $upstream..$orig_head (or with --root,
486# everything leading up to $orig_head) on top of $onto
Junio C Hamanoe646c9c2006-02-14 14:42:05 -0800487
Johannes Sixt1308c172007-07-04 22:09:10 +0200488# Check if we are already based on $onto with linear history,
Martin von Zweigbergkcc1453e2011-02-06 13:43:44 -0500489# but this should be done only when upstream and onto are the same
490# and if this is not an interactive rebase.
Martin von Zweigbergkcb82a052011-02-06 13:43:46 -0500491mb=$(git merge-base "$onto" "$orig_head")
Martin von Zweigbergkcc1453e2011-02-06 13:43:44 -0500492if test "$type" != interactive && test "$upstream" = "$onto" &&
493 test "$mb" = "$onto" &&
Johannes Sixt1308c172007-07-04 22:09:10 +0200494 # linear history?
Martin von Zweigbergkcb82a052011-02-06 13:43:46 -0500495 ! (git rev-list --parents "$onto".."$orig_head" | sane_grep " .* ") > /dev/null
Junio C Hamano7f4bd5d2005-11-28 13:00:31 -0800496then
Sverre Rabbelierb2f82e02009-02-13 23:48:01 +0100497 if test -z "$force_rebase"
498 then
499 # Lazily switch to the target branch if needed...
Jeff King3b21a432011-01-26 19:26:59 -0500500 test -z "$switch_to" || git checkout "$switch_to" --
Jiang Xinc7108bf2012-07-25 22:53:08 +0800501 say "$(eval_gettext "Current branch \$branch_name is up to date.")"
Sverre Rabbelierb2f82e02009-02-13 23:48:01 +0100502 exit 0
503 else
Jiang Xinc7108bf2012-07-25 22:53:08 +0800504 say "$(eval_gettext "Current branch \$branch_name is up to date, rebase forced.")"
Sverre Rabbelierb2f82e02009-02-13 23:48:01 +0100505 fi
Junio C Hamano7f4bd5d2005-11-28 13:00:31 -0800506fi
507
Martin von Zweigbergk8f9bfb62011-02-06 13:43:41 -0500508# If a hook exists, give it a chance to interrupt
509run_pre_rebase_hook "$upstream_arg" "$@"
510
Tor Arne Vestbøa9c38212009-03-01 23:11:38 +0100511if test -n "$diffstat"
512then
513 if test -n "$verbose"
514 then
Jiang Xinc7108bf2012-07-25 22:53:08 +0800515 echo "$(eval_gettext "Changes from \$mb to \$onto:")"
Tor Arne Vestbøa9c38212009-03-01 23:11:38 +0100516 fi
517 # We want color (if set), but no pager
518 GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
519fi
520
Martin von Zweigbergkfa99c1e2011-02-06 13:43:47 -0500521test "$type" = interactive && run_specific_rebase
Martin von Zweigbergkf4107d92011-02-06 13:43:45 -0500522
523# Detach HEAD and reset the tree
Jiang Xinc7108bf2012-07-25 22:53:08 +0800524say "$(gettext "First, rewinding head to replay your work on top of it...")"
Martin von Zweigbergkf4107d92011-02-06 13:43:45 -0500525git checkout -q "$onto^0" || die "could not detach HEAD"
Martin von Zweigbergkcb82a052011-02-06 13:43:46 -0500526git update-ref ORIG_HEAD $orig_head
Martin von Zweigbergkf4107d92011-02-06 13:43:45 -0500527
Junio C Hamanoe646c9c2006-02-14 14:42:05 -0800528# If the $onto is a proper descendant of the tip of the branch, then
Felipe Contrerasa75d7b52009-10-24 11:31:32 +0300529# we just fast-forwarded.
Martin von Zweigbergkcb82a052011-02-06 13:43:46 -0500530if test "$mb" = "$orig_head"
Lukas Sandström32d99542005-12-15 00:36:35 +0100531then
Jiang Xinc7108bf2012-07-25 22:53:08 +0800532 say "$(eval_gettext "Fast-forwarded \$branch_name to \$onto_name.")"
Johannes Schindelin6fd2f5e2007-11-08 18:19:08 +0000533 move_to_original_branch
Lukas Sandström32d99542005-12-15 00:36:35 +0100534 exit 0
535fi
536
Thomas Rast190f5322009-01-05 18:35:16 +0100537if test -n "$rebase_root"
538then
539 revisions="$onto..$orig_head"
540else
541 revisions="$upstream..$orig_head"
542fi
543
Martin von Zweigbergkfa99c1e2011-02-06 13:43:47 -0500544run_specific_rebase