| Junio C Hamano | 59e6b23 | 2005-06-25 09:23:43 | [diff] [blame] | 1 | #!/bin/sh |
| 2 | # |
| 3 | # Copyright (c) 2005 Junio C Hamano. |
| 4 | # |
| 5 | |
| Johannes Schindelin | 1b1dce4 | 2007-06-25 00:11:14 | [diff] [blame] | 6 | USAGE='[--interactive | -i] [-v] [--onto <newbase>] <upstream> [<branch>]' |
| sean | 031321c | 2006-04-26 14:49:38 | [diff] [blame] | 7 | LONG_USAGE='git-rebase replaces <branch> with a new branch of the |
| 8 | same name. When the --onto option is provided the new branch starts |
| 9 | out with a HEAD equal to <newbase>, otherwise it is equal to <upstream> |
| 10 | It then attempts to create a new commit for each commit from the original |
| 11 | <branch> that does not exist in the <upstream> branch. |
| Carl Worth | 69a60af | 2006-02-22 01:10:12 | [diff] [blame] | 12 | |
| sean | 031321c | 2006-04-26 14:49:38 | [diff] [blame] | 13 | It is possible that a merge failure will prevent this process from being |
| 14 | completely automatic. You will have to resolve any such merge failure |
| Sean | cc12005 | 2006-05-14 03:34:08 | [diff] [blame] | 15 | and run git rebase --continue. Another option is to bypass the commit |
| 16 | that caused the merge failure with git rebase --skip. To restore the |
| Johannes Schindelin | 51ef1da | 2008-07-21 10:51:02 | [diff] [blame] | 17 | original <branch> and remove the .git/rebase-apply working files, use the |
| 18 | command git rebase --abort instead. |
| Carl Worth | 69a60af | 2006-02-22 01:10:12 | [diff] [blame] | 19 | |
| sean | 031321c | 2006-04-26 14:49:38 | [diff] [blame] | 20 | Note that if <branch> is not specified on the command line, the |
| SZEDER Gábor | 702088a | 2008-03-10 14:38:33 | [diff] [blame] | 21 | currently checked out branch is used. |
| Junio C Hamano | e646c9c | 2006-02-14 22:42:05 | [diff] [blame] | 22 | |
| sean | 031321c | 2006-04-26 14:49:38 | [diff] [blame] | 23 | Example: git-rebase master~1 topic |
| Junio C Hamano | e646c9c | 2006-02-14 22:42:05 | [diff] [blame] | 24 | |
| sean | 031321c | 2006-04-26 14:49:38 | [diff] [blame] | 25 | A---B---C topic A'\''--B'\''--C'\'' topic |
| 26 | / --> / |
| 27 | D---E---F---G master D---E---F---G master |
| Junio C Hamano | e646c9c | 2006-02-14 22:42:05 | [diff] [blame] | 28 | ' |
| Junio C Hamano | 533b703 | 2007-01-12 20:52:03 | [diff] [blame] | 29 | |
| 30 | SUBDIRECTORY_OK=Yes |
| Junio C Hamano | 8f321a3 | 2007-11-06 09:50:02 | [diff] [blame] | 31 | OPTIONS_SPEC= |
| Junio C Hamano | ae2b0f1 | 2005-11-24 08:12:11 | [diff] [blame] | 32 | . git-sh-setup |
| Shawn O. Pearce | f947413 | 2006-12-28 07:34:48 | [diff] [blame] | 33 | set_reflog_action rebase |
| Shawn O. Pearce | 7eff28a | 2006-12-31 04:32:38 | [diff] [blame] | 34 | require_work_tree |
| Junio C Hamano | 533b703 | 2007-01-12 20:52:03 | [diff] [blame] | 35 | cd_to_toplevel |
| Junio C Hamano | 4282c4f | 2005-08-07 22:51:09 | [diff] [blame] | 36 | |
| Nanako Shiraishi | c442765 | 2008-10-06 05:14:29 | [diff] [blame] | 37 | OK_TO_SKIP_PRE_REBASE= |
| Sean | cc12005 | 2006-05-14 03:34:08 | [diff] [blame] | 38 | RESOLVEMSG=" |
| 39 | When you have resolved this problem run \"git rebase --continue\". |
| 40 | If you would prefer to skip this patch, instead run \"git rebase --skip\". |
| 41 | To restore the original branch and stop rebasing run \"git rebase --abort\". |
| 42 | " |
| Junio C Hamano | e646c9c | 2006-02-14 22:42:05 | [diff] [blame] | 43 | unset newbase |
| Junio C Hamano | a06f678 | 2006-09-25 02:49:47 | [diff] [blame] | 44 | strategy=recursive |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 45 | do_merge= |
| Johannes Schindelin | 28ed6e7 | 2008-07-16 01:33:44 | [diff] [blame] | 46 | dotest="$GIT_DIR"/rebase-merge |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 47 | prec=4 |
| Robert Shearman | b758789 | 2006-10-03 16:29:31 | [diff] [blame] | 48 | verbose= |
| Michael S. Tsirkin | 67dad68 | 2007-02-08 13:57:08 | [diff] [blame] | 49 | git_am_opt= |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 50 | |
| 51 | continue_merge () { |
| 52 | test -n "$prev_head" || die "prev_head must be defined" |
| 53 | test -d "$dotest" || die "$dotest directory does not exist" |
| 54 | |
| Junio C Hamano | 5be6007 | 2007-07-03 05:52:14 | [diff] [blame] | 55 | unmerged=$(git ls-files -u) |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 56 | if test -n "$unmerged" |
| 57 | then |
| 58 | echo "You still have unmerged paths in your index" |
| Jonas Fonseca | 9b07873 | 2007-06-02 17:59:49 | [diff] [blame] | 59 | echo "did you forget to use git add?" |
| Eric Wong | 66eb64c | 2006-06-28 09:11:06 | [diff] [blame] | 60 | die "$RESOLVEMSG" |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 61 | fi |
| 62 | |
| Jonathan del Strother | 889a50e | 2007-10-17 09:31:35 | [diff] [blame] | 63 | cmt=`cat "$dotest/current"` |
| Johannes Schindelin | 6848d58 | 2008-05-14 17:03:59 | [diff] [blame] | 64 | if ! git diff-index --quiet --ignore-submodules HEAD -- |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 65 | then |
| Junio C Hamano | e637122 | 2008-03-16 07:50:22 | [diff] [blame] | 66 | if ! git commit --no-verify -C "$cmt" |
| Eric Wong | f0ef059 | 2006-06-28 10:24:23 | [diff] [blame] | 67 | then |
| 68 | echo "Commit failed, please do not call \"git commit\"" |
| 69 | echo "directly, but instead do one of the following: " |
| 70 | die "$RESOLVEMSG" |
| 71 | fi |
| Johannes Sixt | 7afa845 | 2007-09-01 07:25:27 | [diff] [blame] | 72 | printf "Committed: %0${prec}d " $msgnum |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 73 | else |
| Johannes Sixt | 7afa845 | 2007-09-01 07:25:27 | [diff] [blame] | 74 | printf "Already applied: %0${prec}d " $msgnum |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 75 | fi |
| Junio C Hamano | c7965af | 2007-09-01 09:17:28 | [diff] [blame] | 76 | git rev-list --pretty=oneline -1 "$cmt" | sed -e 's/^[^ ]* //' |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 77 | |
| Junio C Hamano | 5be6007 | 2007-07-03 05:52:14 | [diff] [blame] | 78 | prev_head=`git rev-parse HEAD^0` |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 79 | # save the resulting commit so we can read-tree on it later |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 80 | echo "$prev_head" > "$dotest/prev_head" |
| 81 | |
| 82 | # onto the next patch: |
| 83 | msgnum=$(($msgnum + 1)) |
| Junio C Hamano | 5887ac8 | 2006-06-22 08:44:54 | [diff] [blame] | 84 | echo "$msgnum" >"$dotest/msgnum" |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 85 | } |
| 86 | |
| 87 | call_merge () { |
| Jonathan del Strother | 889a50e | 2007-10-17 09:31:35 | [diff] [blame] | 88 | cmt="$(cat "$dotest/cmt.$1")" |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 89 | echo "$cmt" > "$dotest/current" |
| Junio C Hamano | 5be6007 | 2007-07-03 05:52:14 | [diff] [blame] | 90 | hd=$(git rev-parse --verify HEAD) |
| Johannes Schindelin | 6fd2f5e | 2007-11-08 18:19:08 | [diff] [blame] | 91 | cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD) |
| Jonathan del Strother | 889a50e | 2007-10-17 09:31:35 | [diff] [blame] | 92 | msgnum=$(cat "$dotest/msgnum") |
| 93 | end=$(cat "$dotest/end") |
| Shawn O. Pearce | 0bb733c | 2006-12-28 07:34:56 | [diff] [blame] | 94 | eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"' |
| Jonathan del Strother | 889a50e | 2007-10-17 09:31:35 | [diff] [blame] | 95 | eval GITHEAD_$hd='$(cat "$dotest/onto_name")' |
| Shawn O. Pearce | 0bb733c | 2006-12-28 07:34:56 | [diff] [blame] | 96 | export GITHEAD_$cmt GITHEAD_$hd |
| 97 | git-merge-$strategy "$cmt^" -- "$hd" "$cmt" |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 98 | rv=$? |
| 99 | case "$rv" in |
| 100 | 0) |
| Shawn O. Pearce | 0bb733c | 2006-12-28 07:34:56 | [diff] [blame] | 101 | unset GITHEAD_$cmt GITHEAD_$hd |
| Eric Wong | 9e4bc7d | 2006-06-25 01:29:48 | [diff] [blame] | 102 | return |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 103 | ;; |
| 104 | 1) |
| Johannes Schindelin | b4372ef | 2007-07-06 12:05:59 | [diff] [blame] | 105 | git rerere |
| Eric Wong | 66eb64c | 2006-06-28 09:11:06 | [diff] [blame] | 106 | die "$RESOLVEMSG" |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 107 | ;; |
| 108 | 2) |
| 109 | echo "Strategy: $rv $strategy failed, try another" 1>&2 |
| Eric Wong | 66eb64c | 2006-06-28 09:11:06 | [diff] [blame] | 110 | die "$RESOLVEMSG" |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 111 | ;; |
| 112 | *) |
| 113 | die "Unknown exit code ($rv) from command:" \ |
| 114 | "git-merge-$strategy $cmt^ -- HEAD $cmt" |
| 115 | ;; |
| 116 | esac |
| 117 | } |
| 118 | |
| Johannes Schindelin | 6fd2f5e | 2007-11-08 18:19:08 | [diff] [blame] | 119 | move_to_original_branch () { |
| 120 | test -z "$head_name" && |
| 121 | head_name="$(cat "$dotest"/head-name)" && |
| 122 | onto="$(cat "$dotest"/onto)" && |
| 123 | orig_head="$(cat "$dotest"/orig-head)" |
| 124 | case "$head_name" in |
| 125 | refs/*) |
| 126 | message="rebase finished: $head_name onto $onto" |
| 127 | git update-ref -m "$message" \ |
| 128 | $head_name $(git rev-parse HEAD) $orig_head && |
| 129 | git symbolic-ref HEAD $head_name || |
| 130 | die "Could not move back to $head_name" |
| 131 | ;; |
| 132 | esac |
| 133 | } |
| 134 | |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 135 | finish_rb_merge () { |
| Johannes Schindelin | 6fd2f5e | 2007-11-08 18:19:08 | [diff] [blame] | 136 | move_to_original_branch |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 137 | rm -r "$dotest" |
| 138 | echo "All done." |
| 139 | } |
| 140 | |
| Johannes Schindelin | 1b1dce4 | 2007-06-25 00:11:14 | [diff] [blame] | 141 | is_interactive () { |
| Andreas Ericsson | f8cca01 | 2008-09-29 20:28:57 | [diff] [blame] | 142 | while test $# != 0 |
| 143 | do |
| 144 | case "$1" in |
| 145 | -i|--interactive) |
| 146 | interactive_rebase=explicit |
| 147 | break |
| 148 | ;; |
| 149 | -p|--preserve-merges) |
| 150 | interactive_rebase=implied |
| 151 | ;; |
| 152 | esac |
| Johannes Schindelin | 1b1dce4 | 2007-06-25 00:11:14 | [diff] [blame] | 153 | shift |
| Andreas Ericsson | f8cca01 | 2008-09-29 20:28:57 | [diff] [blame] | 154 | done |
| 155 | |
| 156 | if [ "$interactive_rebase" = implied ]; then |
| 157 | GIT_EDITOR=: |
| 158 | export GIT_EDITOR |
| 159 | fi |
| 160 | |
| 161 | test -n "$interactive_rebase" || test -f "$dotest"/interactive |
| Johannes Schindelin | 1b1dce4 | 2007-06-25 00:11:14 | [diff] [blame] | 162 | } |
| 163 | |
| Nanako Shiraishi | d70b4a8 | 2008-10-06 05:14:24 | [diff] [blame] | 164 | run_pre_rebase_hook () { |
| Nanako Shiraishi | c442765 | 2008-10-06 05:14:29 | [diff] [blame] | 165 | if test -z "$OK_TO_SKIP_PRE_REBASE" && |
| 166 | test -x "$GIT_DIR/hooks/pre-rebase" |
| Nanako Shiraishi | d70b4a8 | 2008-10-06 05:14:24 | [diff] [blame] | 167 | then |
| 168 | "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || { |
| 169 | echo >&2 "The pre-rebase hook refused to rebase." |
| 170 | exit 1 |
| 171 | } |
| 172 | fi |
| 173 | } |
| 174 | |
| Stephan Beyer | 9b752a6 | 2008-08-17 04:25:43 | [diff] [blame] | 175 | test -f "$GIT_DIR"/rebase-apply/applying && |
| 176 | die 'It looks like git-am is in progress. Cannot rebase.' |
| 177 | |
| Johannes Schindelin | 1b1dce4 | 2007-06-25 00:11:14 | [diff] [blame] | 178 | is_interactive "$@" && exec git-rebase--interactive "$@" |
| 179 | |
| Stephan Beyer | 9b752a6 | 2008-08-17 04:25:43 | [diff] [blame] | 180 | if test $# -eq 0 |
| 181 | then |
| 182 | test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply || usage |
| 183 | test -d "$dotest" -o -f "$GIT_DIR"/rebase-apply/rebasing && |
| 184 | die 'A rebase is in progress, try --continue, --skip or --abort.' |
| 185 | die "No arguments given and $GIT_DIR/rebase-apply already exists." |
| 186 | fi |
| 187 | |
| David Kastrup | 822f7c7 | 2007-09-23 20:42:08 | [diff] [blame] | 188 | while test $# != 0 |
| Junio C Hamano | e646c9c | 2006-02-14 22:42:05 | [diff] [blame] | 189 | do |
| 190 | case "$1" in |
| Nanako Shiraishi | c442765 | 2008-10-06 05:14:29 | [diff] [blame] | 191 | --no-verify) |
| 192 | OK_TO_SKIP_PRE_REBASE=yes |
| 193 | ;; |
| sean | 031321c | 2006-04-26 14:49:38 | [diff] [blame] | 194 | --continue) |
| Johannes Schindelin | 51ef1da | 2008-07-21 10:51:02 | [diff] [blame] | 195 | test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply || |
| Stephan Beyer | cd5320f | 2008-06-22 14:07:02 | [diff] [blame] | 196 | die "No rebase in progress?" |
| 197 | |
| Johannes Schindelin | 6848d58 | 2008-05-14 17:03:59 | [diff] [blame] | 198 | git diff-files --quiet --ignore-submodules || { |
| Alex Riesen | 06aff47 | 2007-03-25 00:56:13 | [diff] [blame] | 199 | echo "You must edit all merge conflicts and then" |
| Jonas Fonseca | 9b07873 | 2007-06-02 17:59:49 | [diff] [blame] | 200 | echo "mark them as resolved using git add" |
| sean | 031321c | 2006-04-26 14:49:38 | [diff] [blame] | 201 | exit 1 |
| Alex Riesen | 06aff47 | 2007-03-25 00:56:13 | [diff] [blame] | 202 | } |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 203 | if test -d "$dotest" |
| 204 | then |
| Jonathan del Strother | 889a50e | 2007-10-17 09:31:35 | [diff] [blame] | 205 | prev_head=$(cat "$dotest/prev_head") |
| 206 | end=$(cat "$dotest/end") |
| 207 | msgnum=$(cat "$dotest/msgnum") |
| 208 | onto=$(cat "$dotest/onto") |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 209 | continue_merge |
| 210 | while test "$msgnum" -le "$end" |
| 211 | do |
| 212 | call_merge "$msgnum" |
| 213 | continue_merge |
| 214 | done |
| 215 | finish_rb_merge |
| 216 | exit |
| 217 | fi |
| Johannes Schindelin | 51ef1da | 2008-07-21 10:51:02 | [diff] [blame] | 218 | head_name=$(cat "$GIT_DIR"/rebase-apply/head-name) && |
| 219 | onto=$(cat "$GIT_DIR"/rebase-apply/onto) && |
| 220 | orig_head=$(cat "$GIT_DIR"/rebase-apply/orig-head) && |
| Johannes Schindelin | 3f735b6 | 2007-11-12 13:11:46 | [diff] [blame] | 221 | git am --resolved --3way --resolvemsg="$RESOLVEMSG" && |
| 222 | move_to_original_branch |
| Sean | cc12005 | 2006-05-14 03:34:08 | [diff] [blame] | 223 | exit |
| 224 | ;; |
| 225 | --skip) |
| Johannes Schindelin | 51ef1da | 2008-07-21 10:51:02 | [diff] [blame] | 226 | test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply || |
| Stephan Beyer | cd5320f | 2008-06-22 14:07:02 | [diff] [blame] | 227 | die "No rebase in progress?" |
| 228 | |
| Mike Hommey | fb6e4e1 | 2007-11-08 07:03:06 | [diff] [blame] | 229 | git reset --hard HEAD || exit $? |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 230 | if test -d "$dotest" |
| 231 | then |
| Johannes Schindelin | b4372ef | 2007-07-06 12:05:59 | [diff] [blame] | 232 | git rerere clear |
| Jonathan del Strother | 889a50e | 2007-10-17 09:31:35 | [diff] [blame] | 233 | prev_head=$(cat "$dotest/prev_head") |
| 234 | end=$(cat "$dotest/end") |
| 235 | msgnum=$(cat "$dotest/msgnum") |
| Eric Wong | d5e673b | 2006-06-25 01:29:49 | [diff] [blame] | 236 | msgnum=$(($msgnum + 1)) |
| Jonathan del Strother | 889a50e | 2007-10-17 09:31:35 | [diff] [blame] | 237 | onto=$(cat "$dotest/onto") |
| Eric Wong | d5e673b | 2006-06-25 01:29:49 | [diff] [blame] | 238 | while test "$msgnum" -le "$end" |
| 239 | do |
| 240 | call_merge "$msgnum" |
| 241 | continue_merge |
| 242 | done |
| 243 | finish_rb_merge |
| 244 | exit |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 245 | fi |
| Johannes Schindelin | 51ef1da | 2008-07-21 10:51:02 | [diff] [blame] | 246 | head_name=$(cat "$GIT_DIR"/rebase-apply/head-name) && |
| 247 | onto=$(cat "$GIT_DIR"/rebase-apply/onto) && |
| 248 | orig_head=$(cat "$GIT_DIR"/rebase-apply/orig-head) && |
| Johannes Schindelin | 6fd2f5e | 2007-11-08 18:19:08 | [diff] [blame] | 249 | git am -3 --skip --resolvemsg="$RESOLVEMSG" && |
| 250 | move_to_original_branch |
| sean | 031321c | 2006-04-26 14:49:38 | [diff] [blame] | 251 | exit |
| 252 | ;; |
| 253 | --abort) |
| Johannes Schindelin | 51ef1da | 2008-07-21 10:51:02 | [diff] [blame] | 254 | test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply || |
| Stephan Beyer | cd5320f | 2008-06-22 14:07:02 | [diff] [blame] | 255 | die "No rebase in progress?" |
| 256 | |
| Johannes Schindelin | b4372ef | 2007-07-06 12:05:59 | [diff] [blame] | 257 | git rerere clear |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 258 | if test -d "$dotest" |
| 259 | then |
| Johannes Schindelin | 6fd2f5e | 2007-11-08 18:19:08 | [diff] [blame] | 260 | move_to_original_branch |
| Stephan Beyer | cd5320f | 2008-06-22 14:07:02 | [diff] [blame] | 261 | else |
| Johannes Schindelin | 51ef1da | 2008-07-21 10:51:02 | [diff] [blame] | 262 | dotest="$GIT_DIR"/rebase-apply |
| Johannes Schindelin | 6fd2f5e | 2007-11-08 18:19:08 | [diff] [blame] | 263 | move_to_original_branch |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 264 | fi |
| Bryan Donlan | 97b88dd | 2008-05-04 05:37:51 | [diff] [blame] | 265 | git reset --hard $(cat "$dotest/orig-head") |
| Mike Hommey | 48411d2 | 2008-03-01 10:32:14 | [diff] [blame] | 266 | rm -r "$dotest" |
| sean | 031321c | 2006-04-26 14:49:38 | [diff] [blame] | 267 | exit |
| 268 | ;; |
| Junio C Hamano | e646c9c | 2006-02-14 22:42:05 | [diff] [blame] | 269 | --onto) |
| 270 | test 2 -le "$#" || usage |
| 271 | newbase="$2" |
| 272 | shift |
| 273 | ;; |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 274 | -M|-m|--m|--me|--mer|--merg|--merge) |
| 275 | do_merge=t |
| 276 | ;; |
| 277 | -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\ |
| 278 | --strateg=*|--strategy=*|\ |
| 279 | -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy) |
| 280 | case "$#,$1" in |
| 281 | *,*=*) |
| Dennis Stosberg | 8096fae | 2006-06-27 16:54:26 | [diff] [blame] | 282 | strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;; |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 283 | 1,*) |
| 284 | usage ;; |
| 285 | *) |
| 286 | strategy="$2" |
| 287 | shift ;; |
| 288 | esac |
| 289 | do_merge=t |
| 290 | ;; |
| Robert Shearman | b758789 | 2006-10-03 16:29:31 | [diff] [blame] | 291 | -v|--verbose) |
| 292 | verbose=t |
| 293 | ;; |
| J. Bruce Fields | 059f446 | 2007-09-07 14:20:50 | [diff] [blame] | 294 | --whitespace=*) |
| 295 | git_am_opt="$git_am_opt $1" |
| 296 | ;; |
| Michael S. Tsirkin | 67dad68 | 2007-02-08 13:57:08 | [diff] [blame] | 297 | -C*) |
| J. Bruce Fields | 059f446 | 2007-09-07 14:20:50 | [diff] [blame] | 298 | git_am_opt="$git_am_opt $1" |
| Michael S. Tsirkin | 67dad68 | 2007-02-08 13:57:08 | [diff] [blame] | 299 | ;; |
| Junio C Hamano | e646c9c | 2006-02-14 22:42:05 | [diff] [blame] | 300 | -*) |
| 301 | usage |
| 302 | ;; |
| 303 | *) |
| 304 | break |
| 305 | ;; |
| 306 | esac |
| 307 | shift |
| 308 | done |
| Junio C Hamano | 2db8aae | 2005-12-14 11:11:37 | [diff] [blame] | 309 | |
| Johannes Schindelin | 51ef1da | 2008-07-21 10:51:02 | [diff] [blame] | 310 | # Make sure we do not have $GIT_DIR/rebase-apply |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 311 | if test -z "$do_merge" |
| Junio C Hamano | 7f4bd5d | 2005-11-28 21:00:31 | [diff] [blame] | 312 | then |
| Stephan Beyer | 9b752a6 | 2008-08-17 04:25:43 | [diff] [blame] | 313 | if mkdir "$GIT_DIR"/rebase-apply 2>/dev/null |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 314 | then |
| Johannes Schindelin | 51ef1da | 2008-07-21 10:51:02 | [diff] [blame] | 315 | rmdir "$GIT_DIR"/rebase-apply |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 316 | else |
| 317 | echo >&2 ' |
| Stephan Beyer | 9b752a6 | 2008-08-17 04:25:43 | [diff] [blame] | 318 | It seems that I cannot create a rebase-apply directory, and |
| 319 | I wonder if you are in the middle of patch application or another |
| Johannes Schindelin | 51ef1da | 2008-07-21 10:51:02 | [diff] [blame] | 320 | rebase. If that is not the case, please |
| 321 | rm -fr '"$GIT_DIR"'/rebase-apply |
| Stephan Beyer | 9b752a6 | 2008-08-17 04:25:43 | [diff] [blame] | 322 | and run me again. I am stopping in case you still have something |
| Johannes Schindelin | 51ef1da | 2008-07-21 10:51:02 | [diff] [blame] | 323 | valuable there.' |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 324 | exit 1 |
| 325 | fi |
| 326 | else |
| 327 | if test -d "$dotest" |
| 328 | then |
| Johannes Schindelin | 28ed6e7 | 2008-07-16 01:33:44 | [diff] [blame] | 329 | die "previous rebase directory $dotest still exists." \ |
| Stephan Beyer | 9b752a6 | 2008-08-17 04:25:43 | [diff] [blame] | 330 | 'Try git rebase (--continue | --abort | --skip)' |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 331 | fi |
| Junio C Hamano | 7f4bd5d | 2005-11-28 21:00:31 | [diff] [blame] | 332 | fi |
| 333 | |
| Junio C Hamano | 7f59dbb | 2005-11-14 08:41:53 | [diff] [blame] | 334 | # The tree must be really really clean. |
| Jeff King | 07e62b7 | 2008-12-10 09:25:19 | [diff] [blame] | 335 | if ! git update-index --ignore-submodules --refresh; then |
| 336 | echo >&2 "cannot rebase: you have unstaged changes" |
| 337 | exit 1 |
| 338 | fi |
| Johannes Schindelin | 6848d58 | 2008-05-14 17:03:59 | [diff] [blame] | 339 | diff=$(git diff-index --cached --name-status -r --ignore-submodules HEAD --) |
| Lukas Sandström | 32d9954 | 2005-12-14 23:36:35 | [diff] [blame] | 340 | case "$diff" in |
| Jeff King | 07e62b7 | 2008-12-10 09:25:19 | [diff] [blame] | 341 | ?*) echo >&2 "cannot rebase: your index contains uncommitted changes" |
| 342 | echo >&2 "$diff" |
| Junio C Hamano | 7f59dbb | 2005-11-14 08:41:53 | [diff] [blame] | 343 | exit 1 |
| 344 | ;; |
| Junio C Hamano | 59e6b23 | 2005-06-25 09:23:43 | [diff] [blame] | 345 | esac |
| 346 | |
| Junio C Hamano | e646c9c | 2006-02-14 22:42:05 | [diff] [blame] | 347 | # The upstream head must be given. Make sure it is valid. |
| 348 | upstream_name="$1" |
| 349 | upstream=`git rev-parse --verify "${upstream_name}^0"` || |
| Jason Riedy | d0080b3 | 2006-02-21 20:56:14 | [diff] [blame] | 350 | die "invalid upstream $upstream_name" |
| Lukas Sandström | 32d9954 | 2005-12-14 23:36:35 | [diff] [blame] | 351 | |
| Junio C Hamano | a1bf91e | 2007-03-22 09:54:59 | [diff] [blame] | 352 | # Make sure the branch to rebase onto is valid. |
| 353 | onto_name=${newbase-"$upstream_name"} |
| Junio C Hamano | 5be6007 | 2007-07-03 05:52:14 | [diff] [blame] | 354 | onto=$(git rev-parse --verify "${onto_name}^0") || exit |
| Junio C Hamano | a1bf91e | 2007-03-22 09:54:59 | [diff] [blame] | 355 | |
| Junio C Hamano | 9a111c9 | 2006-02-13 07:17:04 | [diff] [blame] | 356 | # If a hook exists, give it a chance to interrupt |
| Nanako Shiraishi | d70b4a8 | 2008-10-06 05:14:24 | [diff] [blame] | 357 | run_pre_rebase_hook ${1+"$@"} |
| Junio C Hamano | 9a111c9 | 2006-02-13 07:17:04 | [diff] [blame] | 358 | |
| Junio C Hamano | 0cb0664 | 2008-03-15 20:17:42 | [diff] [blame] | 359 | # If the branch to rebase is given, that is the branch we will rebase |
| 360 | # $branch_name -- branch being rebased, or HEAD (already detached) |
| 361 | # $orig_head -- commit object name of tip of the branch before rebasing |
| 362 | # $head_name -- refs/heads/<that-branch> or "detached HEAD" |
| 363 | switch_to= |
| Junio C Hamano | 7f59dbb | 2005-11-14 08:41:53 | [diff] [blame] | 364 | case "$#" in |
| 365 | 2) |
| Junio C Hamano | 0cb0664 | 2008-03-15 20:17:42 | [diff] [blame] | 366 | # Is it "rebase other $branchname" or "rebase other $commit"? |
| Junio C Hamano | e646c9c | 2006-02-14 22:42:05 | [diff] [blame] | 367 | branch_name="$2" |
| Junio C Hamano | 0cb0664 | 2008-03-15 20:17:42 | [diff] [blame] | 368 | switch_to="$2" |
| 369 | |
| 370 | if git show-ref --verify --quiet -- "refs/heads/$2" && |
| Miklos Vajna | 5a92d19 | 2008-12-03 13:26:51 | [diff] [blame] | 371 | branch=$(git rev-parse -q --verify "refs/heads/$2") |
| Junio C Hamano | bcf3161 | 2007-01-21 03:11:29 | [diff] [blame] | 372 | then |
| Junio C Hamano | 0cb0664 | 2008-03-15 20:17:42 | [diff] [blame] | 373 | head_name="refs/heads/$2" |
| Miklos Vajna | 5a92d19 | 2008-12-03 13:26:51 | [diff] [blame] | 374 | elif branch=$(git rev-parse -q --verify "$2") |
| Junio C Hamano | 0cb0664 | 2008-03-15 20:17:42 | [diff] [blame] | 375 | then |
| 376 | head_name="detached HEAD" |
| Junio C Hamano | bcf3161 | 2007-01-21 03:11:29 | [diff] [blame] | 377 | else |
| Junio C Hamano | 0cb0664 | 2008-03-15 20:17:42 | [diff] [blame] | 378 | usage |
| Junio C Hamano | bcf3161 | 2007-01-21 03:11:29 | [diff] [blame] | 379 | fi |
| Junio C Hamano | e646c9c | 2006-02-14 22:42:05 | [diff] [blame] | 380 | ;; |
| Junio C Hamano | 0cb0664 | 2008-03-15 20:17:42 | [diff] [blame] | 381 | *) |
| 382 | # Do not need to switch branches, we are already on it. |
| 383 | if branch_name=`git symbolic-ref -q HEAD` |
| 384 | then |
| 385 | head_name=$branch_name |
| 386 | branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'` |
| 387 | else |
| 388 | head_name="detached HEAD" |
| 389 | branch_name=HEAD ;# detached |
| 390 | fi |
| 391 | branch=$(git rev-parse --verify "${branch_name}^0") || exit |
| 392 | ;; |
| Junio C Hamano | 7f59dbb | 2005-11-14 08:41:53 | [diff] [blame] | 393 | esac |
| Junio C Hamano | 0cb0664 | 2008-03-15 20:17:42 | [diff] [blame] | 394 | orig_head=$branch |
| Junio C Hamano | 99a92f9 | 2005-08-17 22:19:57 | [diff] [blame] | 395 | |
| Junio C Hamano | e646c9c | 2006-02-14 22:42:05 | [diff] [blame] | 396 | # Now we are rebasing commits $upstream..$branch on top of $onto |
| 397 | |
| Johannes Sixt | 1308c17 | 2007-07-04 20:09:10 | [diff] [blame] | 398 | # Check if we are already based on $onto with linear history, |
| 399 | # but this should be done only when upstream and onto are the same. |
| Junio C Hamano | 5be6007 | 2007-07-03 05:52:14 | [diff] [blame] | 400 | mb=$(git merge-base "$onto" "$branch") |
| Johannes Sixt | 1308c17 | 2007-07-04 20:09:10 | [diff] [blame] | 401 | if test "$upstream" = "$onto" && test "$mb" = "$onto" && |
| 402 | # linear history? |
| Jeff King | bbf0812 | 2008-05-14 04:01:22 | [diff] [blame] | 403 | ! (git rev-list --parents "$onto".."$branch" | grep " .* ") > /dev/null |
| Junio C Hamano | 7f4bd5d | 2005-11-28 21:00:31 | [diff] [blame] | 404 | then |
| Junio C Hamano | 0cb0664 | 2008-03-15 20:17:42 | [diff] [blame] | 405 | # Lazily switch to the target branch if needed... |
| 406 | test -z "$switch_to" || git checkout "$switch_to" |
| Robert Shearman | 83c3161 | 2006-07-27 09:32:25 | [diff] [blame] | 407 | echo >&2 "Current branch $branch_name is up to date." |
| 408 | exit 0 |
| Junio C Hamano | 7f4bd5d | 2005-11-28 21:00:31 | [diff] [blame] | 409 | fi |
| 410 | |
| Robert Shearman | b758789 | 2006-10-03 16:29:31 | [diff] [blame] | 411 | if test -n "$verbose" |
| 412 | then |
| 413 | echo "Changes from $mb to $onto:" |
| James Bowes | fefe49d | 2007-05-05 20:48:54 | [diff] [blame] | 414 | # We want color (if set), but no pager |
| Junio C Hamano | 5be6007 | 2007-07-03 05:52:14 | [diff] [blame] | 415 | GIT_PAGER='' git diff --stat --summary "$mb" "$onto" |
| Robert Shearman | b758789 | 2006-10-03 16:29:31 | [diff] [blame] | 416 | fi |
| 417 | |
| Junio C Hamano | 0cb0664 | 2008-03-15 20:17:42 | [diff] [blame] | 418 | # Detach HEAD and reset the tree |
| Junio C Hamano | 228e2eb | 2006-12-22 23:21:55 | [diff] [blame] | 419 | echo "First, rewinding head to replay your work on top of it..." |
| Junio C Hamano | 324c2c3 | 2008-07-14 21:05:35 | [diff] [blame] | 420 | git checkout -q "$onto^0" || die "could not detach HEAD" |
| Junio C Hamano | 22e4079 | 2008-07-07 07:16:38 | [diff] [blame] | 421 | git update-ref ORIG_HEAD $branch |
| Lukas Sandström | 32d9954 | 2005-12-14 23:36:35 | [diff] [blame] | 422 | |
| Junio C Hamano | e646c9c | 2006-02-14 22:42:05 | [diff] [blame] | 423 | # If the $onto is a proper descendant of the tip of the branch, then |
| Lukas Sandström | 32d9954 | 2005-12-14 23:36:35 | [diff] [blame] | 424 | # we just fast forwarded. |
| Robert Shearman | 83c3161 | 2006-07-27 09:32:25 | [diff] [blame] | 425 | if test "$mb" = "$branch" |
| Lukas Sandström | 32d9954 | 2005-12-14 23:36:35 | [diff] [blame] | 426 | then |
| Robert Shearman | d587ed1 | 2006-07-27 09:32:46 | [diff] [blame] | 427 | echo >&2 "Fast-forwarded $branch_name to $onto_name." |
| Johannes Schindelin | 6fd2f5e | 2007-11-08 18:19:08 | [diff] [blame] | 428 | move_to_original_branch |
| Lukas Sandström | 32d9954 | 2005-12-14 23:36:35 | [diff] [blame] | 429 | exit 0 |
| 430 | fi |
| 431 | |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 432 | if test -z "$do_merge" |
| 433 | then |
| Junio C Hamano | 0cb0664 | 2008-03-15 20:17:42 | [diff] [blame] | 434 | git format-patch -k --stdout --full-index --ignore-if-in-upstream \ |
| 435 | "$upstream..$orig_head" | |
| Junio C Hamano | 3041c32 | 2008-03-04 08:25:06 | [diff] [blame] | 436 | git am $git_am_opt --rebasing --resolvemsg="$RESOLVEMSG" && |
| Johannes Schindelin | 6fd2f5e | 2007-11-08 18:19:08 | [diff] [blame] | 437 | move_to_original_branch |
| 438 | ret=$? |
| Johannes Schindelin | 51ef1da | 2008-07-21 10:51:02 | [diff] [blame] | 439 | test 0 != $ret -a -d "$GIT_DIR"/rebase-apply && |
| 440 | echo $head_name > "$GIT_DIR"/rebase-apply/head-name && |
| 441 | echo $onto > "$GIT_DIR"/rebase-apply/onto && |
| 442 | echo $orig_head > "$GIT_DIR"/rebase-apply/orig-head |
| Johannes Schindelin | 6fd2f5e | 2007-11-08 18:19:08 | [diff] [blame] | 443 | exit $ret |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 444 | fi |
| Sean | cc12005 | 2006-05-14 03:34:08 | [diff] [blame] | 445 | |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 446 | # start doing a rebase with git-merge |
| 447 | # this is rename-aware if the recursive (default) strategy is used |
| 448 | |
| 449 | mkdir -p "$dotest" |
| 450 | echo "$onto" > "$dotest/onto" |
| Shawn O. Pearce | 0bb733c | 2006-12-28 07:34:56 | [diff] [blame] | 451 | echo "$onto_name" > "$dotest/onto_name" |
| Johannes Schindelin | 6fd2f5e | 2007-11-08 18:19:08 | [diff] [blame] | 452 | prev_head=$orig_head |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 453 | echo "$prev_head" > "$dotest/prev_head" |
| Johannes Schindelin | 6fd2f5e | 2007-11-08 18:19:08 | [diff] [blame] | 454 | echo "$orig_head" > "$dotest/orig-head" |
| 455 | echo "$head_name" > "$dotest/head-name" |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 456 | |
| 457 | msgnum=0 |
| Junio C Hamano | 0cb0664 | 2008-03-15 20:17:42 | [diff] [blame] | 458 | for cmt in `git rev-list --reverse --no-merges "$upstream..$orig_head"` |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 459 | do |
| 460 | msgnum=$(($msgnum + 1)) |
| Junio C Hamano | 5887ac8 | 2006-06-22 08:44:54 | [diff] [blame] | 461 | echo "$cmt" > "$dotest/cmt.$msgnum" |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 462 | done |
| 463 | |
| Junio C Hamano | 5887ac8 | 2006-06-22 08:44:54 | [diff] [blame] | 464 | echo 1 >"$dotest/msgnum" |
| 465 | echo $msgnum >"$dotest/end" |
| Eric Wong | 58634db | 2006-06-21 10:04:41 | [diff] [blame] | 466 | |
| 467 | end=$msgnum |
| 468 | msgnum=1 |
| 469 | |
| 470 | while test "$msgnum" -le "$end" |
| 471 | do |
| 472 | call_merge "$msgnum" |
| 473 | continue_merge |
| 474 | done |
| 475 | |
| 476 | finish_rb_merge |