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