git-rebase: extend --signoff support
[git] / git-rebase--interactive.sh
1 # This shell script fragment is sourced by git-rebase to implement
2 # its interactive mode.  "git rebase --interactive" makes it easy
3 # to fix up commits in the middle of a series and rearrange commits.
4 #
5 # Copyright (c) 2006 Johannes E. Schindelin
6 #
7 # The original idea comes from Eric W. Biederman, in
8 # http://article.gmane.org/gmane.comp.version-control.git/22407
9 #
10 # The file containing rebase commands, comments, and empty lines.
11 # This file is created by "git rebase -i" then edited by the user.  As
12 # the lines are processed, they are removed from the front of this
13 # file and written to the tail of $done.
14 todo="$state_dir"/git-rebase-todo
15
16 # The rebase command lines that have already been processed.  A line
17 # is moved here when it is first handled, before any associated user
18 # actions.
19 done="$state_dir"/done
20
21 # The commit message that is planned to be used for any changes that
22 # need to be committed following a user interaction.
23 msg="$state_dir"/message
24
25 # The file into which is accumulated the suggested commit message for
26 # squash/fixup commands.  When the first of a series of squash/fixups
27 # is seen, the file is created and the commit message from the
28 # previous commit and from the first squash/fixup commit are written
29 # to it.  The commit message for each subsequent squash/fixup commit
30 # is appended to the file as it is processed.
31 #
32 # The first line of the file is of the form
33 #     # This is a combination of $count commits.
34 # where $count is the number of commits whose messages have been
35 # written to the file so far (including the initial "pick" commit).
36 # Each time that a commit message is processed, this line is read and
37 # updated.  It is deleted just before the combined commit is made.
38 squash_msg="$state_dir"/message-squash
39
40 # If the current series of squash/fixups has not yet included a squash
41 # command, then this file exists and holds the commit message of the
42 # original "pick" commit.  (If the series ends without a "squash"
43 # command, then this can be used as the commit message of the combined
44 # commit without opening the editor.)
45 fixup_msg="$state_dir"/message-fixup
46
47 # $rewritten is the name of a directory containing files for each
48 # commit that is reachable by at least one merge base of $head and
49 # $upstream. They are not necessarily rewritten, but their children
50 # might be.  This ensures that commits on merged, but otherwise
51 # unrelated side branches are left alone. (Think "X" in the man page's
52 # example.)
53 rewritten="$state_dir"/rewritten
54
55 dropped="$state_dir"/dropped
56
57 end="$state_dir"/end
58 msgnum="$state_dir"/msgnum
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 # Work around Git for Windows' Bash whose "read" does not strip CRLF
81 # and leaves CR at the end instead.
82 cr=$(printf "\015")
83
84 # When signoff=--signoff, we may actually want to skip signing off specific commits,
85 # particularly those followed by squashes or fixups. The next variable holds the
86 # signoff option for the commit being processed
87 this_signoff=$signoff
88
89 strategy_args=${strategy:+--strategy=$strategy}
90 test -n "$strategy_opts" &&
91 eval '
92         for strategy_opt in '"$strategy_opts"'
93         do
94                 strategy_args="$strategy_args -X$(git rev-parse --sq-quote "${strategy_opt#--}")"
95         done
96 '
97
98 GIT_CHERRY_PICK_HELP="$resolvemsg"
99 export GIT_CHERRY_PICK_HELP
100
101 comment_char=$(git config --get core.commentchar 2>/dev/null)
102 case "$comment_char" in
103 '' | auto)
104         comment_char="#"
105         ;;
106 ?)
107         ;;
108 *)
109         comment_char=$(echo "$comment_char" | cut -c1)
110         ;;
111 esac
112
113 warn () {
114         printf '%s\n' "$*" >&2
115 }
116
117 # Output the commit message for the specified commit.
118 commit_message () {
119         git cat-file commit "$1" | sed "1,/^$/d"
120 }
121
122 orig_reflog_action="$GIT_REFLOG_ACTION"
123
124 comment_for_reflog () {
125         case "$orig_reflog_action" in
126         ''|rebase*)
127                 GIT_REFLOG_ACTION="rebase -i ($1)"
128                 export GIT_REFLOG_ACTION
129                 ;;
130         esac
131 }
132
133 last_count=
134 mark_action_done () {
135         sed -e 1q < "$todo" >> "$done"
136         sed -e 1d < "$todo" >> "$todo".new
137         mv -f "$todo".new "$todo"
138         new_count=$(( $(git stripspace --strip-comments <"$done" | wc -l) ))
139         echo $new_count >"$msgnum"
140         total=$(($new_count + $(git stripspace --strip-comments <"$todo" | wc -l)))
141         echo $total >"$end"
142         if test "$last_count" != "$new_count"
143         then
144                 last_count=$new_count
145                 eval_gettext "Rebasing (\$new_count/\$total)"; printf "\r"
146                 test -z "$verbose" || echo
147         fi
148 }
149
150 # Put the last action marked done at the beginning of the todo list
151 # again. If there has not been an action marked done yet, leave the list of
152 # items on the todo list unchanged.
153 reschedule_last_action () {
154         tail -n 1 "$done" | cat - "$todo" >"$todo".new
155         sed -e \$d <"$done" >"$done".new
156         mv -f "$todo".new "$todo"
157         mv -f "$done".new "$done"
158 }
159
160 append_todo_help () {
161         gettext "
162 Commands:
163  p, pick = use commit
164  r, reword = use commit, but edit the commit message
165  e, edit = use commit, but stop for amending
166  s, squash = use commit, but meld into previous commit
167  f, fixup = like \"squash\", but discard this commit's log message
168  x, exec = run command (the rest of the line) using shell
169  d, drop = remove commit
170
171 These lines can be re-ordered; they are executed from top to bottom.
172 " | git stripspace --comment-lines >>"$todo"
173
174         if test $(get_missing_commit_check_level) = error
175         then
176                 gettext "
177 Do not remove any line. Use 'drop' explicitly to remove a commit.
178 " | git stripspace --comment-lines >>"$todo"
179         else
180                 gettext "
181 If you remove a line here THAT COMMIT WILL BE LOST.
182 " | git stripspace --comment-lines >>"$todo"
183         fi
184 }
185
186 make_patch () {
187         sha1_and_parents="$(git rev-list --parents -1 "$1")"
188         case "$sha1_and_parents" in
189         ?*' '?*' '?*)
190                 git diff --cc $sha1_and_parents
191                 ;;
192         ?*' '?*)
193                 git diff-tree -p "$1^!"
194                 ;;
195         *)
196                 echo "Root commit"
197                 ;;
198         esac > "$state_dir"/patch
199         test -f "$msg" ||
200                 commit_message "$1" > "$msg"
201         test -f "$author_script" ||
202                 get_author_ident_from_commit "$1" > "$author_script"
203 }
204
205 die_with_patch () {
206         echo "$1" > "$state_dir"/stopped-sha
207         make_patch "$1"
208         die "$2"
209 }
210
211 exit_with_patch () {
212         echo "$1" > "$state_dir"/stopped-sha
213         make_patch $1
214         git rev-parse --verify HEAD > "$amend"
215         gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")}
216         warn "$(eval_gettext "\
217 You can amend the commit now, with
218
219         git commit --amend \$gpg_sign_opt_quoted
220
221 Once you are satisfied with your changes, run
222
223         git rebase --continue")"
224         warn
225         exit $2
226 }
227
228 die_abort () {
229         apply_autostash
230         rm -rf "$state_dir"
231         die "$1"
232 }
233
234 has_action () {
235         test -n "$(git stripspace --strip-comments <"$1")"
236 }
237
238 is_empty_commit() {
239         tree=$(git rev-parse -q --verify "$1"^{tree} 2>/dev/null) || {
240                 sha1=$1
241                 die "$(eval_gettext "\$sha1: not a commit that can be picked")"
242         }
243         ptree=$(git rev-parse -q --verify "$1"^^{tree} 2>/dev/null) ||
244                 ptree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
245         test "$tree" = "$ptree"
246 }
247
248 is_merge_commit()
249 {
250         git rev-parse --verify --quiet "$1"^2 >/dev/null 2>&1
251 }
252
253 # Run command with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
254 # GIT_AUTHOR_DATE exported from the current environment.
255 do_with_author () {
256         (
257                 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
258                 "$@"
259         )
260 }
261
262 git_sequence_editor () {
263         if test -z "$GIT_SEQUENCE_EDITOR"
264         then
265                 GIT_SEQUENCE_EDITOR="$(git config sequence.editor)"
266                 if [ -z "$GIT_SEQUENCE_EDITOR" ]
267                 then
268                         GIT_SEQUENCE_EDITOR="$(git var GIT_EDITOR)" || return $?
269                 fi
270         fi
271
272         eval "$GIT_SEQUENCE_EDITOR" '"$@"'
273 }
274
275 pick_one () {
276         ff=--ff
277
278         case "$1" in -n) sha1=$2; ff= ;; *) sha1=$1 ;; esac
279         case "$force_rebase" in '') ;; ?*) ff= ;; esac
280         output git rev-parse --verify $sha1 || die "$(eval_gettext "Invalid commit name: \$sha1")"
281
282         if is_empty_commit "$sha1"
283         then
284                 empty_args="--allow-empty"
285         fi
286
287         test -d "$rewritten" &&
288                 pick_one_preserving_merges "$@" && return
289
290         output eval git cherry-pick \
291                         ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
292                         $this_signoff "$strategy_args" $empty_args $ff "$@"
293
294         # If cherry-pick dies it leaves the to-be-picked commit unrecorded. Reschedule
295         # previous task so this commit is not lost.
296         ret=$?
297         case "$ret" in [01]) ;; *) reschedule_last_action ;; esac
298         return $ret
299 }
300
301 pick_one_preserving_merges () {
302         fast_forward=t
303         case "$1" in
304         -n)
305                 fast_forward=f
306                 sha1=$2
307                 ;;
308         *)
309                 sha1=$1
310                 ;;
311         esac
312         sha1=$(git rev-parse $sha1)
313
314         if test -f "$state_dir"/current-commit
315         then
316                 if test "$fast_forward" = t
317                 then
318                         while read current_commit
319                         do
320                                 git rev-parse HEAD > "$rewritten"/$current_commit
321                         done <"$state_dir"/current-commit
322                         rm "$state_dir"/current-commit ||
323                                 die "$(gettext "Cannot write current commit's replacement sha1")"
324                 fi
325         fi
326
327         echo $sha1 >> "$state_dir"/current-commit
328
329         # rewrite parents; if none were rewritten, we can fast-forward.
330         new_parents=
331         pend=" $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)"
332         if test "$pend" = " "
333         then
334                 pend=" root"
335         fi
336         while [ "$pend" != "" ]
337         do
338                 p=$(expr "$pend" : ' \([^ ]*\)')
339                 pend="${pend# $p}"
340
341                 if test -f "$rewritten"/$p
342                 then
343                         new_p=$(cat "$rewritten"/$p)
344
345                         # If the todo reordered commits, and our parent is marked for
346                         # rewriting, but hasn't been gotten to yet, assume the user meant to
347                         # drop it on top of the current HEAD
348                         if test -z "$new_p"
349                         then
350                                 new_p=$(git rev-parse HEAD)
351                         fi
352
353                         test $p != $new_p && fast_forward=f
354                         case "$new_parents" in
355                         *$new_p*)
356                                 ;; # do nothing; that parent is already there
357                         *)
358                                 new_parents="$new_parents $new_p"
359                                 ;;
360                         esac
361                 else
362                         if test -f "$dropped"/$p
363                         then
364                                 fast_forward=f
365                                 replacement="$(cat "$dropped"/$p)"
366                                 test -z "$replacement" && replacement=root
367                                 pend=" $replacement$pend"
368                         else
369                                 new_parents="$new_parents $p"
370                         fi
371                 fi
372         done
373         case $fast_forward in
374         t)
375                 output warn "$(eval_gettext "Fast-forward to \$sha1")"
376                 output git reset --hard $sha1 ||
377                         die "$(eval_gettext "Cannot fast-forward to \$sha1")"
378                 ;;
379         f)
380                 first_parent=$(expr "$new_parents" : ' \([^ ]*\)')
381
382                 if [ "$1" != "-n" ]
383                 then
384                         # detach HEAD to current parent
385                         output git checkout $first_parent 2> /dev/null ||
386                                 die "$(eval_gettext "Cannot move HEAD to \$first_parent")"
387                 fi
388
389                 case "$new_parents" in
390                 ' '*' '*)
391                         test "a$1" = a-n && die "$(eval_gettext "Refusing to squash a merge: \$sha1")"
392
393                         # redo merge
394                         author_script_content=$(get_author_ident_from_commit $sha1)
395                         eval "$author_script_content"
396                         msg_content="$(commit_message $sha1)"
397                         # No point in merging the first parent, that's HEAD
398                         new_parents=${new_parents# $first_parent}
399                         merge_args="--no-log --no-ff"
400                         if ! do_with_author output eval \
401                         'git merge ${gpg_sign_opt:+"$gpg_sign_opt"} \
402                                 $merge_args $strategy_args -m "$msg_content" $new_parents'
403                         then
404                                 printf "%s\n" "$msg_content" > "$GIT_DIR"/MERGE_MSG
405                                 die_with_patch $sha1 "$(eval_gettext "Error redoing merge \$sha1")"
406                         fi
407                         echo "$sha1 $(git rev-parse HEAD^0)" >> "$rewritten_list"
408                         ;;
409                 *)
410                         output eval git cherry-pick \
411                                 ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
412                                 $this_signoff "$strategy_args" "$@" ||
413                                 die_with_patch $sha1 "$(eval_gettext "Could not pick \$sha1")"
414                         ;;
415                 esac
416                 ;;
417         esac
418 }
419
420 this_nth_commit_message () {
421         n=$1
422         eval_gettext "This is the commit message #\${n}:"
423 }
424
425 skip_nth_commit_message () {
426         n=$1
427         eval_gettext "The commit message #\${n} will be skipped:"
428 }
429
430 update_squash_messages () {
431         if test -f "$squash_msg"; then
432                 mv "$squash_msg" "$squash_msg".bak || exit
433                 count=$(($(sed -n \
434                         -e "1s/^$comment_char[^0-9]*\([0-9][0-9]*\).*/\1/p" \
435                         -e "q" < "$squash_msg".bak)+1))
436                 {
437                         printf '%s\n' "$comment_char $(eval_ngettext \
438                                 "This is a combination of \$count commit." \
439                                 "This is a combination of \$count commits." \
440                                 $count)"
441                         sed -e 1d -e '2,/^./{
442                                 /^$/d
443                         }' <"$squash_msg".bak
444                 } >"$squash_msg"
445         else
446                 commit_message HEAD >"$fixup_msg" ||
447                 die "$(eval_gettext "Cannot write \$fixup_msg")"
448                 count=2
449                 {
450                         printf '%s\n' "$comment_char $(gettext "This is a combination of 2 commits.")"
451                         printf '%s\n' "$comment_char $(gettext "This is the 1st commit message:")"
452                         echo
453                         cat "$fixup_msg"
454                 } >"$squash_msg"
455         fi
456         case $1 in
457         squash)
458                 rm -f "$fixup_msg"
459                 echo
460                 printf '%s\n' "$comment_char $(this_nth_commit_message $count)"
461                 echo
462                 commit_message $2
463                 ;;
464         fixup)
465                 echo
466                 printf '%s\n' "$comment_char $(skip_nth_commit_message $count)"
467                 echo
468                 # Change the space after the comment character to TAB:
469                 commit_message $2 | git stripspace --comment-lines | sed -e 's/ /       /'
470                 ;;
471         esac >>"$squash_msg"
472 }
473
474 peek_next_command () {
475         git stripspace --strip-comments <"$todo" | sed -n -e 's/ .*//p' -e q
476 }
477
478 # Check if the current commit should be signed off or not. This sets the
479 # variable this_signoff to the value of the signoff variable unless the next
480 # action is a squash or fixup, in which case the signoff is skipped.
481 check_this_signoff() {
482         this_signoff=$signoff
483         if test "$this_signoff" = --signoff ; then
484                 case "$(peek_next_command)" in
485                 squash|s|fixup|f)
486                         this_signoff=--no-signoff
487                 esac
488         fi
489 }
490
491 # A squash/fixup has failed.  Prepare the long version of the squash
492 # commit message, then die_with_patch.  This code path requires the
493 # user to edit the combined commit message for all commits that have
494 # been squashed/fixedup so far.  So also erase the old squash
495 # messages, effectively causing the combined commit to be used as the
496 # new basis for any further squash/fixups.  Args: sha1 rest
497 die_failed_squash() {
498         sha1=$1
499         rest=$2
500         mv "$squash_msg" "$msg" || exit
501         rm -f "$fixup_msg"
502         cp "$msg" "$GIT_DIR"/MERGE_MSG || exit
503         warn
504         warn "$(eval_gettext "Could not apply \$sha1... \$rest")"
505         die_with_patch $sha1 ""
506 }
507
508 flush_rewritten_pending() {
509         test -s "$rewritten_pending" || return
510         newsha1="$(git rev-parse HEAD^0)"
511         sed "s/$/ $newsha1/" < "$rewritten_pending" >> "$rewritten_list"
512         rm -f "$rewritten_pending"
513 }
514
515 record_in_rewritten() {
516         oldsha1="$(git rev-parse $1)"
517         echo "$oldsha1" >> "$rewritten_pending"
518
519         case "$(peek_next_command)" in
520         squash|s|fixup|f)
521                 ;;
522         *)
523                 flush_rewritten_pending
524                 ;;
525         esac
526 }
527
528 do_pick () {
529         sha1=$1
530         rest=$2
531         if test "$(git rev-parse HEAD)" = "$squash_onto"
532         then
533                 # Set the correct commit message and author info on the
534                 # sentinel root before cherry-picking the original changes
535                 # without committing (-n).  Finally, update the sentinel again
536                 # to include these changes.  If the cherry-pick results in a
537                 # conflict, this means our behaviour is similar to a standard
538                 # failed cherry-pick during rebase, with a dirty index to
539                 # resolve before manually running git commit --amend then git
540                 # rebase --continue.
541                 git commit --allow-empty --allow-empty-message --amend \
542                            --no-post-rewrite -n -q -C $sha1 &&
543                         pick_one -n $sha1 &&
544                         git commit --allow-empty --allow-empty-message \
545                                    --amend --no-post-rewrite -n -q -C $sha1 \
546                                    $this_signoff ${gpg_sign_opt:+"$gpg_sign_opt"} ||
547                                    die_with_patch $sha1 "$(eval_gettext "Could not apply \$sha1... \$rest")"
548         else
549                 pick_one $sha1 ||
550                         die_with_patch $sha1 "$(eval_gettext "Could not apply \$sha1... \$rest")"
551         fi
552 }
553
554 do_next () {
555         rm -f "$msg" "$author_script" "$amend" "$state_dir"/stopped-sha || exit
556         read -r command sha1 rest < "$todo"
557         case "$command" in
558         "$comment_char"*|''|noop|drop|d)
559                 mark_action_done
560                 ;;
561         "$cr")
562                 # Work around CR left by "read" (e.g. with Git for Windows' Bash).
563                 mark_action_done
564                 ;;
565         pick|p)
566                 comment_for_reflog pick
567
568                 mark_action_done
569                 check_this_signoff
570                 do_pick $sha1 "$rest"
571                 record_in_rewritten $sha1
572                 ;;
573         reword|r)
574                 comment_for_reflog reword
575
576                 mark_action_done
577                 check_this_signoff
578                 do_pick $sha1 "$rest"
579                 git commit --amend --no-post-rewrite ${gpg_sign_opt:+"$gpg_sign_opt"} || {
580                         warn "$(eval_gettext "\
581 Could not amend commit after successfully picking \$sha1... \$rest
582 This is most likely due to an empty commit message, or the pre-commit hook
583 failed. If the pre-commit hook failed, you may need to resolve the issue before
584 you are able to reword the commit.")"
585                         exit_with_patch $sha1 1
586                 }
587                 record_in_rewritten $sha1
588                 ;;
589         edit|e)
590                 comment_for_reflog edit
591
592                 mark_action_done
593                 check_this_signoff
594                 do_pick $sha1 "$rest"
595                 sha1_abbrev=$(git rev-parse --short $sha1)
596                 warn "$(eval_gettext "Stopped at \$sha1_abbrev... \$rest")"
597                 exit_with_patch $sha1 0
598                 ;;
599         squash|s|fixup|f)
600                 case "$command" in
601                 squash|s)
602                         squash_style=squash
603                         ;;
604                 fixup|f)
605                         squash_style=fixup
606                         ;;
607                 esac
608                 comment_for_reflog $squash_style
609
610                 test -f "$done" && has_action "$done" ||
611                         die "$(eval_gettext "Cannot '\$squash_style' without a previous commit")"
612
613                 mark_action_done
614                 update_squash_messages $squash_style $sha1
615                 author_script_content=$(get_author_ident_from_commit HEAD)
616                 echo "$author_script_content" > "$author_script"
617                 eval "$author_script_content"
618                 if ! pick_one -n $sha1
619                 then
620                         git rev-parse --verify HEAD >"$amend"
621                         die_failed_squash $sha1 "$rest"
622                 fi
623                 case "$(peek_next_command)" in
624                 squash|s|fixup|f)
625                         # This is an intermediate commit; its message will only be
626                         # used in case of trouble.  So use the long version:
627                         do_with_author output git commit --amend --no-verify -F "$squash_msg" \
628                                 ${gpg_sign_opt:+"$gpg_sign_opt"} ||
629                                 die_failed_squash $sha1 "$rest"
630                         ;;
631                 *)
632                         # This is the final command of this squash/fixup group
633                         if test -f "$fixup_msg"
634                         then
635                                 do_with_author git commit --amend --no-verify -F "$fixup_msg" \
636                                         $signoff ${gpg_sign_opt:+"$gpg_sign_opt"} ||
637                                         die_failed_squash $sha1 "$rest"
638                         else
639                                 cp "$squash_msg" "$GIT_DIR"/SQUASH_MSG || exit
640                                 rm -f "$GIT_DIR"/MERGE_MSG
641                                 do_with_author git commit --amend --no-verify -F "$GIT_DIR"/SQUASH_MSG -e \
642                                         $signoff ${gpg_sign_opt:+"$gpg_sign_opt"} ||
643                                         die_failed_squash $sha1 "$rest"
644                         fi
645                         rm -f "$squash_msg" "$fixup_msg"
646                         ;;
647                 esac
648                 record_in_rewritten $sha1
649                 ;;
650         x|"exec")
651                 read -r command rest < "$todo"
652                 mark_action_done
653                 eval_gettextln "Executing: \$rest"
654                 "${SHELL:-@SHELL_PATH@}" -c "$rest" # Actual execution
655                 status=$?
656                 # Run in subshell because require_clean_work_tree can die.
657                 dirty=f
658                 (require_clean_work_tree "rebase" 2>/dev/null) || dirty=t
659                 if test "$status" -ne 0
660                 then
661                         warn "$(eval_gettext "Execution failed: \$rest")"
662                         test "$dirty" = f ||
663                                 warn "$(gettext "and made changes to the index and/or the working tree")"
664
665                         warn "$(gettext "\
666 You can fix the problem, and then run
667
668         git rebase --continue")"
669                         warn
670                         if test $status -eq 127         # command not found
671                         then
672                                 status=1
673                         fi
674                         exit "$status"
675                 elif test "$dirty" = t
676                 then
677                         # TRANSLATORS: after these lines is a command to be issued by the user
678                         warn "$(eval_gettext "\
679 Execution succeeded: \$rest
680 but left changes to the index and/or the working tree
681 Commit or stash your changes, and then run
682
683         git rebase --continue")"
684                         warn
685                         exit 1
686                 fi
687                 ;;
688         *)
689                 warn "$(eval_gettext "Unknown command: \$command \$sha1 \$rest")"
690                 fixtodo="$(gettext "Please fix this using 'git rebase --edit-todo'.")"
691                 if git rev-parse --verify -q "$sha1" >/dev/null
692                 then
693                         die_with_patch $sha1 "$fixtodo"
694                 else
695                         die "$fixtodo"
696                 fi
697                 ;;
698         esac
699         test -s "$todo" && return
700
701         comment_for_reflog finish &&
702         newhead=$(git rev-parse HEAD) &&
703         case $head_name in
704         refs/*)
705                 message="$GIT_REFLOG_ACTION: $head_name onto $onto" &&
706                 git update-ref -m "$message" $head_name $newhead $orig_head &&
707                 git symbolic-ref \
708                   -m "$GIT_REFLOG_ACTION: returning to $head_name" \
709                   HEAD $head_name
710                 ;;
711         esac && {
712                 test ! -f "$state_dir"/verbose ||
713                         git diff-tree --stat $orig_head..HEAD
714         } &&
715         {
716                 test -s "$rewritten_list" &&
717                 git notes copy --for-rewrite=rebase < "$rewritten_list" ||
718                 true # we don't care if this copying failed
719         } &&
720         hook="$(git rev-parse --git-path hooks/post-rewrite)"
721         if test -x "$hook" && test -s "$rewritten_list"; then
722                 "$hook" rebase < "$rewritten_list"
723                 true # we don't care if this hook failed
724         fi &&
725                 warn "$(eval_gettext "Successfully rebased and updated \$head_name.")"
726
727         return 1 # not failure; just to break the do_rest loop
728 }
729
730 # can only return 0, when the infinite loop breaks
731 do_rest () {
732         while :
733         do
734                 do_next || break
735         done
736 }
737
738 # skip picking commits whose parents are unchanged
739 skip_unnecessary_picks () {
740         fd=3
741         while read -r command rest
742         do
743                 # fd=3 means we skip the command
744                 case "$fd,$command" in
745                 3,pick|3,p)
746                         # pick a commit whose parent is current $onto -> skip
747                         sha1=${rest%% *}
748                         case "$(git rev-parse --verify --quiet "$sha1"^)" in
749                         "$onto"*)
750                                 onto=$sha1
751                                 ;;
752                         *)
753                                 fd=1
754                                 ;;
755                         esac
756                         ;;
757                 3,"$comment_char"*|3,)
758                         # copy comments
759                         ;;
760                 *)
761                         fd=1
762                         ;;
763                 esac
764                 printf '%s\n' "$command${rest:+ }$rest" >&$fd
765         done <"$todo" >"$todo.new" 3>>"$done" &&
766         mv -f "$todo".new "$todo" &&
767         case "$(peek_next_command)" in
768         squash|s|fixup|f)
769                 record_in_rewritten "$onto"
770                 ;;
771         esac ||
772                 die "$(gettext "Could not skip unnecessary pick commands")"
773 }
774
775 transform_todo_ids () {
776         while read -r command rest
777         do
778                 case "$command" in
779                 "$comment_char"* | exec)
780                         # Be careful for oddball commands like 'exec'
781                         # that do not have a SHA-1 at the beginning of $rest.
782                         ;;
783                 *)
784                         sha1=$(git rev-parse --verify --quiet "$@" ${rest%%[     ]*}) &&
785                         rest="$sha1 ${rest#*[    ]}"
786                         ;;
787                 esac
788                 printf '%s\n' "$command${rest:+ }$rest"
789         done <"$todo" >"$todo.new" &&
790         mv -f "$todo.new" "$todo"
791 }
792
793 expand_todo_ids() {
794         transform_todo_ids
795 }
796
797 collapse_todo_ids() {
798         transform_todo_ids --short
799 }
800
801 # Rearrange the todo list that has both "pick sha1 msg" and
802 # "pick sha1 fixup!/squash! msg" appears in it so that the latter
803 # comes immediately after the former, and change "pick" to
804 # "fixup"/"squash".
805 #
806 # Note that if the config has specified a custom instruction format
807 # each log message will be re-retrieved in order to normalize the
808 # autosquash arrangement
809 rearrange_squash () {
810         # extract fixup!/squash! lines and resolve any referenced sha1's
811         while read -r pick sha1 message
812         do
813                 test -z "${format}" || message=$(git log -n 1 --format="%s" ${sha1})
814                 case "$message" in
815                 "squash! "*|"fixup! "*)
816                         action="${message%%!*}"
817                         rest=$message
818                         prefix=
819                         # skip all squash! or fixup! (but save for later)
820                         while :
821                         do
822                                 case "$rest" in
823                                 "squash! "*|"fixup! "*)
824                                         prefix="$prefix${rest%%!*},"
825                                         rest="${rest#*! }"
826                                         ;;
827                                 *)
828                                         break
829                                         ;;
830                                 esac
831                         done
832                         printf '%s %s %s %s\n' "$sha1" "$action" "$prefix" "$rest"
833                         # if it's a single word, try to resolve to a full sha1 and
834                         # emit a second copy. This allows us to match on both message
835                         # and on sha1 prefix
836                         if test "${rest#* }" = "$rest"; then
837                                 fullsha="$(git rev-parse -q --verify "$rest" 2>/dev/null)"
838                                 if test -n "$fullsha"; then
839                                         # prefix the action to uniquely identify this line as
840                                         # intended for full sha1 match
841                                         echo "$sha1 +$action $prefix $fullsha"
842                                 fi
843                         fi
844                 esac
845         done >"$1.sq" <"$1"
846         test -s "$1.sq" || return
847
848         used=
849         while read -r pick sha1 message
850         do
851                 case " $used" in
852                 *" $sha1 "*) continue ;;
853                 esac
854                 printf '%s\n' "$pick $sha1 $message"
855                 test -z "${format}" || message=$(git log -n 1 --format="%s" ${sha1})
856                 used="$used$sha1 "
857                 while read -r squash action msg_prefix msg_content
858                 do
859                         case " $used" in
860                         *" $squash "*) continue ;;
861                         esac
862                         emit=0
863                         case "$action" in
864                         +*)
865                                 action="${action#+}"
866                                 # full sha1 prefix test
867                                 case "$msg_content" in "$sha1"*) emit=1;; esac ;;
868                         *)
869                                 # message prefix test
870                                 case "$message" in "$msg_content"*) emit=1;; esac ;;
871                         esac
872                         if test $emit = 1; then
873                                 if test -n "${format}"
874                                 then
875                                         msg_content=$(git log -n 1 --format="${format}" ${squash})
876                                 else
877                                         msg_content="$(echo "$msg_prefix" | sed "s/,/! /g")$msg_content"
878                                 fi
879                                 printf '%s\n' "$action $squash $msg_content"
880                                 used="$used$squash "
881                         fi
882                 done <"$1.sq"
883         done >"$1.rearranged" <"$1"
884         cat "$1.rearranged" >"$1"
885         rm -f "$1.sq" "$1.rearranged"
886 }
887
888 # Add commands after a pick or after a squash/fixup serie
889 # in the todo list.
890 add_exec_commands () {
891         {
892                 first=t
893                 while read -r insn rest
894                 do
895                         case $insn in
896                         pick)
897                                 test -n "$first" ||
898                                 printf "%s" "$cmd"
899                                 ;;
900                         esac
901                         printf "%s %s\n" "$insn" "$rest"
902                         first=
903                 done
904                 printf "%s" "$cmd"
905         } <"$1" >"$1.new" &&
906         mv "$1.new" "$1"
907 }
908
909 # Check if the SHA-1 passed as an argument is a
910 # correct one, if not then print $2 in "$todo".badsha
911 # $1: the SHA-1 to test
912 # $2: the line number of the input
913 # $3: the input filename
914 check_commit_sha () {
915         badsha=0
916         if test -z "$1"
917         then
918                 badsha=1
919         else
920                 sha1_verif="$(git rev-parse --verify --quiet $1^{commit})"
921                 if test -z "$sha1_verif"
922                 then
923                         badsha=1
924                 fi
925         fi
926
927         if test $badsha -ne 0
928         then
929                 line="$(sed -n -e "${2}p" "$3")"
930                 warn "$(eval_gettext "\
931 Warning: the SHA-1 is missing or isn't a commit in the following line:
932  - \$line")"
933                 warn
934         fi
935
936         return $badsha
937 }
938
939 # prints the bad commits and bad commands
940 # from the todolist in stdin
941 check_bad_cmd_and_sha () {
942         retval=0
943         lineno=0
944         while read -r command rest
945         do
946                 lineno=$(( $lineno + 1 ))
947                 case $command in
948                 "$comment_char"*|''|noop|x|exec)
949                         # Doesn't expect a SHA-1
950                         ;;
951                 "$cr")
952                         # Work around CR left by "read" (e.g. with Git for
953                         # Windows' Bash).
954                         ;;
955                 pick|p|drop|d|reword|r|edit|e|squash|s|fixup|f)
956                         if ! check_commit_sha "${rest%%[        ]*}" "$lineno" "$1"
957                         then
958                                 retval=1
959                         fi
960                         ;;
961                 *)
962                         line="$(sed -n -e "${lineno}p" "$1")"
963                         warn "$(eval_gettext "\
964 Warning: the command isn't recognized in the following line:
965  - \$line")"
966                         warn
967                         retval=1
968                         ;;
969                 esac
970         done <"$1"
971         return $retval
972 }
973
974 # Print the list of the SHA-1 of the commits
975 # from stdin to stdout
976 todo_list_to_sha_list () {
977         git stripspace --strip-comments |
978         while read -r command sha1 rest
979         do
980                 case $command in
981                 "$comment_char"*|''|noop|x|"exec")
982                         ;;
983                 *)
984                         long_sha=$(git rev-list --no-walk "$sha1" 2>/dev/null)
985                         printf "%s\n" "$long_sha"
986                         ;;
987                 esac
988         done
989 }
990
991 # Use warn for each line in stdin
992 warn_lines () {
993         while read -r line
994         do
995                 warn " - $line"
996         done
997 }
998
999 # Switch to the branch in $into and notify it in the reflog
1000 checkout_onto () {
1001         GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name"
1002         output git checkout $onto || die_abort "$(gettext "could not detach HEAD")"
1003         git update-ref ORIG_HEAD $orig_head
1004 }
1005
1006 get_missing_commit_check_level () {
1007         check_level=$(git config --get rebase.missingCommitsCheck)
1008         check_level=${check_level:-ignore}
1009         # Don't be case sensitive
1010         printf '%s' "$check_level" | tr 'A-Z' 'a-z'
1011 }
1012
1013 # Check if the user dropped some commits by mistake
1014 # Behaviour determined by rebase.missingCommitsCheck.
1015 # Check if there is an unrecognized command or a
1016 # bad SHA-1 in a command.
1017 check_todo_list () {
1018         raise_error=f
1019
1020         check_level=$(get_missing_commit_check_level)
1021
1022         case "$check_level" in
1023         warn|error)
1024                 # Get the SHA-1 of the commits
1025                 todo_list_to_sha_list <"$todo".backup >"$todo".oldsha1
1026                 todo_list_to_sha_list <"$todo" >"$todo".newsha1
1027
1028                 # Sort the SHA-1 and compare them
1029                 sort -u "$todo".oldsha1 >"$todo".oldsha1+
1030                 mv "$todo".oldsha1+ "$todo".oldsha1
1031                 sort -u "$todo".newsha1 >"$todo".newsha1+
1032                 mv "$todo".newsha1+ "$todo".newsha1
1033                 comm -2 -3 "$todo".oldsha1 "$todo".newsha1 >"$todo".miss
1034
1035                 # Warn about missing commits
1036                 if test -s "$todo".miss
1037                 then
1038                         test "$check_level" = error && raise_error=t
1039
1040                         warn "$(gettext "\
1041 Warning: some commits may have been dropped accidentally.
1042 Dropped commits (newer to older):")"
1043
1044                         # Make the list user-friendly and display
1045                         opt="--no-walk=sorted --format=oneline --abbrev-commit --stdin"
1046                         git rev-list $opt <"$todo".miss | warn_lines
1047
1048                         warn "$(gettext "\
1049 To avoid this message, use \"drop\" to explicitly remove a commit.
1050
1051 Use 'git config rebase.missingCommitsCheck' to change the level of warnings.
1052 The possible behaviours are: ignore, warn, error.")"
1053                         warn
1054                 fi
1055                 ;;
1056         ignore)
1057                 ;;
1058         *)
1059                 warn "$(eval_gettext "Unrecognized setting \$check_level for option rebase.missingCommitsCheck. Ignoring.")"
1060                 ;;
1061         esac
1062
1063         if ! check_bad_cmd_and_sha "$todo"
1064         then
1065                 raise_error=t
1066         fi
1067
1068         if test $raise_error = t
1069         then
1070                 # Checkout before the first commit of the
1071                 # rebase: this way git rebase --continue
1072                 # will work correctly as it expects HEAD to be
1073                 # placed before the commit of the next action
1074                 checkout_onto
1075
1076                 warn "$(gettext "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --continue'.")"
1077                 die "$(gettext "Or you can abort the rebase with 'git rebase --abort'.")"
1078         fi
1079 }
1080
1081 # The whole contents of this file is run by dot-sourcing it from
1082 # inside a shell function.  It used to be that "return"s we see
1083 # below were not inside any function, and expected to return
1084 # to the function that dot-sourced us.
1085 #
1086 # However, older (9.x) versions of FreeBSD /bin/sh misbehave on such a
1087 # construct and continue to run the statements that follow such a "return".
1088 # As a work-around, we introduce an extra layer of a function
1089 # here, and immediately call it after defining it.
1090 git_rebase__interactive () {
1091
1092 case "$action" in
1093 continue)
1094         if test ! -d "$rewritten"
1095         then
1096                 exec git rebase--helper ${force_rebase:+--no-ff} $signoff --continue
1097         fi
1098         # do we have anything to commit?
1099         if git diff-index --cached --quiet HEAD --
1100         then
1101                 # Nothing to commit -- skip this commit
1102
1103                 test ! -f "$GIT_DIR"/CHERRY_PICK_HEAD ||
1104                 rm "$GIT_DIR"/CHERRY_PICK_HEAD ||
1105                 die "$(gettext "Could not remove CHERRY_PICK_HEAD")"
1106         else
1107                 if ! test -f "$author_script"
1108                 then
1109                         gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")}
1110                         die "$(eval_gettext "\
1111 You have staged changes in your working tree.
1112 If these changes are meant to be
1113 squashed into the previous commit, run:
1114
1115   git commit --amend \$gpg_sign_opt_quoted
1116
1117 If they are meant to go into a new commit, run:
1118
1119   git commit \$gpg_sign_opt_quoted
1120
1121 In both cases, once you're done, continue with:
1122
1123   git rebase --continue
1124 ")"
1125                 fi
1126                 . "$author_script" ||
1127                         die "$(gettext "Error trying to find the author identity to amend commit")"
1128
1129                 check_this_signoff
1130                 if test -f "$amend"
1131                 then
1132                         current_head=$(git rev-parse --verify HEAD)
1133                         test "$current_head" = $(cat "$amend") ||
1134                         die "$(gettext "\
1135 You have uncommitted changes in your working tree. Please commit them
1136 first and then run 'git rebase --continue' again.")"
1137                         do_with_author git commit --amend --no-verify -F "$msg" -e \
1138                                 $this_signoff ${gpg_sign_opt:+"$gpg_sign_opt"} ||
1139                                 die "$(gettext "Could not commit staged changes.")"
1140                 else
1141                         do_with_author git commit --no-verify -F "$msg" -e \
1142                                 $this_signoff ${gpg_sign_opt:+"$gpg_sign_opt"} ||
1143                                 die "$(gettext "Could not commit staged changes.")"
1144                 fi
1145         fi
1146
1147         if test -r "$state_dir"/stopped-sha
1148         then
1149                 record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
1150         fi
1151
1152         require_clean_work_tree "rebase"
1153         do_rest
1154         return 0
1155         ;;
1156 skip)
1157         git rerere clear
1158
1159         if test ! -d "$rewritten"
1160         then
1161                 exec git rebase--helper ${force_rebase:+--no-ff} $signoff --continue
1162         fi
1163         do_rest
1164         return 0
1165         ;;
1166 edit-todo)
1167         git stripspace --strip-comments <"$todo" >"$todo".new
1168         mv -f "$todo".new "$todo"
1169         collapse_todo_ids
1170         append_todo_help
1171         gettext "
1172 You are editing the todo file of an ongoing interactive rebase.
1173 To continue rebase after editing, run:
1174     git rebase --continue
1175
1176 " | git stripspace --comment-lines >>"$todo"
1177
1178         git_sequence_editor "$todo" ||
1179                 die "$(gettext "Could not execute editor")"
1180         expand_todo_ids
1181
1182         exit
1183         ;;
1184 esac
1185
1186 comment_for_reflog start
1187
1188 if test ! -z "$switch_to"
1189 then
1190         GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to"
1191         output git checkout "$switch_to" -- ||
1192                 die "$(eval_gettext "Could not checkout \$switch_to")"
1193
1194         comment_for_reflog start
1195 fi
1196
1197 orig_head=$(git rev-parse --verify HEAD) || die "$(gettext "No HEAD?")"
1198 mkdir -p "$state_dir" || die "$(eval_gettext "Could not create temporary \$state_dir")"
1199
1200 : > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")"
1201 write_basic_state
1202 if test t = "$preserve_merges"
1203 then
1204         if test -z "$rebase_root"
1205         then
1206                 mkdir "$rewritten" &&
1207                 for c in $(git merge-base --all $orig_head $upstream)
1208                 do
1209                         echo $onto > "$rewritten"/$c ||
1210                                 die "$(gettext "Could not init rewritten commits")"
1211                 done
1212         else
1213                 mkdir "$rewritten" &&
1214                 echo $onto > "$rewritten"/root ||
1215                         die "$(gettext "Could not init rewritten commits")"
1216         fi
1217         # No cherry-pick because our first pass is to determine
1218         # parents to rewrite and skipping dropped commits would
1219         # prematurely end our probe
1220         merges_option=
1221 else
1222         merges_option="--no-merges --cherry-pick"
1223 fi
1224
1225 shorthead=$(git rev-parse --short $orig_head)
1226 shortonto=$(git rev-parse --short $onto)
1227 if test -z "$rebase_root"
1228         # this is now equivalent to ! -z "$upstream"
1229 then
1230         shortupstream=$(git rev-parse --short $upstream)
1231         revisions=$upstream...$orig_head
1232         shortrevisions=$shortupstream..$shorthead
1233 else
1234         revisions=$onto...$orig_head
1235         shortrevisions=$shorthead
1236 fi
1237 format=$(git config --get rebase.instructionFormat)
1238 # the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse
1239 git rev-list $merges_option --format="%m%H ${format:-%s}" \
1240         --reverse --left-right --topo-order \
1241         $revisions ${restrict_revision+^$restrict_revision} | \
1242         sed -n "s/^>//p" |
1243 while read -r sha1 rest
1244 do
1245
1246         if test -z "$keep_empty" && is_empty_commit $sha1 && ! is_merge_commit $sha1
1247         then
1248                 comment_out="$comment_char "
1249         else
1250                 comment_out=
1251         fi
1252
1253         if test t != "$preserve_merges"
1254         then
1255                 printf '%s\n' "${comment_out}pick $sha1 $rest" >>"$todo"
1256         else
1257                 if test -z "$rebase_root"
1258                 then
1259                         preserve=t
1260                         for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
1261                         do
1262                                 if test -f "$rewritten"/$p
1263                                 then
1264                                         preserve=f
1265                                 fi
1266                         done
1267                 else
1268                         preserve=f
1269                 fi
1270                 if test f = "$preserve"
1271                 then
1272                         touch "$rewritten"/$sha1
1273                         printf '%s\n' "${comment_out}pick $sha1 $rest" >>"$todo"
1274                 fi
1275         fi
1276 done
1277
1278 # Watch for commits that been dropped by --cherry-pick
1279 if test t = "$preserve_merges"
1280 then
1281         mkdir "$dropped"
1282         # Save all non-cherry-picked changes
1283         git rev-list $revisions --left-right --cherry-pick | \
1284                 sed -n "s/^>//p" > "$state_dir"/not-cherry-picks
1285         # Now all commits and note which ones are missing in
1286         # not-cherry-picks and hence being dropped
1287         git rev-list $revisions |
1288         while read rev
1289         do
1290                 if test -f "$rewritten"/$rev &&
1291                    ! sane_grep "$rev" "$state_dir"/not-cherry-picks >/dev/null
1292                 then
1293                         # Use -f2 because if rev-list is telling us this commit is
1294                         # not worthwhile, we don't want to track its multiple heads,
1295                         # just the history of its first-parent for others that will
1296                         # be rebasing on top of it
1297                         git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$dropped"/$rev
1298                         sha1=$(git rev-list -1 $rev)
1299                         sane_grep -v "^[a-z][a-z]* $sha1" <"$todo" > "${todo}2" ; mv "${todo}2" "$todo"
1300                         rm "$rewritten"/$rev
1301                 fi
1302         done
1303 fi
1304
1305 test -s "$todo" || echo noop >> "$todo"
1306 test -n "$autosquash" && rearrange_squash "$todo"
1307 test -n "$cmd" && add_exec_commands "$todo"
1308
1309 todocount=$(git stripspace --strip-comments <"$todo" | wc -l)
1310 todocount=${todocount##* }
1311
1312 cat >>"$todo" <<EOF
1313
1314 $comment_char $(eval_ngettext \
1315         "Rebase \$shortrevisions onto \$shortonto (\$todocount command)" \
1316         "Rebase \$shortrevisions onto \$shortonto (\$todocount commands)" \
1317         "$todocount")
1318 EOF
1319 append_todo_help
1320 gettext "
1321 However, if you remove everything, the rebase will be aborted.
1322
1323 " | git stripspace --comment-lines >>"$todo"
1324
1325 if test -z "$keep_empty"
1326 then
1327         printf '%s\n' "$comment_char $(gettext "Note that empty commits are commented out")" >>"$todo"
1328 fi
1329
1330
1331 has_action "$todo" ||
1332         return 2
1333
1334 cp "$todo" "$todo".backup
1335 collapse_todo_ids
1336 git_sequence_editor "$todo" ||
1337         die_abort "$(gettext "Could not execute editor")"
1338
1339 has_action "$todo" ||
1340         return 2
1341
1342 check_todo_list
1343
1344 expand_todo_ids
1345
1346 test -d "$rewritten" || test -n "$force_rebase" || skip_unnecessary_picks
1347
1348 checkout_onto
1349 if test -z "$rebase_root" && test ! -d "$rewritten"
1350 then
1351         require_clean_work_tree "rebase"
1352         exec git rebase--helper ${force_rebase:+--no-ff} $signoff --continue
1353 fi
1354 do_rest
1355
1356 }
1357 # ... and then we call the whole thing.
1358 git_rebase__interactive