Merge branch 'tb/t0050-maint'
[git] / git-rebase--interactive.sh
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 #
13 # The file containing rebase commands, comments, and empty lines.
14 # This file is created by "git rebase -i" then edited by the user.  As
15 # the lines are processed, they are removed from the front of this
16 # file and written to the tail of $done.
17 todo="$state_dir"/git-rebase-todo
18
19 # The rebase command lines that have already been processed.  A line
20 # is moved here when it is first handled, before any associated user
21 # actions.
22 done="$state_dir"/done
23
24 # The commit message that is planned to be used for any changes that
25 # need to be committed following a user interaction.
26 msg="$state_dir"/message
27
28 # The file into which is accumulated the suggested commit message for
29 # squash/fixup commands.  When the first of a series of squash/fixups
30 # is seen, the file is created and the commit message from the
31 # previous commit and from the first squash/fixup commit are written
32 # to it.  The commit message for each subsequent squash/fixup commit
33 # is appended to the file as it is processed.
34 #
35 # The first line of the file is of the form
36 #     # This is a combination of $count commits.
37 # where $count is the number of commits whose messages have been
38 # written to the file so far (including the initial "pick" commit).
39 # Each time that a commit message is processed, this line is read and
40 # updated.  It is deleted just before the combined commit is made.
41 squash_msg="$state_dir"/message-squash
42
43 # If the current series of squash/fixups has not yet included a squash
44 # command, then this file exists and holds the commit message of the
45 # original "pick" commit.  (If the series ends without a "squash"
46 # command, then this can be used as the commit message of the combined
47 # commit without opening the editor.)
48 fixup_msg="$state_dir"/message-fixup
49
50 # $rewritten is the name of a directory containing files for each
51 # commit that is reachable by at least one merge base of $head and
52 # $upstream. They are not necessarily rewritten, but their children
53 # might be.  This ensures that commits on merged, but otherwise
54 # unrelated side branches are left alone. (Think "X" in the man page's
55 # example.)
56 rewritten="$state_dir"/rewritten
57
58 dropped="$state_dir"/dropped
59
60 # A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
61 # GIT_AUTHOR_DATE that will be used for the commit that is currently
62 # being rebased.
63 author_script="$state_dir"/author-script
64
65 # When an "edit" rebase command is being processed, the SHA1 of the
66 # commit to be edited is recorded in this file.  When "git rebase
67 # --continue" is executed, if there are any staged changes then they
68 # will be amended to the HEAD commit, but only provided the HEAD
69 # commit is still the commit to be edited.  When any other rebase
70 # command is processed, this file is deleted.
71 amend="$state_dir"/amend
72
73 # For the post-rewrite hook, we make a list of rewritten commits and
74 # their new sha1s.  The rewritten-pending list keeps the sha1s of
75 # commits that have been processed, but not committed yet,
76 # e.g. because they are waiting for a 'squash' command.
77 rewritten_list="$state_dir"/rewritten-list
78 rewritten_pending="$state_dir"/rewritten-pending
79
80 GIT_CHERRY_PICK_HELP="$resolvemsg"
81 export GIT_CHERRY_PICK_HELP
82
83 warn () {
84         printf '%s\n' "$*" >&2
85 }
86
87 # Output the commit message for the specified commit.
88 commit_message () {
89         git cat-file commit "$1" | sed "1,/^$/d"
90 }
91
92 orig_reflog_action="$GIT_REFLOG_ACTION"
93
94 comment_for_reflog () {
95         case "$orig_reflog_action" in
96         ''|rebase*)
97                 GIT_REFLOG_ACTION="rebase -i ($1)"
98                 export GIT_REFLOG_ACTION
99                 ;;
100         esac
101 }
102
103 last_count=
104 mark_action_done () {
105         sed -e 1q < "$todo" >> "$done"
106         sed -e 1d < "$todo" >> "$todo".new
107         mv -f "$todo".new "$todo"
108         new_count=$(sane_grep -c '^[^#]' < "$done")
109         total=$(($new_count+$(sane_grep -c '^[^#]' < "$todo")))
110         if test "$last_count" != "$new_count"
111         then
112                 last_count=$new_count
113                 printf "Rebasing (%d/%d)\r" $new_count $total
114                 test -z "$verbose" || echo
115         fi
116 }
117
118 append_todo_help () {
119         cat >> "$todo" << EOF
120 #
121 # Commands:
122 #  p, pick = use commit
123 #  r, reword = use commit, but edit the commit message
124 #  e, edit = use commit, but stop for amending
125 #  s, squash = use commit, but meld into previous commit
126 #  f, fixup = like "squash", but discard this commit's log message
127 #  x, exec = run command (the rest of the line) using shell
128 #
129 # These lines can be re-ordered; they are executed from top to bottom.
130 #
131 # If you remove a line here THAT COMMIT WILL BE LOST.
132 EOF
133 }
134
135 make_patch () {
136         sha1_and_parents="$(git rev-list --parents -1 "$1")"
137         case "$sha1_and_parents" in
138         ?*' '?*' '?*)
139                 git diff --cc $sha1_and_parents
140                 ;;
141         ?*' '?*)
142                 git diff-tree -p "$1^!"
143                 ;;
144         *)
145                 echo "Root commit"
146                 ;;
147         esac > "$state_dir"/patch
148         test -f "$msg" ||
149                 commit_message "$1" > "$msg"
150         test -f "$author_script" ||
151                 get_author_ident_from_commit "$1" > "$author_script"
152 }
153
154 die_with_patch () {
155         echo "$1" > "$state_dir"/stopped-sha
156         make_patch "$1"
157         git rerere
158         die "$2"
159 }
160
161 exit_with_patch () {
162         echo "$1" > "$state_dir"/stopped-sha
163         make_patch $1
164         git rev-parse --verify HEAD > "$amend"
165         warn "You can amend the commit now, with"
166         warn
167         warn "  git commit --amend"
168         warn
169         warn "Once you are satisfied with your changes, run"
170         warn
171         warn "  git rebase --continue"
172         warn
173         exit $2
174 }
175
176 die_abort () {
177         rm -rf "$state_dir"
178         die "$1"
179 }
180
181 has_action () {
182         sane_grep '^[^#]' "$1" >/dev/null
183 }
184
185 is_empty_commit() {
186         tree=$(git rev-parse -q --verify "$1"^{tree} 2>/dev/null ||
187                 die "$1: not a commit that can be picked")
188         ptree=$(git rev-parse -q --verify "$1"^^{tree} 2>/dev/null ||
189                 ptree=4b825dc642cb6eb9a060e54bf8d69288fbee4904)
190         test "$tree" = "$ptree"
191 }
192
193 is_merge_commit()
194 {
195         git rev-parse --verify --quiet "$1"^2 >/dev/null 2>&1
196 }
197
198 # Run command with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
199 # GIT_AUTHOR_DATE exported from the current environment.
200 do_with_author () {
201         (
202                 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
203                 "$@"
204         )
205 }
206
207 git_sequence_editor () {
208         if test -z "$GIT_SEQUENCE_EDITOR"
209         then
210                 GIT_SEQUENCE_EDITOR="$(git config sequence.editor)"
211                 if [ -z "$GIT_SEQUENCE_EDITOR" ]
212                 then
213                         GIT_SEQUENCE_EDITOR="$(git var GIT_EDITOR)" || return $?
214                 fi
215         fi
216
217         eval "$GIT_SEQUENCE_EDITOR" '"$@"'
218 }
219
220 pick_one () {
221         ff=--ff
222
223         case "$1" in -n) sha1=$2; ff= ;; *) sha1=$1 ;; esac
224         case "$force_rebase" in '') ;; ?*) ff= ;; esac
225         output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
226
227         if is_empty_commit "$sha1"
228         then
229                 empty_args="--allow-empty"
230         fi
231
232         test -d "$rewritten" &&
233                 pick_one_preserving_merges "$@" && return
234         output git cherry-pick $empty_args $ff "$@"
235 }
236
237 pick_one_preserving_merges () {
238         fast_forward=t
239         case "$1" in
240         -n)
241                 fast_forward=f
242                 sha1=$2
243                 ;;
244         *)
245                 sha1=$1
246                 ;;
247         esac
248         sha1=$(git rev-parse $sha1)
249
250         if test -f "$state_dir"/current-commit
251         then
252                 if test "$fast_forward" = t
253                 then
254                         while read current_commit
255                         do
256                                 git rev-parse HEAD > "$rewritten"/$current_commit
257                         done <"$state_dir"/current-commit
258                         rm "$state_dir"/current-commit ||
259                         die "Cannot write current commit's replacement sha1"
260                 fi
261         fi
262
263         echo $sha1 >> "$state_dir"/current-commit
264
265         # rewrite parents; if none were rewritten, we can fast-forward.
266         new_parents=
267         pend=" $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)"
268         if test "$pend" = " "
269         then
270                 pend=" root"
271         fi
272         while [ "$pend" != "" ]
273         do
274                 p=$(expr "$pend" : ' \([^ ]*\)')
275                 pend="${pend# $p}"
276
277                 if test -f "$rewritten"/$p
278                 then
279                         new_p=$(cat "$rewritten"/$p)
280
281                         # If the todo reordered commits, and our parent is marked for
282                         # rewriting, but hasn't been gotten to yet, assume the user meant to
283                         # drop it on top of the current HEAD
284                         if test -z "$new_p"
285                         then
286                                 new_p=$(git rev-parse HEAD)
287                         fi
288
289                         test $p != $new_p && fast_forward=f
290                         case "$new_parents" in
291                         *$new_p*)
292                                 ;; # do nothing; that parent is already there
293                         *)
294                                 new_parents="$new_parents $new_p"
295                                 ;;
296                         esac
297                 else
298                         if test -f "$dropped"/$p
299                         then
300                                 fast_forward=f
301                                 replacement="$(cat "$dropped"/$p)"
302                                 test -z "$replacement" && replacement=root
303                                 pend=" $replacement$pend"
304                         else
305                                 new_parents="$new_parents $p"
306                         fi
307                 fi
308         done
309         case $fast_forward in
310         t)
311                 output warn "Fast-forward to $sha1"
312                 output git reset --hard $sha1 ||
313                         die "Cannot fast-forward to $sha1"
314                 ;;
315         f)
316                 first_parent=$(expr "$new_parents" : ' \([^ ]*\)')
317
318                 if [ "$1" != "-n" ]
319                 then
320                         # detach HEAD to current parent
321                         output git checkout $first_parent 2> /dev/null ||
322                                 die "Cannot move HEAD to $first_parent"
323                 fi
324
325                 case "$new_parents" in
326                 ' '*' '*)
327                         test "a$1" = a-n && die "Refusing to squash a merge: $sha1"
328
329                         # redo merge
330                         author_script_content=$(get_author_ident_from_commit $sha1)
331                         eval "$author_script_content"
332                         msg_content="$(commit_message $sha1)"
333                         # No point in merging the first parent, that's HEAD
334                         new_parents=${new_parents# $first_parent}
335                         if ! do_with_author output \
336                                 git merge --no-ff ${strategy:+-s $strategy} -m \
337                                         "$msg_content" $new_parents
338                         then
339                                 printf "%s\n" "$msg_content" > "$GIT_DIR"/MERGE_MSG
340                                 die_with_patch $sha1 "Error redoing merge $sha1"
341                         fi
342                         echo "$sha1 $(git rev-parse HEAD^0)" >> "$rewritten_list"
343                         ;;
344                 *)
345                         output git cherry-pick "$@" ||
346                                 die_with_patch $sha1 "Could not pick $sha1"
347                         ;;
348                 esac
349                 ;;
350         esac
351 }
352
353 nth_string () {
354         case "$1" in
355         *1[0-9]|*[04-9]) echo "$1"th;;
356         *1) echo "$1"st;;
357         *2) echo "$1"nd;;
358         *3) echo "$1"rd;;
359         esac
360 }
361
362 update_squash_messages () {
363         if test -f "$squash_msg"; then
364                 mv "$squash_msg" "$squash_msg".bak || exit
365                 count=$(($(sed -n \
366                         -e "1s/^# This is a combination of \(.*\) commits\./\1/p" \
367                         -e "q" < "$squash_msg".bak)+1))
368                 {
369                         echo "# This is a combination of $count commits."
370                         sed -e 1d -e '2,/^./{
371                                 /^$/d
372                         }' <"$squash_msg".bak
373                 } >"$squash_msg"
374         else
375                 commit_message HEAD > "$fixup_msg" || die "Cannot write $fixup_msg"
376                 count=2
377                 {
378                         echo "# This is a combination of 2 commits."
379                         echo "# The first commit's message is:"
380                         echo
381                         cat "$fixup_msg"
382                 } >"$squash_msg"
383         fi
384         case $1 in
385         squash)
386                 rm -f "$fixup_msg"
387                 echo
388                 echo "# This is the $(nth_string $count) commit message:"
389                 echo
390                 commit_message $2
391                 ;;
392         fixup)
393                 echo
394                 echo "# The $(nth_string $count) commit message will be skipped:"
395                 echo
396                 commit_message $2 | sed -e 's/^/#       /'
397                 ;;
398         esac >>"$squash_msg"
399 }
400
401 peek_next_command () {
402         sed -n -e "/^#/d" -e '/^$/d' -e "s/ .*//p" -e "q" < "$todo"
403 }
404
405 # A squash/fixup has failed.  Prepare the long version of the squash
406 # commit message, then die_with_patch.  This code path requires the
407 # user to edit the combined commit message for all commits that have
408 # been squashed/fixedup so far.  So also erase the old squash
409 # messages, effectively causing the combined commit to be used as the
410 # new basis for any further squash/fixups.  Args: sha1 rest
411 die_failed_squash() {
412         mv "$squash_msg" "$msg" || exit
413         rm -f "$fixup_msg"
414         cp "$msg" "$GIT_DIR"/MERGE_MSG || exit
415         warn
416         warn "Could not apply $1... $2"
417         die_with_patch $1 ""
418 }
419
420 flush_rewritten_pending() {
421         test -s "$rewritten_pending" || return
422         newsha1="$(git rev-parse HEAD^0)"
423         sed "s/$/ $newsha1/" < "$rewritten_pending" >> "$rewritten_list"
424         rm -f "$rewritten_pending"
425 }
426
427 record_in_rewritten() {
428         oldsha1="$(git rev-parse $1)"
429         echo "$oldsha1" >> "$rewritten_pending"
430
431         case "$(peek_next_command)" in
432         squash|s|fixup|f)
433                 ;;
434         *)
435                 flush_rewritten_pending
436                 ;;
437         esac
438 }
439
440 do_pick () {
441         if test "$(git rev-parse HEAD)" = "$squash_onto"
442         then
443                 # Set the correct commit message and author info on the
444                 # sentinel root before cherry-picking the original changes
445                 # without committing (-n).  Finally, update the sentinel again
446                 # to include these changes.  If the cherry-pick results in a
447                 # conflict, this means our behaviour is similar to a standard
448                 # failed cherry-pick during rebase, with a dirty index to
449                 # resolve before manually running git commit --amend then git
450                 # rebase --continue.
451                 git commit --allow-empty --allow-empty-message --amend \
452                            --no-post-rewrite -n -q -C $1 &&
453                         pick_one -n $1 &&
454                         git commit --allow-empty --allow-empty-message \
455                                    --amend --no-post-rewrite -n -q -C $1 ||
456                         die_with_patch $1 "Could not apply $1... $2"
457         else
458                 pick_one $1 ||
459                         die_with_patch $1 "Could not apply $1... $2"
460         fi
461 }
462
463 do_next () {
464         rm -f "$msg" "$author_script" "$amend" || exit
465         read -r command sha1 rest < "$todo"
466         case "$command" in
467         '#'*|''|noop)
468                 mark_action_done
469                 ;;
470         pick|p)
471                 comment_for_reflog pick
472
473                 mark_action_done
474                 do_pick $sha1 "$rest"
475                 record_in_rewritten $sha1
476                 ;;
477         reword|r)
478                 comment_for_reflog reword
479
480                 mark_action_done
481                 do_pick $sha1 "$rest"
482                 git commit --amend --no-post-rewrite || {
483                         warn "Could not amend commit after successfully picking $sha1... $rest"
484                         warn "This is most likely due to an empty commit message, or the pre-commit hook"
485                         warn "failed. If the pre-commit hook failed, you may need to resolve the issue before"
486                         warn "you are able to reword the commit."
487                         exit_with_patch $sha1 1
488                 }
489                 record_in_rewritten $sha1
490                 ;;
491         edit|e)
492                 comment_for_reflog edit
493
494                 mark_action_done
495                 do_pick $sha1 "$rest"
496                 warn "Stopped at $sha1... $rest"
497                 exit_with_patch $sha1 0
498                 ;;
499         squash|s|fixup|f)
500                 case "$command" in
501                 squash|s)
502                         squash_style=squash
503                         ;;
504                 fixup|f)
505                         squash_style=fixup
506                         ;;
507                 esac
508                 comment_for_reflog $squash_style
509
510                 test -f "$done" && has_action "$done" ||
511                         die "Cannot '$squash_style' without a previous commit"
512
513                 mark_action_done
514                 update_squash_messages $squash_style $sha1
515                 author_script_content=$(get_author_ident_from_commit HEAD)
516                 echo "$author_script_content" > "$author_script"
517                 eval "$author_script_content"
518                 if ! pick_one -n $sha1
519                 then
520                         git rev-parse --verify HEAD >"$amend"
521                         die_failed_squash $sha1 "$rest"
522                 fi
523                 case "$(peek_next_command)" in
524                 squash|s|fixup|f)
525                         # This is an intermediate commit; its message will only be
526                         # used in case of trouble.  So use the long version:
527                         do_with_author output git commit --amend --no-verify -F "$squash_msg" ||
528                                 die_failed_squash $sha1 "$rest"
529                         ;;
530                 *)
531                         # This is the final command of this squash/fixup group
532                         if test -f "$fixup_msg"
533                         then
534                                 do_with_author git commit --amend --no-verify -F "$fixup_msg" ||
535                                         die_failed_squash $sha1 "$rest"
536                         else
537                                 cp "$squash_msg" "$GIT_DIR"/SQUASH_MSG || exit
538                                 rm -f "$GIT_DIR"/MERGE_MSG
539                                 do_with_author git commit --amend --no-verify -F "$GIT_DIR"/SQUASH_MSG -e ||
540                                         die_failed_squash $sha1 "$rest"
541                         fi
542                         rm -f "$squash_msg" "$fixup_msg"
543                         ;;
544                 esac
545                 record_in_rewritten $sha1
546                 ;;
547         x|"exec")
548                 read -r command rest < "$todo"
549                 mark_action_done
550                 printf 'Executing: %s\n' "$rest"
551                 # "exec" command doesn't take a sha1 in the todo-list.
552                 # => can't just use $sha1 here.
553                 git rev-parse --verify HEAD > "$state_dir"/stopped-sha
554                 ${SHELL:-@SHELL_PATH@} -c "$rest" # Actual execution
555                 status=$?
556                 # Run in subshell because require_clean_work_tree can die.
557                 dirty=f
558                 (require_clean_work_tree "rebase" 2>/dev/null) || dirty=t
559                 if test "$status" -ne 0
560                 then
561                         warn "Execution failed: $rest"
562                         test "$dirty" = f ||
563                         warn "and made changes to the index and/or the working tree"
564
565                         warn "You can fix the problem, and then run"
566                         warn
567                         warn "  git rebase --continue"
568                         warn
569                         if test $status -eq 127         # command not found
570                         then
571                                 status=1
572                         fi
573                         exit "$status"
574                 elif test "$dirty" = t
575                 then
576                         warn "Execution succeeded: $rest"
577                         warn "but left changes to the index and/or the working tree"
578                         warn "Commit or stash your changes, and then run"
579                         warn
580                         warn "  git rebase --continue"
581                         warn
582                         exit 1
583                 fi
584                 ;;
585         *)
586                 warn "Unknown command: $command $sha1 $rest"
587                 fixtodo="Please fix this using 'git rebase --edit-todo'."
588                 if git rev-parse --verify -q "$sha1" >/dev/null
589                 then
590                         die_with_patch $sha1 "$fixtodo"
591                 else
592                         die "$fixtodo"
593                 fi
594                 ;;
595         esac
596         test -s "$todo" && return
597
598         comment_for_reflog finish &&
599         newhead=$(git rev-parse HEAD) &&
600         case $head_name in
601         refs/*)
602                 message="$GIT_REFLOG_ACTION: $head_name onto $onto" &&
603                 git update-ref -m "$message" $head_name $newhead $orig_head &&
604                 git symbolic-ref \
605                   -m "$GIT_REFLOG_ACTION: returning to $head_name" \
606                   HEAD $head_name
607                 ;;
608         esac && {
609                 test ! -f "$state_dir"/verbose ||
610                         git diff-tree --stat $orig_head..HEAD
611         } &&
612         {
613                 test -s "$rewritten_list" &&
614                 git notes copy --for-rewrite=rebase < "$rewritten_list" ||
615                 true # we don't care if this copying failed
616         } &&
617         if test -x "$GIT_DIR"/hooks/post-rewrite &&
618                 test -s "$rewritten_list"; then
619                 "$GIT_DIR"/hooks/post-rewrite rebase < "$rewritten_list"
620                 true # we don't care if this hook failed
621         fi &&
622         rm -rf "$state_dir" &&
623         git gc --auto &&
624         warn "Successfully rebased and updated $head_name."
625
626         exit
627 }
628
629 do_rest () {
630         while :
631         do
632                 do_next
633         done
634 }
635
636 # skip picking commits whose parents are unchanged
637 skip_unnecessary_picks () {
638         fd=3
639         while read -r command rest
640         do
641                 # fd=3 means we skip the command
642                 case "$fd,$command" in
643                 3,pick|3,p)
644                         # pick a commit whose parent is current $onto -> skip
645                         sha1=${rest%% *}
646                         case "$(git rev-parse --verify --quiet "$sha1"^)" in
647                         "$onto"*)
648                                 onto=$sha1
649                                 ;;
650                         *)
651                                 fd=1
652                                 ;;
653                         esac
654                         ;;
655                 3,#*|3,)
656                         # copy comments
657                         ;;
658                 *)
659                         fd=1
660                         ;;
661                 esac
662                 printf '%s\n' "$command${rest:+ }$rest" >&$fd
663         done <"$todo" >"$todo.new" 3>>"$done" &&
664         mv -f "$todo".new "$todo" &&
665         case "$(peek_next_command)" in
666         squash|s|fixup|f)
667                 record_in_rewritten "$onto"
668                 ;;
669         esac ||
670         die "Could not skip unnecessary pick commands"
671 }
672
673 # Rearrange the todo list that has both "pick sha1 msg" and
674 # "pick sha1 fixup!/squash! msg" appears in it so that the latter
675 # comes immediately after the former, and change "pick" to
676 # "fixup"/"squash".
677 rearrange_squash () {
678         # extract fixup!/squash! lines and resolve any referenced sha1's
679         while read -r pick sha1 message
680         do
681                 case "$message" in
682                 "squash! "*|"fixup! "*)
683                         action="${message%%!*}"
684                         rest="${message#*! }"
685                         echo "$sha1 $action $rest"
686                         # if it's a single word, try to resolve to a full sha1 and
687                         # emit a second copy. This allows us to match on both message
688                         # and on sha1 prefix
689                         if test "${rest#* }" = "$rest"; then
690                                 fullsha="$(git rev-parse -q --verify "$rest" 2>/dev/null)"
691                                 if test -n "$fullsha"; then
692                                         # prefix the action to uniquely identify this line as
693                                         # intended for full sha1 match
694                                         echo "$sha1 +$action $fullsha"
695                                 fi
696                         fi
697                 esac
698         done >"$1.sq" <"$1"
699         test -s "$1.sq" || return
700
701         used=
702         while read -r pick sha1 message
703         do
704                 case " $used" in
705                 *" $sha1 "*) continue ;;
706                 esac
707                 printf '%s\n' "$pick $sha1 $message"
708                 used="$used$sha1 "
709                 while read -r squash action msg_content
710                 do
711                         case " $used" in
712                         *" $squash "*) continue ;;
713                         esac
714                         emit=0
715                         case "$action" in
716                         +*)
717                                 action="${action#+}"
718                                 # full sha1 prefix test
719                                 case "$msg_content" in "$sha1"*) emit=1;; esac ;;
720                         *)
721                                 # message prefix test
722                                 case "$message" in "$msg_content"*) emit=1;; esac ;;
723                         esac
724                         if test $emit = 1; then
725                                 printf '%s\n' "$action $squash $action! $msg_content"
726                                 used="$used$squash "
727                         fi
728                 done <"$1.sq"
729         done >"$1.rearranged" <"$1"
730         cat "$1.rearranged" >"$1"
731         rm -f "$1.sq" "$1.rearranged"
732 }
733
734 # Add commands after a pick or after a squash/fixup serie
735 # in the todo list.
736 add_exec_commands () {
737         {
738                 first=t
739                 while read -r insn rest
740                 do
741                         case $insn in
742                         pick)
743                                 test -n "$first" ||
744                                 printf "%s" "$cmd"
745                                 ;;
746                         esac
747                         printf "%s %s\n" "$insn" "$rest"
748                         first=
749                 done
750                 printf "%s" "$cmd"
751         } <"$1" >"$1.new" &&
752         mv "$1.new" "$1"
753 }
754
755 case "$action" in
756 continue)
757         # do we have anything to commit?
758         if git diff-index --cached --quiet HEAD --
759         then
760                 : Nothing to commit -- skip this
761         else
762                 if ! test -f "$author_script"
763                 then
764                         die "You have staged changes in your working tree. If these changes are meant to be
765 squashed into the previous commit, run:
766
767   git commit --amend
768
769 If they are meant to go into a new commit, run:
770
771   git commit
772
773 In both case, once you're done, continue with:
774
775   git rebase --continue
776 "
777                 fi
778                 . "$author_script" ||
779                         die "Error trying to find the author identity to amend commit"
780                 if test -f "$amend"
781                 then
782                         current_head=$(git rev-parse --verify HEAD)
783                         test "$current_head" = $(cat "$amend") ||
784                         die "\
785 You have uncommitted changes in your working tree. Please, commit them
786 first and then run 'git rebase --continue' again."
787                         do_with_author git commit --amend --no-verify -F "$msg" -e ||
788                                 die "Could not commit staged changes."
789                 else
790                         do_with_author git commit --no-verify -F "$msg" -e ||
791                                 die "Could not commit staged changes."
792                 fi
793         fi
794
795         record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
796
797         require_clean_work_tree "rebase"
798         do_rest
799         ;;
800 skip)
801         git rerere clear
802
803         do_rest
804         ;;
805 edit-todo)
806         sed -e '/^#/d' < "$todo" > "$todo".new
807         mv -f "$todo".new "$todo"
808         append_todo_help
809         cat >> "$todo" << EOF
810 #
811 # You are editing the todo file of an ongoing interactive rebase.
812 # To continue rebase after editing, run:
813 #     git rebase --continue
814 #
815 EOF
816
817         git_sequence_editor "$todo" ||
818                 die "Could not execute editor"
819
820         exit
821         ;;
822 esac
823
824 git var GIT_COMMITTER_IDENT >/dev/null ||
825         die "You need to set your committer info first"
826
827 comment_for_reflog start
828
829 if test ! -z "$switch_to"
830 then
831         output git checkout "$switch_to" -- ||
832                 die "Could not checkout $switch_to"
833 fi
834
835 orig_head=$(git rev-parse --verify HEAD) || die "No HEAD?"
836 mkdir "$state_dir" || die "Could not create temporary $state_dir"
837
838 : > "$state_dir"/interactive || die "Could not mark as interactive"
839 write_basic_state
840 if test t = "$preserve_merges"
841 then
842         if test -z "$rebase_root"
843         then
844                 mkdir "$rewritten" &&
845                 for c in $(git merge-base --all $orig_head $upstream)
846                 do
847                         echo $onto > "$rewritten"/$c ||
848                                 die "Could not init rewritten commits"
849                 done
850         else
851                 mkdir "$rewritten" &&
852                 echo $onto > "$rewritten"/root ||
853                         die "Could not init rewritten commits"
854         fi
855         # No cherry-pick because our first pass is to determine
856         # parents to rewrite and skipping dropped commits would
857         # prematurely end our probe
858         merges_option=
859 else
860         merges_option="--no-merges --cherry-pick"
861 fi
862
863 shorthead=$(git rev-parse --short $orig_head)
864 shortonto=$(git rev-parse --short $onto)
865 if test -z "$rebase_root"
866         # this is now equivalent to ! -z "$upstream"
867 then
868         shortupstream=$(git rev-parse --short $upstream)
869         revisions=$upstream...$orig_head
870         shortrevisions=$shortupstream..$shorthead
871 else
872         revisions=$onto...$orig_head
873         shortrevisions=$shorthead
874 fi
875 git rev-list $merges_option --pretty=oneline --abbrev-commit \
876         --abbrev=7 --reverse --left-right --topo-order \
877         $revisions | \
878         sed -n "s/^>//p" |
879 while read -r shortsha1 rest
880 do
881
882         if test -z "$keep_empty" && is_empty_commit $shortsha1 && ! is_merge_commit $shortsha1
883         then
884                 comment_out="# "
885         else
886                 comment_out=
887         fi
888
889         if test t != "$preserve_merges"
890         then
891                 printf '%s\n' "${comment_out}pick $shortsha1 $rest" >>"$todo"
892         else
893                 sha1=$(git rev-parse $shortsha1)
894                 if test -z "$rebase_root"
895                 then
896                         preserve=t
897                         for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
898                         do
899                                 if test -f "$rewritten"/$p
900                                 then
901                                         preserve=f
902                                 fi
903                         done
904                 else
905                         preserve=f
906                 fi
907                 if test f = "$preserve"
908                 then
909                         touch "$rewritten"/$sha1
910                         printf '%s\n' "${comment_out}pick $shortsha1 $rest" >>"$todo"
911                 fi
912         fi
913 done
914
915 # Watch for commits that been dropped by --cherry-pick
916 if test t = "$preserve_merges"
917 then
918         mkdir "$dropped"
919         # Save all non-cherry-picked changes
920         git rev-list $revisions --left-right --cherry-pick | \
921                 sed -n "s/^>//p" > "$state_dir"/not-cherry-picks
922         # Now all commits and note which ones are missing in
923         # not-cherry-picks and hence being dropped
924         git rev-list $revisions |
925         while read rev
926         do
927                 if test -f "$rewritten"/$rev -a "$(sane_grep "$rev" "$state_dir"/not-cherry-picks)" = ""
928                 then
929                         # Use -f2 because if rev-list is telling us this commit is
930                         # not worthwhile, we don't want to track its multiple heads,
931                         # just the history of its first-parent for others that will
932                         # be rebasing on top of it
933                         git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$dropped"/$rev
934                         short=$(git rev-list -1 --abbrev-commit --abbrev=7 $rev)
935                         sane_grep -v "^[a-z][a-z]* $short" <"$todo" > "${todo}2" ; mv "${todo}2" "$todo"
936                         rm "$rewritten"/$rev
937                 fi
938         done
939 fi
940
941 test -s "$todo" || echo noop >> "$todo"
942 test -n "$autosquash" && rearrange_squash "$todo"
943 test -n "$cmd" && add_exec_commands "$todo"
944
945 cat >> "$todo" << EOF
946
947 # Rebase $shortrevisions onto $shortonto
948 EOF
949 append_todo_help
950 cat >> "$todo" << EOF
951 #
952 # However, if you remove everything, the rebase will be aborted.
953 #
954 EOF
955
956 if test -z "$keep_empty"
957 then
958         echo "# Note that empty commits are commented out" >>"$todo"
959 fi
960
961
962 has_action "$todo" ||
963         die_abort "Nothing to do"
964
965 cp "$todo" "$todo".backup
966 git_sequence_editor "$todo" ||
967         die_abort "Could not execute editor"
968
969 has_action "$todo" ||
970         die_abort "Nothing to do"
971
972 test -d "$rewritten" || test -n "$force_rebase" || skip_unnecessary_picks
973
974 output git checkout $onto || die_abort "could not detach HEAD"
975 git update-ref ORIG_HEAD $orig_head
976 do_rest