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