]> git.ipfire.org Git - thirdparty/git.git/blame - git-rebase.sh
Merge branch 'maint'
[thirdparty/git.git] / git-rebase.sh
CommitLineData
59e6b23a
JH
1#!/bin/sh
2#
3# Copyright (c) 2005 Junio C Hamano.
4#
5
b758789c 6USAGE='[-v] [--onto <newbase>] <upstream> [<branch>]'
031321c6
SE
7LONG_USAGE='git-rebase replaces <branch> with a new branch of the
8same name. When the --onto option is provided the new branch starts
9out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
10It then attempts to create a new commit for each commit from the original
11<branch> that does not exist in the <upstream> branch.
69a60af5 12
031321c6
SE
13It is possible that a merge failure will prevent this process from being
14completely automatic. You will have to resolve any such merge failure
cc120056
SE
15and run git rebase --continue. Another option is to bypass the commit
16that caused the merge failure with git rebase --skip. To restore the
17original <branch> and remove the .dotest working files, use the command
18git rebase --abort instead.
69a60af5 19
031321c6
SE
20Note that if <branch> is not specified on the command line, the
21currently checked out branch is used. You must be in the top
22directory of your project to start (or continue) a rebase.
e646c9c8 23
031321c6 24Example: git-rebase master~1 topic
e646c9c8 25
031321c6
SE
26 A---B---C topic A'\''--B'\''--C'\'' topic
27 / --> /
28 D---E---F---G master D---E---F---G master
e646c9c8 29'
ae2b0f15 30. git-sh-setup
4282c4fb 31
cc120056
SE
32RESOLVEMSG="
33When you have resolved this problem run \"git rebase --continue\".
34If you would prefer to skip this patch, instead run \"git rebase --skip\".
35To restore the original branch and stop rebasing run \"git rebase --abort\".
36"
e646c9c8 37unset newbase
a06f678e 38strategy=recursive
58634dbf
EW
39do_merge=
40dotest=$GIT_DIR/.dotest-merge
41prec=4
b758789c 42verbose=
58634dbf
EW
43
44continue_merge () {
45 test -n "$prev_head" || die "prev_head must be defined"
46 test -d "$dotest" || die "$dotest directory does not exist"
47
48 unmerged=$(git-ls-files -u)
49 if test -n "$unmerged"
50 then
51 echo "You still have unmerged paths in your index"
52 echo "did you forget update-index?"
66eb64cb 53 die "$RESOLVEMSG"
58634dbf
EW
54 fi
55
56 if test -n "`git-diff-index HEAD`"
57 then
f0ef0596
EW
58 if ! git-commit -C "`cat $dotest/current`"
59 then
60 echo "Commit failed, please do not call \"git commit\""
61 echo "directly, but instead do one of the following: "
62 die "$RESOLVEMSG"
63 fi
9e4bc7dd 64 printf "Committed: %0${prec}d" $msgnum
58634dbf 65 else
9e4bc7dd 66 printf "Already applied: %0${prec}d" $msgnum
58634dbf 67 fi
9e4bc7dd
EW
68 echo ' '`git-rev-list --pretty=oneline -1 HEAD | \
69 sed 's/^[a-f0-9]\+ //'`
58634dbf
EW
70
71 prev_head=`git-rev-parse HEAD^0`
58634dbf 72 # save the resulting commit so we can read-tree on it later
58634dbf
EW
73 echo "$prev_head" > "$dotest/prev_head"
74
75 # onto the next patch:
76 msgnum=$(($msgnum + 1))
5887ac82 77 echo "$msgnum" >"$dotest/msgnum"
58634dbf
EW
78}
79
80call_merge () {
5887ac82 81 cmt="$(cat $dotest/cmt.$1)"
58634dbf
EW
82 echo "$cmt" > "$dotest/current"
83 git-merge-$strategy "$cmt^" -- HEAD "$cmt"
84 rv=$?
85 case "$rv" in
86 0)
9e4bc7dd 87 return
58634dbf
EW
88 ;;
89 1)
90 test -d "$GIT_DIR/rr-cache" && git-rerere
66eb64cb 91 die "$RESOLVEMSG"
58634dbf
EW
92 ;;
93 2)
94 echo "Strategy: $rv $strategy failed, try another" 1>&2
66eb64cb 95 die "$RESOLVEMSG"
58634dbf
EW
96 ;;
97 *)
98 die "Unknown exit code ($rv) from command:" \
99 "git-merge-$strategy $cmt^ -- HEAD $cmt"
100 ;;
101 esac
102}
103
104finish_rb_merge () {
58634dbf
EW
105 rm -r "$dotest"
106 echo "All done."
107}
108
e646c9c8
JH
109while case "$#" in 0) break ;; esac
110do
111 case "$1" in
031321c6
SE
112 --continue)
113 diff=$(git-diff-files)
114 case "$diff" in
115 ?*) echo "You must edit all merge conflicts and then"
116 echo "mark them as resolved using git update-index"
117 exit 1
118 ;;
119 esac
58634dbf
EW
120 if test -d "$dotest"
121 then
122 prev_head="`cat $dotest/prev_head`"
123 end="`cat $dotest/end`"
124 msgnum="`cat $dotest/msgnum`"
125 onto="`cat $dotest/onto`"
126 continue_merge
127 while test "$msgnum" -le "$end"
128 do
129 call_merge "$msgnum"
130 continue_merge
131 done
132 finish_rb_merge
133 exit
134 fi
8ef1c7c7
SP
135 git am --resolved --3way --resolvemsg="$RESOLVEMSG" \
136 --reflog-action=rebase
cc120056
SE
137 exit
138 ;;
139 --skip)
58634dbf
EW
140 if test -d "$dotest"
141 then
d5e673b6
EW
142 prev_head="`cat $dotest/prev_head`"
143 end="`cat $dotest/end`"
144 msgnum="`cat $dotest/msgnum`"
145 msgnum=$(($msgnum + 1))
146 onto="`cat $dotest/onto`"
147 while test "$msgnum" -le "$end"
148 do
149 call_merge "$msgnum"
150 continue_merge
151 done
152 finish_rb_merge
153 exit
58634dbf 154 fi
8ef1c7c7
SP
155 git am -3 --skip --resolvemsg="$RESOLVEMSG" \
156 --reflog-action=rebase
031321c6
SE
157 exit
158 ;;
159 --abort)
58634dbf
EW
160 if test -d "$dotest"
161 then
162 rm -r "$dotest"
163 elif test -d .dotest
164 then
165 rm -r .dotest
166 else
167 die "No rebase in progress?"
168 fi
031321c6 169 git reset --hard ORIG_HEAD
031321c6
SE
170 exit
171 ;;
e646c9c8
JH
172 --onto)
173 test 2 -le "$#" || usage
174 newbase="$2"
175 shift
176 ;;
58634dbf
EW
177 -M|-m|--m|--me|--mer|--merg|--merge)
178 do_merge=t
179 ;;
180 -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
181 --strateg=*|--strategy=*|\
182 -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
183 case "$#,$1" in
184 *,*=*)
8096fae7 185 strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
58634dbf
EW
186 1,*)
187 usage ;;
188 *)
189 strategy="$2"
190 shift ;;
191 esac
192 do_merge=t
193 ;;
b758789c
RS
194 -v|--verbose)
195 verbose=t
196 ;;
e646c9c8
JH
197 -*)
198 usage
199 ;;
200 *)
201 break
202 ;;
203 esac
204 shift
205done
2db8aaec 206
7f4bd5d8 207# Make sure we do not have .dotest
58634dbf 208if test -z "$do_merge"
7f4bd5d8 209then
58634dbf
EW
210 if mkdir .dotest
211 then
212 rmdir .dotest
213 else
214 echo >&2 '
7f4bd5d8
JH
215It seems that I cannot create a .dotest directory, and I wonder if you
216are in the middle of patch application or another rebase. If that is not
217the case, please rm -fr .dotest and run me again. I am stopping in case
218you still have something valuable there.'
58634dbf
EW
219 exit 1
220 fi
221else
222 if test -d "$dotest"
223 then
224 die "previous dotest directory $dotest still exists." \
225 'try git-rebase < --continue | --abort >'
226 fi
7f4bd5d8
JH
227fi
228
7f59dbbb 229# The tree must be really really clean.
215a7ad1 230git-update-index --refresh || exit
7f59dbbb 231diff=$(git-diff-index --cached --name-status -r HEAD)
32d99544 232case "$diff" in
7f59dbbb
JH
233?*) echo "$diff"
234 exit 1
235 ;;
236esac
99a92f92 237
e646c9c8
JH
238# The upstream head must be given. Make sure it is valid.
239upstream_name="$1"
240upstream=`git rev-parse --verify "${upstream_name}^0"` ||
d0080b3c 241 die "invalid upstream $upstream_name"
32d99544 242
9a111c91
JH
243# If a hook exists, give it a chance to interrupt
244if test -x "$GIT_DIR/hooks/pre-rebase"
245then
246 "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
247 echo >&2 "The pre-rebase hook refused to rebase."
248 exit 1
249 }
250fi
251
7f59dbbb 252# If the branch to rebase is given, first switch to it.
59e6b23a 253case "$#" in
7f59dbbb 2542)
e646c9c8 255 branch_name="$2"
3ae39ab2 256 git-checkout "$2" || usage
e646c9c8
JH
257 ;;
258*)
259 branch_name=`git symbolic-ref HEAD` || die "No current branch"
f327dbce 260 branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'`
e646c9c8 261 ;;
59e6b23a 262esac
e646c9c8 263branch=$(git-rev-parse --verify "${branch_name}^0") || exit
59e6b23a 264
e646c9c8
JH
265# Make sure the branch to rebase onto is valid.
266onto_name=${newbase-"$upstream_name"}
267onto=$(git-rev-parse --verify "${onto_name}^0") || exit
32d99544 268
e646c9c8
JH
269# Now we are rebasing commits $upstream..$branch on top of $onto
270
271# Check if we are already based on $onto, but this should be
272# done only when upstream and onto are the same.
83c31614
RS
273mb=$(git-merge-base "$onto" "$branch")
274if test "$upstream" = "$onto" && test "$mb" = "$onto"
7f4bd5d8 275then
83c31614
RS
276 echo >&2 "Current branch $branch_name is up to date."
277 exit 0
7f4bd5d8
JH
278fi
279
b758789c
RS
280if test -n "$verbose"
281then
282 echo "Changes from $mb to $onto:"
283 git-diff-tree --stat --summary "$mb" "$onto"
284fi
285
e646c9c8
JH
286# Rewind the head to "$onto"; this saves our current head in ORIG_HEAD.
287git-reset --hard "$onto"
32d99544 288
e646c9c8 289# If the $onto is a proper descendant of the tip of the branch, then
32d99544 290# we just fast forwarded.
83c31614 291if test "$mb" = "$branch"
32d99544 292then
d587ed13 293 echo >&2 "Fast-forwarded $branch_name to $onto_name."
32d99544
LS
294 exit 0
295fi
296
58634dbf
EW
297if test -z "$do_merge"
298then
91b48977 299 git-format-patch -k --stdout --full-index --ignore-if-in-upstream "$upstream"..ORIG_HEAD |
8ef1c7c7
SP
300 git am --binary -3 -k --resolvemsg="$RESOLVEMSG" \
301 --reflog-action=rebase
58634dbf
EW
302 exit $?
303fi
304
a06f678e 305if test "@@NO_PYTHON@@" && test "$strategy" = "recursive-old"
693c15dc 306then
a06f678e 307 die 'The recursive-old merge strategy is written in Python,
693c15dc 308which this installation of git was not configured with. Please consider
a06f678e 309a different merge strategy (e.g. recursive, resolve, or stupid)
693c15dc
EW
310or install Python and git with Python support.'
311
312fi
313
58634dbf
EW
314# start doing a rebase with git-merge
315# this is rename-aware if the recursive (default) strategy is used
316
317mkdir -p "$dotest"
318echo "$onto" > "$dotest/onto"
319prev_head=`git-rev-parse HEAD^0`
320echo "$prev_head" > "$dotest/prev_head"
321
322msgnum=0
323for cmt in `git-rev-list --no-merges "$upstream"..ORIG_HEAD \
d9bffc08 324 | @@PERL@@ -e 'print reverse <>'`
58634dbf
EW
325do
326 msgnum=$(($msgnum + 1))
5887ac82 327 echo "$cmt" > "$dotest/cmt.$msgnum"
58634dbf
EW
328done
329
5887ac82
JH
330echo 1 >"$dotest/msgnum"
331echo $msgnum >"$dotest/end"
58634dbf
EW
332
333end=$msgnum
334msgnum=1
335
336while test "$msgnum" -le "$end"
337do
338 call_merge "$msgnum"
339 continue_merge
340done
cc120056 341
58634dbf 342finish_rb_merge