Merge branch 'mm/rebase-i-post-rewrite-exec'
authorJunio C Hamano <gitster@pobox.com>
Mon, 1 Jun 2015 19:45:20 +0000 (12:45 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 1 Jun 2015 19:45:20 +0000 (12:45 -0700)
"git rebase -i" fired post-rewrite hook when it shouldn't (namely,
when it was told to stop sequencing with 'exec' insn).

* mm/rebase-i-post-rewrite-exec:
t5407: use <<- to align the expected output
rebase -i: fix post-rewrite hook with failed exec command
rebase -i: demonstrate incorrect behavior of post-rewrite

1  2 
git-rebase--interactive.sh
index bab0dccc04d85215223c30597659f23cf8edff32,9d413cbc128327ab047c5450d476cc45e178c763..dc3133f681227e66dd54f7bed4be68277e4240b3
@@@ -132,16 -132,6 +132,16 @@@ mark_action_done () 
        fi
  }
  
 +# Put the last action marked done at the beginning of the todo list
 +# again. If there has not been an action marked done yet, leave the list of
 +# items on the todo list unchanged.
 +reschedule_last_action () {
 +      tail -n 1 "$done" | cat - "$todo" >"$todo".new
 +      sed -e \$d <"$done" >"$done".new
 +      mv -f "$todo".new "$todo"
 +      mv -f "$done".new "$done"
 +}
 +
  append_todo_help () {
        git stripspace --comment-lines >>"$todo" <<\EOF
  
@@@ -262,12 -252,6 +262,12 @@@ pick_one () 
        output eval git cherry-pick \
                        ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
                        "$strategy_args" $empty_args $ff "$@"
 +
 +      # If cherry-pick dies it leaves the to-be-picked commit unrecorded. Reschedule
 +      # previous task so this commit is not lost.
 +      ret=$?
 +      case "$ret" in [01]) ;; *) reschedule_last_action ;; esac
 +      return $ret
  }
  
  pick_one_preserving_merges () {
@@@ -502,7 -486,7 +502,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)
                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.
                git notes copy --for-rewrite=rebase < "$rewritten_list" ||
                true # we don't care if this copying failed
        } &&
 -      if test -x "$GIT_DIR"/hooks/post-rewrite &&
 -              test -s "$rewritten_list"; then
 -              "$GIT_DIR"/hooks/post-rewrite rebase < "$rewritten_list"
 +      hook="$(git rev-parse --git-path hooks/post-rewrite)"
 +      if test -x "$hook" && test -s "$rewritten_list"; then
 +              "$hook" rebase < "$rewritten_list"
                true # we don't care if this hook failed
        fi &&
        warn "Successfully rebased and updated $head_name."
@@@ -890,7 -871,10 +887,10 @@@ first and then run 'git rebase --contin
                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
@@@ -977,13 -961,14 +977,13 @@@ els
        revisions=$onto...$orig_head
        shortrevisions=$shorthead
  fi
 -git rev-list $merges_option --pretty=oneline --abbrev-commit \
 -      --abbrev=7 --reverse --left-right --topo-order \
 -      $revisions | \
 +git rev-list $merges_option --pretty=oneline --reverse --left-right --topo-order \
 +      $revisions ${restrict_revision+^$restrict_revision} | \
        sed -n "s/^>//p" |
 -while read -r shortsha1 rest
 +while read -r sha1 rest
  do
  
 -      if test -z "$keep_empty" && is_empty_commit $shortsha1 && ! is_merge_commit $shortsha1
 +      if test -z "$keep_empty" && is_empty_commit $sha1 && ! is_merge_commit $sha1
        then
                comment_out="$comment_char "
        else
  
        if test t != "$preserve_merges"
        then
 -              printf '%s\n' "${comment_out}pick $shortsha1 $rest" >>"$todo"
 +              printf '%s\n' "${comment_out}pick $sha1 $rest" >>"$todo"
        else
 -              sha1=$(git rev-parse $shortsha1)
                if test -z "$rebase_root"
                then
                        preserve=t
                if test f = "$preserve"
                then
                        touch "$rewritten"/$sha1
 -                      printf '%s\n' "${comment_out}pick $shortsha1 $rest" >>"$todo"
 +                      printf '%s\n' "${comment_out}pick $sha1 $rest" >>"$todo"
                fi
        fi
  done
        git rev-list $revisions |
        while read rev
        do
 -              if test -f "$rewritten"/$rev -a "$(sane_grep "$rev" "$state_dir"/not-cherry-picks)" = ""
 +              if test -f "$rewritten"/$rev && test "$(sane_grep "$rev" "$state_dir"/not-cherry-picks)" = ""
                then
                        # Use -f2 because if rev-list is telling us this commit is
                        # not worthwhile, we don't want to track its multiple heads,
                        # just the history of its first-parent for others that will
                        # be rebasing on top of it
                        git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$dropped"/$rev
 -                      short=$(git rev-list -1 --abbrev-commit --abbrev=7 $rev)
 -                      sane_grep -v "^[a-z][a-z]* $short" <"$todo" > "${todo}2" ; mv "${todo}2" "$todo"
 +                      sha1=$(git rev-list -1 $rev)
 +                      sane_grep -v "^[a-z][a-z]* $sha1" <"$todo" > "${todo}2" ; mv "${todo}2" "$todo"
                        rm "$rewritten"/$rev
                fi
        done
@@@ -1045,12 -1031,9 +1045,12 @@@ test -s "$todo" || echo noop >> "$todo
  test -n "$autosquash" && rearrange_squash "$todo"
  test -n "$cmd" && add_exec_commands "$todo"
  
 +todocount=$(git stripspace --strip-comments <"$todo" | wc -l)
 +todocount=${todocount##* }
 +
  cat >>"$todo" <<EOF
  
 -$comment_char Rebase $shortrevisions onto $shortonto
 +$comment_char Rebase $shortrevisions onto $shortonto ($todocount command(s))
  EOF
  append_todo_help
  git stripspace --comment-lines >>"$todo" <<\EOF
@@@ -1069,7 -1052,6 +1069,7 @@@ has_action "$todo" |
        return 2
  
  cp "$todo" "$todo".backup
 +collapse_todo_ids
  git_sequence_editor "$todo" ||
        die_abort "Could not execute editor"