Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 1 | #!/bin/sh |
| 2 | # |
| 3 | # Copyright (c) 2006 Johannes E. Schindelin |
| 4 | |
| 5 | # SHORT DESCRIPTION |
| 6 | # |
| 7 | # This script makes it easy to fix up commits in the middle of a series, |
| 8 | # and rearrange commits. |
| 9 | # |
| 10 | # The original idea comes from Eric W. Biederman, in |
| 11 | # http://article.gmane.org/gmane.comp.version-control.git/22407 |
| 12 | |
Stephan Beyer | 7970aaf | 2008-07-12 17:48:20 +0200 | [diff] [blame] | 13 | OPTIONS_KEEPDASHDASH= |
| 14 | OPTIONS_SPEC="\ |
| 15 | git-rebase [-i] [options] [--] <upstream> [<branch>] |
| 16 | git-rebase [-i] (--continue | --abort | --skip) |
| 17 | -- |
| 18 | Available options are |
| 19 | v,verbose display a diffstat of what changed upstream |
| 20 | onto= rebase onto given branch instead of upstream |
| 21 | p,preserve-merges try to recreate merges instead of ignoring them |
| 22 | s,strategy= use the given merge strategy |
| 23 | m,merge always used (no-op) |
| 24 | i,interactive always used (no-op) |
| 25 | Actions: |
| 26 | continue continue rebasing process |
| 27 | abort abort rebasing process and restore original branch |
| 28 | skip skip current patch and continue rebasing process |
| 29 | " |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 30 | |
| 31 | . git-sh-setup |
| 32 | require_work_tree |
| 33 | |
Johannes Schindelin | 28ed6e7 | 2008-07-16 03:33:44 +0200 | [diff] [blame] | 34 | DOTEST="$GIT_DIR/rebase-merge" |
Seth Falcon | c22486c | 2007-07-28 16:44:40 -0700 | [diff] [blame] | 35 | TODO="$DOTEST"/git-rebase-todo |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 36 | DONE="$DOTEST"/done |
Johannes Schindelin | 6368f3f | 2007-07-21 18:09:41 +0100 | [diff] [blame] | 37 | MSG="$DOTEST"/message |
| 38 | SQUASH_MSG="$DOTEST"/message-squash |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 39 | REWRITTEN="$DOTEST"/rewritten |
| 40 | PRESERVE_MERGES= |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 41 | STRATEGY= |
Stephan Beyer | 7970aaf | 2008-07-12 17:48:20 +0200 | [diff] [blame] | 42 | ONTO= |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 43 | VERBOSE= |
| 44 | |
Wincent Colaiuta | 804c717 | 2007-11-28 00:06:36 -0800 | [diff] [blame] | 45 | GIT_CHERRY_PICK_HELP=" After resolving the conflicts, |
| 46 | mark the corrected paths with 'git add <paths>', and |
| 47 | run 'git rebase --continue'" |
| 48 | export GIT_CHERRY_PICK_HELP |
| 49 | |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 50 | warn () { |
| 51 | echo "$*" >&2 |
| 52 | } |
| 53 | |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 54 | output () { |
| 55 | case "$VERBOSE" in |
| 56 | '') |
Matt Kraai | 5166810 | 2007-09-25 18:30:13 -0700 | [diff] [blame] | 57 | output=$("$@" 2>&1 ) |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 58 | status=$? |
Matt Kraai | 5166810 | 2007-09-25 18:30:13 -0700 | [diff] [blame] | 59 | test $status != 0 && printf "%s\n" "$output" |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 60 | return $status |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 61 | ;; |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 62 | *) |
| 63 | "$@" |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 64 | ;; |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 65 | esac |
| 66 | } |
| 67 | |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 68 | require_clean_work_tree () { |
| 69 | # test if working tree is dirty |
| 70 | git rev-parse --verify HEAD > /dev/null && |
Johannes Schindelin | 6848d58 | 2008-05-14 18:03:59 +0100 | [diff] [blame] | 71 | git update-index --ignore-submodules --refresh && |
| 72 | git diff-files --quiet --ignore-submodules && |
| 73 | git diff-index --cached --quiet HEAD --ignore-submodules -- || |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 74 | die "Working tree is dirty" |
| 75 | } |
| 76 | |
| 77 | ORIG_REFLOG_ACTION="$GIT_REFLOG_ACTION" |
| 78 | |
| 79 | comment_for_reflog () { |
| 80 | case "$ORIG_REFLOG_ACTION" in |
| 81 | ''|rebase*) |
| 82 | GIT_REFLOG_ACTION="rebase -i ($1)" |
| 83 | export GIT_REFLOG_ACTION |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 84 | ;; |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 85 | esac |
| 86 | } |
| 87 | |
Junio C Hamano | 4e67387 | 2008-01-14 20:01:21 -0800 | [diff] [blame] | 88 | last_count= |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 89 | mark_action_done () { |
| 90 | sed -e 1q < "$TODO" >> "$DONE" |
| 91 | sed -e 1d < "$TODO" >> "$TODO".new |
| 92 | mv -f "$TODO".new "$TODO" |
Jeff King | aadbe44 | 2008-03-12 17:32:17 -0400 | [diff] [blame] | 93 | count=$(grep -c '^[^#]' < "$DONE") |
| 94 | total=$(($count+$(grep -c '^[^#]' < "$TODO"))) |
Junio C Hamano | 4e67387 | 2008-01-14 20:01:21 -0800 | [diff] [blame] | 95 | if test "$last_count" != "$count" |
| 96 | then |
| 97 | last_count=$count |
| 98 | printf "Rebasing (%d/%d)\r" $count $total |
| 99 | test -z "$VERBOSE" || echo |
| 100 | fi |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | make_patch () { |
Johannes Schindelin | be6ff20 | 2007-09-25 16:42:36 +0100 | [diff] [blame] | 104 | parent_sha1=$(git rev-parse --verify "$1"^) || |
| 105 | die "Cannot get patch for $1^" |
Johannes Schindelin | f3d5e46 | 2007-10-09 13:59:43 +0100 | [diff] [blame] | 106 | git diff-tree -p "$parent_sha1".."$1" > "$DOTEST"/patch |
Johannes Schindelin | be6ff20 | 2007-09-25 16:42:36 +0100 | [diff] [blame] | 107 | test -f "$DOTEST"/message || |
| 108 | git cat-file commit "$1" | sed "1,/^$/d" > "$DOTEST"/message |
| 109 | test -f "$DOTEST"/author-script || |
| 110 | get_author_ident_from_commit "$1" > "$DOTEST"/author-script |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 111 | } |
| 112 | |
| 113 | die_with_patch () { |
| 114 | make_patch "$1" |
Johannes Schindelin | ecfe72f | 2007-11-22 11:18:10 +0000 | [diff] [blame] | 115 | git rerere |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 116 | die "$2" |
| 117 | } |
| 118 | |
Johannes Schindelin | c54b781 | 2007-06-25 18:56:55 +0100 | [diff] [blame] | 119 | die_abort () { |
| 120 | rm -rf "$DOTEST" |
| 121 | die "$1" |
| 122 | } |
| 123 | |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 124 | has_action () { |
Jeff King | aadbe44 | 2008-03-12 17:32:17 -0400 | [diff] [blame] | 125 | grep '^[^#]' "$1" >/dev/null |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 126 | } |
| 127 | |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 128 | pick_one () { |
Johannes Schindelin | 1d25c8c | 2007-08-23 09:55:41 +0100 | [diff] [blame] | 129 | no_ff= |
| 130 | case "$1" in -n) sha1=$2; no_ff=t ;; *) sha1=$1 ;; esac |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 131 | output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1" |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 132 | test -d "$REWRITTEN" && |
| 133 | pick_one_preserving_merges "$@" && return |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 134 | parent_sha1=$(git rev-parse --verify $sha1^) || |
| 135 | die "Could not get the parent of $sha1" |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 136 | current_sha1=$(git rev-parse --verify HEAD) |
Michael W. Olson | 2858028 | 2007-10-15 13:48:27 -0400 | [diff] [blame] | 137 | if test "$no_ff$current_sha1" = "$parent_sha1"; then |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 138 | output git reset --hard $sha1 |
| 139 | test "a$1" = a-n && output git reset --soft $current_sha1 |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 140 | sha1=$(git rev-parse --short $sha1) |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 141 | output warn Fast forward to $sha1 |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 142 | else |
Björn Steinbrink | 2a9c53e | 2007-10-31 03:20:31 +0100 | [diff] [blame] | 143 | output git cherry-pick "$@" |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 144 | fi |
| 145 | } |
| 146 | |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 147 | pick_one_preserving_merges () { |
| 148 | case "$1" in -n) sha1=$2 ;; *) sha1=$1 ;; esac |
| 149 | sha1=$(git rev-parse $sha1) |
| 150 | |
Johannes Schindelin | 3b38ec1 | 2007-07-24 03:18:28 +0100 | [diff] [blame] | 151 | if test -f "$DOTEST"/current-commit |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 152 | then |
| 153 | current_commit=$(cat "$DOTEST"/current-commit) && |
| 154 | git rev-parse HEAD > "$REWRITTEN"/$current_commit && |
| 155 | rm "$DOTEST"/current-commit || |
| 156 | die "Cannot write current commit's replacement sha1" |
| 157 | fi |
| 158 | |
| 159 | # rewrite parents; if none were rewritten, we can fast-forward. |
| 160 | fast_forward=t |
| 161 | preserve=t |
| 162 | new_parents= |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 163 | for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-) |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 164 | do |
Johannes Schindelin | 3b38ec1 | 2007-07-24 03:18:28 +0100 | [diff] [blame] | 165 | if test -f "$REWRITTEN"/$p |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 166 | then |
| 167 | preserve=f |
| 168 | new_p=$(cat "$REWRITTEN"/$p) |
| 169 | test $p != $new_p && fast_forward=f |
| 170 | case "$new_parents" in |
| 171 | *$new_p*) |
| 172 | ;; # do nothing; that parent is already there |
| 173 | *) |
| 174 | new_parents="$new_parents $new_p" |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 175 | ;; |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 176 | esac |
Stephan Beyer | 1c5fa0a | 2008-07-16 03:51:49 +0200 | [diff] [blame] | 177 | else |
| 178 | new_parents="$new_parents $p" |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 179 | fi |
| 180 | done |
| 181 | case $fast_forward in |
| 182 | t) |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 183 | output warn "Fast forward to $sha1" |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 184 | test $preserve = f || echo $sha1 > "$REWRITTEN"/$sha1 |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 185 | ;; |
| 186 | f) |
| 187 | test "a$1" = a-n && die "Refusing to squash a merge: $sha1" |
| 188 | |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 189 | first_parent=$(expr "$new_parents" : ' \([^ ]*\)') |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 190 | # detach HEAD to current parent |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 191 | output git checkout $first_parent 2> /dev/null || |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 192 | die "Cannot move HEAD to $first_parent" |
| 193 | |
| 194 | echo $sha1 > "$DOTEST"/current-commit |
| 195 | case "$new_parents" in |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 196 | ' '*' '*) |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 197 | # redo merge |
| 198 | author_script=$(get_author_ident_from_commit $sha1) |
| 199 | eval "$author_script" |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 200 | msg="$(git cat-file commit $sha1 | sed -e '1,/^$/d')" |
Björn Steinbrink | f91333d | 2007-10-31 03:20:32 +0100 | [diff] [blame] | 201 | # No point in merging the first parent, that's HEAD |
| 202 | new_parents=${new_parents# $first_parent} |
Johannes Schindelin | ae830ed | 2007-09-25 16:43:44 +0100 | [diff] [blame] | 203 | if ! GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" \ |
| 204 | GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \ |
| 205 | GIT_AUTHOR_DATE="$GIT_AUTHOR_DATE" \ |
| 206 | output git merge $STRATEGY -m "$msg" \ |
| 207 | $new_parents |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 208 | then |
Johannes Schindelin | ecfe72f | 2007-11-22 11:18:10 +0000 | [diff] [blame] | 209 | git rerere |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 210 | printf "%s\n" "$msg" > "$GIT_DIR"/MERGE_MSG |
Johannes Schindelin | 18640d9 | 2007-07-08 03:01:29 +0100 | [diff] [blame] | 211 | die Error redoing merge $sha1 |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 212 | fi |
| 213 | ;; |
| 214 | *) |
Björn Steinbrink | 2a9c53e | 2007-10-31 03:20:31 +0100 | [diff] [blame] | 215 | output git cherry-pick "$@" || |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 216 | die_with_patch $sha1 "Could not pick $sha1" |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 217 | ;; |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 218 | esac |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 219 | ;; |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 220 | esac |
| 221 | } |
| 222 | |
Johannes Schindelin | 6368f3f | 2007-07-21 18:09:41 +0100 | [diff] [blame] | 223 | nth_string () { |
| 224 | case "$1" in |
| 225 | *1[0-9]|*[04-9]) echo "$1"th;; |
| 226 | *1) echo "$1"st;; |
| 227 | *2) echo "$1"nd;; |
| 228 | *3) echo "$1"rd;; |
| 229 | esac |
| 230 | } |
| 231 | |
| 232 | make_squash_message () { |
Johannes Schindelin | 3b38ec1 | 2007-07-24 03:18:28 +0100 | [diff] [blame] | 233 | if test -f "$SQUASH_MSG"; then |
Junio C Hamano | c7965af | 2007-09-01 02:17:28 -0700 | [diff] [blame] | 234 | COUNT=$(($(sed -n "s/^# This is [^0-9]*\([1-9][0-9]*\).*/\1/p" \ |
Jeff King | b4ce54f | 2008-03-12 17:34:34 -0400 | [diff] [blame] | 235 | < "$SQUASH_MSG" | sed -ne '$p')+1)) |
Johannes Schindelin | 6368f3f | 2007-07-21 18:09:41 +0100 | [diff] [blame] | 236 | echo "# This is a combination of $COUNT commits." |
Junio C Hamano | 8ad1065 | 2007-12-30 12:37:59 -0800 | [diff] [blame] | 237 | sed -e 1d -e '2,/^./{ |
| 238 | /^$/d |
| 239 | }' <"$SQUASH_MSG" |
Johannes Schindelin | 6368f3f | 2007-07-21 18:09:41 +0100 | [diff] [blame] | 240 | else |
| 241 | COUNT=2 |
| 242 | echo "# This is a combination of two commits." |
| 243 | echo "# The first commit's message is:" |
| 244 | echo |
| 245 | git cat-file commit HEAD | sed -e '1,/^$/d' |
Johannes Schindelin | 6368f3f | 2007-07-21 18:09:41 +0100 | [diff] [blame] | 246 | fi |
Junio C Hamano | 8ad1065 | 2007-12-30 12:37:59 -0800 | [diff] [blame] | 247 | echo |
Johannes Schindelin | 6368f3f | 2007-07-21 18:09:41 +0100 | [diff] [blame] | 248 | echo "# This is the $(nth_string $COUNT) commit message:" |
| 249 | echo |
| 250 | git cat-file commit $1 | sed -e '1,/^$/d' |
| 251 | } |
| 252 | |
| 253 | peek_next_command () { |
| 254 | sed -n "1s/ .*$//p" < "$TODO" |
| 255 | } |
| 256 | |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 257 | do_next () { |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 258 | rm -f "$DOTEST"/message "$DOTEST"/author-script \ |
| 259 | "$DOTEST"/amend || exit |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 260 | read command sha1 rest < "$TODO" |
| 261 | case "$command" in |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 262 | '#'*|'') |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 263 | mark_action_done |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 264 | ;; |
Johannes Schindelin | f8babc4 | 2007-09-29 03:32:11 +0100 | [diff] [blame] | 265 | pick|p) |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 266 | comment_for_reflog pick |
| 267 | |
| 268 | mark_action_done |
| 269 | pick_one $sha1 || |
| 270 | die_with_patch $sha1 "Could not apply $sha1... $rest" |
| 271 | ;; |
Johannes Schindelin | f8babc4 | 2007-09-29 03:32:11 +0100 | [diff] [blame] | 272 | edit|e) |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 273 | comment_for_reflog edit |
| 274 | |
| 275 | mark_action_done |
| 276 | pick_one $sha1 || |
| 277 | die_with_patch $sha1 "Could not apply $sha1... $rest" |
| 278 | make_patch $sha1 |
Johannes Schindelin | be6ff20 | 2007-09-25 16:42:36 +0100 | [diff] [blame] | 279 | : > "$DOTEST"/amend |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 280 | warn |
| 281 | warn "You can amend the commit now, with" |
| 282 | warn |
| 283 | warn " git commit --amend" |
| 284 | warn |
Jonathan del Strother | 0460fb4 | 2008-02-27 12:50:22 +0000 | [diff] [blame] | 285 | warn "Once you are satisfied with your changes, run" |
| 286 | warn |
| 287 | warn " git rebase --continue" |
| 288 | warn |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 289 | exit 0 |
| 290 | ;; |
Johannes Schindelin | f8babc4 | 2007-09-29 03:32:11 +0100 | [diff] [blame] | 291 | squash|s) |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 292 | comment_for_reflog squash |
| 293 | |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 294 | has_action "$DONE" || |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 295 | die "Cannot 'squash' without a previous commit" |
| 296 | |
| 297 | mark_action_done |
Johannes Schindelin | 6368f3f | 2007-07-21 18:09:41 +0100 | [diff] [blame] | 298 | make_squash_message $sha1 > "$MSG" |
| 299 | case "$(peek_next_command)" in |
Johannes Schindelin | f8babc4 | 2007-09-29 03:32:11 +0100 | [diff] [blame] | 300 | squash|s) |
Johannes Schindelin | 6368f3f | 2007-07-21 18:09:41 +0100 | [diff] [blame] | 301 | EDIT_COMMIT= |
Johannes Schindelin | 91e1ee7 | 2007-07-26 07:35:51 +0100 | [diff] [blame] | 302 | USE_OUTPUT=output |
Johannes Schindelin | 6368f3f | 2007-07-21 18:09:41 +0100 | [diff] [blame] | 303 | cp "$MSG" "$SQUASH_MSG" |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 304 | ;; |
Johannes Schindelin | 6368f3f | 2007-07-21 18:09:41 +0100 | [diff] [blame] | 305 | *) |
| 306 | EDIT_COMMIT=-e |
Johannes Schindelin | 91e1ee7 | 2007-07-26 07:35:51 +0100 | [diff] [blame] | 307 | USE_OUTPUT= |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 308 | rm -f "$SQUASH_MSG" || exit |
| 309 | ;; |
Johannes Schindelin | 6368f3f | 2007-07-21 18:09:41 +0100 | [diff] [blame] | 310 | esac |
| 311 | |
Alex Riesen | 793ad04 | 2007-07-13 00:30:35 +0200 | [diff] [blame] | 312 | failed=f |
Johannes Schindelin | 81ab1cb | 2007-09-30 00:34:23 +0100 | [diff] [blame] | 313 | author_script=$(get_author_ident_from_commit HEAD) |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 314 | output git reset --soft HEAD^ |
Johannes Schindelin | fb47cfb | 2007-07-24 21:43:09 +0100 | [diff] [blame] | 315 | pick_one -n $sha1 || failed=t |
Johannes Schindelin | 18640d9 | 2007-07-08 03:01:29 +0100 | [diff] [blame] | 316 | echo "$author_script" > "$DOTEST"/author-script |
Shawn O. Pearce | dbedf97 | 2007-12-19 01:45:00 -0500 | [diff] [blame] | 317 | if test $failed = f |
| 318 | then |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 319 | # This is like --amend, but with a different message |
| 320 | eval "$author_script" |
Johannes Schindelin | ae830ed | 2007-09-25 16:43:44 +0100 | [diff] [blame] | 321 | GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" \ |
| 322 | GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \ |
| 323 | GIT_AUTHOR_DATE="$GIT_AUTHOR_DATE" \ |
Shawn O. Pearce | dbedf97 | 2007-12-19 01:45:00 -0500 | [diff] [blame] | 324 | $USE_OUTPUT git commit --no-verify -F "$MSG" $EDIT_COMMIT || failed=t |
| 325 | fi |
| 326 | if test $failed = t |
| 327 | then |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 328 | cp "$MSG" "$GIT_DIR"/MERGE_MSG |
| 329 | warn |
| 330 | warn "Could not apply $sha1... $rest" |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 331 | die_with_patch $sha1 "" |
Shawn O. Pearce | dbedf97 | 2007-12-19 01:45:00 -0500 | [diff] [blame] | 332 | fi |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 333 | ;; |
| 334 | *) |
| 335 | warn "Unknown command: $command $sha1 $rest" |
| 336 | die_with_patch $sha1 "Please fix this in the file $TODO." |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 337 | ;; |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 338 | esac |
| 339 | test -s "$TODO" && return |
| 340 | |
Johannes Schindelin | 68a163c | 2007-06-25 18:58:28 +0100 | [diff] [blame] | 341 | comment_for_reflog finish && |
| 342 | HEADNAME=$(cat "$DOTEST"/head-name) && |
| 343 | OLDHEAD=$(cat "$DOTEST"/head) && |
| 344 | SHORTONTO=$(git rev-parse --short $(cat "$DOTEST"/onto)) && |
Johannes Schindelin | 3b38ec1 | 2007-07-24 03:18:28 +0100 | [diff] [blame] | 345 | if test -d "$REWRITTEN" |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 346 | then |
| 347 | test -f "$DOTEST"/current-commit && |
| 348 | current_commit=$(cat "$DOTEST"/current-commit) && |
| 349 | git rev-parse HEAD > "$REWRITTEN"/$current_commit |
Johannes Schindelin | 34454e8 | 2007-12-17 21:01:25 +0000 | [diff] [blame] | 350 | if test -f "$REWRITTEN"/$OLDHEAD |
| 351 | then |
| 352 | NEWHEAD=$(cat "$REWRITTEN"/$OLDHEAD) |
| 353 | else |
| 354 | NEWHEAD=$OLDHEAD |
| 355 | fi |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 356 | else |
| 357 | NEWHEAD=$(git rev-parse HEAD) |
| 358 | fi && |
Johannes Schindelin | 73697a0 | 2007-09-25 16:43:15 +0100 | [diff] [blame] | 359 | case $HEADNAME in |
| 360 | refs/*) |
| 361 | message="$GIT_REFLOG_ACTION: $HEADNAME onto $SHORTONTO)" && |
| 362 | git update-ref -m "$message" $HEADNAME $NEWHEAD $OLDHEAD && |
| 363 | git symbolic-ref HEAD $HEADNAME |
| 364 | ;; |
| 365 | esac && { |
Johannes Schindelin | 3df0a85 | 2007-07-08 03:02:13 +0100 | [diff] [blame] | 366 | test ! -f "$DOTEST"/verbose || |
Johannes Schindelin | f3d5e46 | 2007-10-09 13:59:43 +0100 | [diff] [blame] | 367 | git diff-tree --stat $(cat "$DOTEST"/head)..HEAD |
Johannes Schindelin | 3df0a85 | 2007-07-08 03:02:13 +0100 | [diff] [blame] | 368 | } && |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 369 | rm -rf "$DOTEST" && |
Johannes Schindelin | 73697a0 | 2007-09-25 16:43:15 +0100 | [diff] [blame] | 370 | git gc --auto && |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 371 | warn "Successfully rebased and updated $HEADNAME." |
| 372 | |
| 373 | exit |
| 374 | } |
| 375 | |
| 376 | do_rest () { |
| 377 | while : |
| 378 | do |
| 379 | do_next |
| 380 | done |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 381 | } |
| 382 | |
Stephan Beyer | 7970aaf | 2008-07-12 17:48:20 +0200 | [diff] [blame] | 383 | # check if no other options are set |
| 384 | is_standalone () { |
| 385 | test $# -eq 2 -a "$2" = '--' && |
| 386 | test -z "$ONTO" && |
| 387 | test -z "$PRESERVE_MERGES" && |
| 388 | test -z "$STRATEGY" && |
| 389 | test -z "$VERBOSE" |
| 390 | } |
| 391 | |
| 392 | get_saved_options () { |
| 393 | test -d "$REWRITTEN" && PRESERVE_MERGES=t |
| 394 | test -f "$DOTEST"/strategy && STRATEGY="$(cat "$DOTEST"/strategy)" |
| 395 | test -f "$DOTEST"/verbose && VERBOSE=t |
| 396 | } |
| 397 | |
David Kastrup | 822f7c7 | 2007-09-23 22:42:08 +0200 | [diff] [blame] | 398 | while test $# != 0 |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 399 | do |
| 400 | case "$1" in |
| 401 | --continue) |
Stephan Beyer | 7970aaf | 2008-07-12 17:48:20 +0200 | [diff] [blame] | 402 | is_standalone "$@" || usage |
| 403 | get_saved_options |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 404 | comment_for_reflog continue |
| 405 | |
| 406 | test -d "$DOTEST" || die "No interactive rebase running" |
| 407 | |
Junio C Hamano | ab11903 | 2007-12-30 12:51:42 -0800 | [diff] [blame] | 408 | # Sanity check |
| 409 | git rev-parse --verify HEAD >/dev/null || |
| 410 | die "Cannot read HEAD" |
Johannes Schindelin | 6848d58 | 2008-05-14 18:03:59 +0100 | [diff] [blame] | 411 | git update-index --ignore-submodules --refresh && |
| 412 | git diff-files --quiet --ignore-submodules || |
Junio C Hamano | ab11903 | 2007-12-30 12:51:42 -0800 | [diff] [blame] | 413 | die "Working tree is dirty" |
| 414 | |
| 415 | # do we have anything to commit? |
Johannes Schindelin | 6848d58 | 2008-05-14 18:03:59 +0100 | [diff] [blame] | 416 | if git diff-index --cached --quiet --ignore-submodules HEAD -- |
Shawn O. Pearce | 0327062 | 2007-12-20 02:12:12 -0500 | [diff] [blame] | 417 | then |
Junio C Hamano | ab11903 | 2007-12-30 12:51:42 -0800 | [diff] [blame] | 418 | : Nothing to commit -- skip this |
| 419 | else |
| 420 | . "$DOTEST"/author-script || |
| 421 | die "Cannot find the author identity" |
| 422 | if test -f "$DOTEST"/amend |
| 423 | then |
| 424 | git reset --soft HEAD^ || |
| 425 | die "Cannot rewind the HEAD" |
| 426 | fi |
| 427 | export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE && |
| 428 | git commit --no-verify -F "$DOTEST"/message -e || |
Shawn O. Pearce | dbedf97 | 2007-12-19 01:45:00 -0500 | [diff] [blame] | 429 | die "Could not commit staged changes." |
Shawn O. Pearce | 0327062 | 2007-12-20 02:12:12 -0500 | [diff] [blame] | 430 | fi |
Johannes Schindelin | 18640d9 | 2007-07-08 03:01:29 +0100 | [diff] [blame] | 431 | |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 432 | require_clean_work_tree |
| 433 | do_rest |
| 434 | ;; |
| 435 | --abort) |
Stephan Beyer | 7970aaf | 2008-07-12 17:48:20 +0200 | [diff] [blame] | 436 | is_standalone "$@" || usage |
| 437 | get_saved_options |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 438 | comment_for_reflog abort |
| 439 | |
Johannes Schindelin | ecfe72f | 2007-11-22 11:18:10 +0000 | [diff] [blame] | 440 | git rerere clear |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 441 | test -d "$DOTEST" || die "No interactive rebase running" |
| 442 | |
| 443 | HEADNAME=$(cat "$DOTEST"/head-name) |
| 444 | HEAD=$(cat "$DOTEST"/head) |
Johannes Schindelin | 73697a0 | 2007-09-25 16:43:15 +0100 | [diff] [blame] | 445 | case $HEADNAME in |
| 446 | refs/*) |
| 447 | git symbolic-ref HEAD $HEADNAME |
| 448 | ;; |
| 449 | esac && |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 450 | output git reset --hard $HEAD && |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 451 | rm -rf "$DOTEST" |
| 452 | exit |
| 453 | ;; |
| 454 | --skip) |
Stephan Beyer | 7970aaf | 2008-07-12 17:48:20 +0200 | [diff] [blame] | 455 | is_standalone "$@" || usage |
| 456 | get_saved_options |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 457 | comment_for_reflog skip |
| 458 | |
Johannes Schindelin | ecfe72f | 2007-11-22 11:18:10 +0000 | [diff] [blame] | 459 | git rerere clear |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 460 | test -d "$DOTEST" || die "No interactive rebase running" |
| 461 | |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 462 | output git reset --hard && do_rest |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 463 | ;; |
Stephan Beyer | 7970aaf | 2008-07-12 17:48:20 +0200 | [diff] [blame] | 464 | -s) |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 465 | case "$#,$1" in |
| 466 | *,*=*) |
Ralf Wildenhues | b5e960b | 2007-11-08 22:47:36 +0100 | [diff] [blame] | 467 | STRATEGY="-s "$(expr "z$1" : 'z-[^=]*=\(.*\)') ;; |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 468 | 1,*) |
| 469 | usage ;; |
| 470 | *) |
| 471 | STRATEGY="-s $2" |
| 472 | shift ;; |
| 473 | esac |
| 474 | ;; |
Stephan Beyer | 7970aaf | 2008-07-12 17:48:20 +0200 | [diff] [blame] | 475 | -m) |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 476 | # we use merge anyway |
| 477 | ;; |
Stephan Beyer | 7970aaf | 2008-07-12 17:48:20 +0200 | [diff] [blame] | 478 | -v) |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 479 | VERBOSE=t |
| 480 | ;; |
Stephan Beyer | 7970aaf | 2008-07-12 17:48:20 +0200 | [diff] [blame] | 481 | -p) |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 482 | PRESERVE_MERGES=t |
| 483 | ;; |
Stephan Beyer | 7970aaf | 2008-07-12 17:48:20 +0200 | [diff] [blame] | 484 | -i) |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 485 | # yeah, we know |
| 486 | ;; |
Stephan Beyer | 7970aaf | 2008-07-12 17:48:20 +0200 | [diff] [blame] | 487 | --onto) |
| 488 | shift |
| 489 | ONTO=$(git rev-parse --verify "$1") || |
| 490 | die "Does not point to a valid commit: $1" |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 491 | ;; |
Stephan Beyer | 7970aaf | 2008-07-12 17:48:20 +0200 | [diff] [blame] | 492 | --) |
| 493 | shift |
| 494 | test $# -eq 1 -o $# -eq 2 || usage |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 495 | test -d "$DOTEST" && |
| 496 | die "Interactive rebase already started" |
| 497 | |
| 498 | git var GIT_COMMITTER_IDENT >/dev/null || |
| 499 | die "You need to set your committer info first" |
| 500 | |
| 501 | comment_for_reflog start |
| 502 | |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 503 | require_clean_work_tree |
| 504 | |
Johannes Sixt | 69e66f5 | 2008-06-02 16:01:40 +0200 | [diff] [blame] | 505 | UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base" |
| 506 | test -z "$ONTO" && ONTO=$UPSTREAM |
| 507 | |
Johannes Schindelin | 3b38ec1 | 2007-07-24 03:18:28 +0100 | [diff] [blame] | 508 | if test ! -z "$2" |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 509 | then |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 510 | output git show-ref --verify --quiet "refs/heads/$2" || |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 511 | die "Invalid branchname: $2" |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 512 | output git checkout "$2" || |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 513 | die "Could not checkout $2" |
| 514 | fi |
| 515 | |
| 516 | HEAD=$(git rev-parse --verify HEAD) || die "No HEAD?" |
Matt Kraai | 5166810 | 2007-09-25 18:30:13 -0700 | [diff] [blame] | 517 | mkdir "$DOTEST" || die "Could not create temporary $DOTEST" |
| 518 | |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 519 | : > "$DOTEST"/interactive || die "Could not mark as interactive" |
Johannes Schindelin | 73697a0 | 2007-09-25 16:43:15 +0100 | [diff] [blame] | 520 | git symbolic-ref HEAD > "$DOTEST"/head-name 2> /dev/null || |
| 521 | echo "detached HEAD" > "$DOTEST"/head-name |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 522 | |
| 523 | echo $HEAD > "$DOTEST"/head |
| 524 | echo $UPSTREAM > "$DOTEST"/upstream |
| 525 | echo $ONTO > "$DOTEST"/onto |
Johannes Schindelin | 8e4a91b | 2007-07-08 03:02:47 +0100 | [diff] [blame] | 526 | test -z "$STRATEGY" || echo "$STRATEGY" > "$DOTEST"/strategy |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 527 | test t = "$VERBOSE" && : > "$DOTEST"/verbose |
Johannes Schindelin | 3b38ec1 | 2007-07-24 03:18:28 +0100 | [diff] [blame] | 528 | if test t = "$PRESERVE_MERGES" |
Johannes Schindelin | f09c9b8 | 2007-06-25 18:59:43 +0100 | [diff] [blame] | 529 | then |
| 530 | # $REWRITTEN contains files for each commit that is |
| 531 | # reachable by at least one merge base of $HEAD and |
| 532 | # $UPSTREAM. They are not necessarily rewritten, but |
| 533 | # their children might be. |
| 534 | # This ensures that commits on merged, but otherwise |
| 535 | # unrelated side branches are left alone. (Think "X" |
| 536 | # in the man page's example.) |
| 537 | mkdir "$REWRITTEN" && |
| 538 | for c in $(git merge-base --all $HEAD $UPSTREAM) |
| 539 | do |
| 540 | echo $ONTO > "$REWRITTEN"/$c || |
| 541 | die "Could not init rewritten commits" |
| 542 | done |
| 543 | MERGES_OPTION= |
| 544 | else |
| 545 | MERGES_OPTION=--no-merges |
| 546 | fi |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 547 | |
Johannes Schindelin | c54b781 | 2007-06-25 18:56:55 +0100 | [diff] [blame] | 548 | SHORTUPSTREAM=$(git rev-parse --short $UPSTREAM) |
| 549 | SHORTHEAD=$(git rev-parse --short $HEAD) |
| 550 | SHORTONTO=$(git rev-parse --short $ONTO) |
Johannes Schindelin | 6047a23 | 2007-11-22 12:30:10 +0000 | [diff] [blame] | 551 | git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \ |
| 552 | --abbrev=7 --reverse --left-right --cherry-pick \ |
| 553 | $UPSTREAM...$HEAD | \ |
| 554 | sed -n "s/^>/pick /p" > "$TODO" |
| 555 | cat >> "$TODO" << EOF |
| 556 | |
| 557 | # Rebase $SHORTUPSTREAM..$SHORTHEAD onto $SHORTONTO |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 558 | # |
| 559 | # Commands: |
Miklos Vajna | 88b1f0b | 2008-06-07 18:20:19 +0200 | [diff] [blame] | 560 | # p, pick = use commit |
| 561 | # e, edit = use commit, but stop for amending |
| 562 | # s, squash = use commit, but meld into previous commit |
Johannes Schindelin | 82576dd | 2007-07-08 21:32:22 +0100 | [diff] [blame] | 563 | # |
| 564 | # If you remove a line here THAT COMMIT WILL BE LOST. |
Johannes Schindelin | 6047a23 | 2007-11-22 12:30:10 +0000 | [diff] [blame] | 565 | # However, if you remove everything, the rebase will be aborted. |
Johannes Schindelin | 82576dd | 2007-07-08 21:32:22 +0100 | [diff] [blame] | 566 | # |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 567 | EOF |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 568 | |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 569 | has_action "$TODO" || |
Johannes Schindelin | c54b781 | 2007-06-25 18:56:55 +0100 | [diff] [blame] | 570 | die_abort "Nothing to do" |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 571 | |
| 572 | cp "$TODO" "$TODO".backup |
Adam Roben | ef0c2ab | 2007-07-19 22:09:35 -0700 | [diff] [blame] | 573 | git_editor "$TODO" || |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 574 | die "Could not execute editor" |
| 575 | |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 576 | has_action "$TODO" || |
Johannes Schindelin | c54b781 | 2007-06-25 18:56:55 +0100 | [diff] [blame] | 577 | die_abort "Nothing to do" |
| 578 | |
Junio C Hamano | 22e4079 | 2008-07-07 00:16:38 -0700 | [diff] [blame] | 579 | git update-ref ORIG_HEAD $HEAD |
Johannes Schindelin | dfa49f3 | 2007-07-23 23:45:49 +0100 | [diff] [blame] | 580 | output git checkout $ONTO && do_rest |
Johannes Schindelin | 376ccb8 | 2007-09-25 16:42:51 +0100 | [diff] [blame] | 581 | ;; |
Johannes Schindelin | 1b1dce4 | 2007-06-25 01:11:14 +0100 | [diff] [blame] | 582 | esac |
| 583 | shift |
| 584 | done |