tag.c: use 'ref-filter' APIs
[gitweb.git] / git-rebase--interactive.sh
index c26a200a6c0e7edd2b182b71af50df52179d295f..f01637b1fdeb7f021b74171135ac0e7dba566542 100644 (file)
@@ -512,7 +512,7 @@ do_pick () {
 }
 
 do_next () {
-       rm -f "$msg" "$author_script" "$amend" || exit
+       rm -f "$msg" "$author_script" "$amend" "$state_dir"/stopped-sha || exit
        read -r command sha1 rest < "$todo"
        case "$command" in
        "$comment_char"*|''|noop|drop|d)
@@ -602,9 +602,6 @@ do_next () {
                read -r command rest < "$todo"
                mark_action_done
                printf 'Executing: %s\n' "$rest"
-               # "exec" command doesn't take a sha1 in the todo-list.
-               # => can't just use $sha1 here.
-               git rev-parse --verify HEAD > "$state_dir"/stopped-sha
                ${SHELL:-@SHELL_PATH@} -c "$rest" # Actual execution
                status=$?
                # Run in subshell because require_clean_work_tree can die.
@@ -753,10 +750,15 @@ collapse_todo_ids() {
 # "pick sha1 fixup!/squash! msg" appears in it so that the latter
 # comes immediately after the former, and change "pick" to
 # "fixup"/"squash".
+#
+# Note that if the config has specified a custom instruction format
+# each log message will be re-retrieved in order to normalize the
+# autosquash arrangement
 rearrange_squash () {
        # extract fixup!/squash! lines and resolve any referenced sha1's
        while read -r pick sha1 message
        do
+               test -z "${format}" || message=$(git log -n 1 --format="%s" ${sha1})
                case "$message" in
                "squash! "*|"fixup! "*)
                        action="${message%%!*}"
@@ -798,6 +800,7 @@ rearrange_squash () {
                *" $sha1 "*) continue ;;
                esac
                printf '%s\n' "$pick $sha1 $message"
+               test -z "${format}" || message=$(git log -n 1 --format="%s" ${sha1})
                used="$used$sha1 "
                while read -r squash action msg_prefix msg_content
                do
@@ -815,8 +818,13 @@ rearrange_squash () {
                                case "$message" in "$msg_content"*) emit=1;; esac ;;
                        esac
                        if test $emit = 1; then
-                               real_prefix=$(echo "$msg_prefix" | sed "s/,/! /g")
-                               printf '%s\n' "$action $squash ${real_prefix}$msg_content"
+                               if test -n "${format}"
+                               then
+                                       msg_content=$(git log -n 1 --format="${format}" ${squash})
+                               else
+                                       msg_content="$(echo "$msg_prefix" | sed "s/,/! /g")$msg_content"
+                               fi
+                               printf '%s\n' "$action $squash $msg_content"
                                used="$used$squash "
                        fi
                done <"$1.sq"
@@ -846,6 +854,71 @@ add_exec_commands () {
        mv "$1.new" "$1"
 }
 
+# Check if the SHA-1 passed as an argument is a
+# correct one, if not then print $2 in "$todo".badsha
+# $1: the SHA-1 to test
+# $2: the line to display if incorrect SHA-1
+check_commit_sha () {
+       badsha=0
+       if test -z $1
+       then
+               badsha=1
+       else
+               sha1_verif="$(git rev-parse --verify --quiet $1^{commit})"
+               if test -z $sha1_verif
+               then
+                       badsha=1
+               fi
+       fi
+
+       if test $badsha -ne 0
+       then
+               warn "Warning: the SHA-1 is missing or isn't" \
+                       "a commit in the following line:"
+               warn " - $2"
+               warn
+       fi
+
+       return $badsha
+}
+
+# prints the bad commits and bad commands
+# from the todolist in stdin
+check_bad_cmd_and_sha () {
+       retval=0
+       git stripspace --strip-comments |
+       (
+               while read -r line
+               do
+                       IFS=' '
+                       set -- $line
+                       command=$1
+                       sha1=$2
+
+                       case $command in
+                       ''|noop|x|"exec")
+                               # Doesn't expect a SHA-1
+                               ;;
+                       pick|p|drop|d|reword|r|edit|e|squash|s|fixup|f)
+                               if ! check_commit_sha $sha1 "$line"
+                               then
+                                       retval=1
+                               fi
+                               ;;
+                       *)
+                               warn "Warning: the command isn't recognized" \
+                                       "in the following line:"
+                               warn " - $line"
+                               warn
+                               retval=1
+                               ;;
+                       esac
+               done
+
+               return $retval
+       )
+}
+
 # Print the list of the SHA-1 of the commits
 # from stdin to stdout
 todo_list_to_sha_list () {
@@ -887,6 +960,8 @@ get_missing_commit_check_level () {
 
 # Check if the user dropped some commits by mistake
 # Behaviour determined by rebase.missingCommitsCheck.
+# Check if there is an unrecognized command or a
+# bad SHA-1 in a command.
 check_todo_list () {
        raise_error=f
 
@@ -935,6 +1010,11 @@ check_todo_list () {
                ;;
        esac
 
+       if ! check_bad_cmd_and_sha <"$todo"
+       then
+               raise_error=t
+       fi
+
        if test $raise_error = t
        then
                # Checkout before the first commit of the
@@ -964,7 +1044,11 @@ continue)
        # do we have anything to commit?
        if git diff-index --cached --quiet HEAD --
        then
-               : Nothing to commit -- skip this
+               # Nothing to commit -- skip this commit
+
+               test ! -f "$GIT_DIR"/CHERRY_PICK_HEAD ||
+               rm "$GIT_DIR"/CHERRY_PICK_HEAD ||
+               die "Could not remove CHERRY_PICK_HEAD"
        else
                if ! test -f "$author_script"
                then
@@ -1002,7 +1086,10 @@ first and then run 'git rebase --continue' again."
                fi
        fi
 
-       record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
+       if test -r "$state_dir"/stopped-sha
+       then
+               record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
+       fi
 
        require_clean_work_tree "rebase"
        do_rest
@@ -1089,7 +1176,10 @@ else
        revisions=$onto...$orig_head
        shortrevisions=$shorthead
 fi
-git rev-list $merges_option --pretty=oneline --reverse --left-right --topo-order \
+format=$(git config --get rebase.instructionFormat)
+# the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse
+git rev-list $merges_option --format="%m%H ${format:-%s}" \
+       --reverse --left-right --topo-order \
        $revisions ${restrict_revision+^$restrict_revision} | \
        sed -n "s/^>//p" |
 while read -r sha1 rest