Merge branch 'gr/rebase-i-drop-warn' into maint
authorJunio C Hamano <gitster@pobox.com>
Tue, 3 Nov 2015 23:32:30 +0000 (15:32 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 3 Nov 2015 23:32:30 +0000 (15:32 -0800)
Recent update to "rebase -i" that tries to sanity check the edited
insn sheet before it uses it has become too picky on Windows where
CRLF left by the editor is turned into a trailing CR on the line
read via the "read" built-in command.

* gr/rebase-i-drop-warn:
rebase-i: work around Windows CRLF line endings
t3404: "rebase -i" gets broken when insn sheet uses CR/LF line endings

1  2 
git-rebase--interactive.sh
t/t3404-rebase-interactive.sh
index d65c06eff36f09c982d66b11684d8f3ab3784393,b20cafcde4c8730cfe7c247274746cd4fa541676..30edb179259d634f20649fe7f74df3f0c58f10ec
@@@ -77,6 -77,10 +77,10 @@@ amend="$state_dir"/amen
  rewritten_list="$state_dir"/rewritten-list
  rewritten_pending="$state_dir"/rewritten-pending
  
+ # Work around Git for Windows' Bash whose "read" does not strip CRLF
+ # and leaves CR at the end instead.
+ cr=$(printf "\015")
  strategy_args=
  if test -n "$do_merge"
  then
@@@ -512,12 -516,16 +516,16 @@@ 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)
                mark_action_done
                ;;
+       "$cr")
+               # Work around CR left by "read" (e.g. with Git for Windows' Bash).
+               mark_action_done
+               ;;
        pick|p)
                comment_for_reflog pick
  
                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.
@@@ -750,15 -761,10 +758,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%%!*}"
                *" $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
                                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"
@@@ -896,6 -896,10 +904,10 @@@ check_bad_cmd_and_sha () 
                "$comment_char"*|''|noop|x|exec)
                        # Doesn't expect a SHA-1
                        ;;
+               "$cr")
+                       # Work around CR left by "read" (e.g. with Git for
+                       # Windows' Bash).
+                       ;;
                pick|p|drop|d|reword|r|edit|e|squash|s|fixup|f)
                        if ! check_commit_sha "${rest%%[        ]*}" "$lineno" "$1"
                        then
@@@ -1040,11 -1044,7 +1052,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
@@@ -1082,10 -1082,7 +1094,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
        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
index 3de0b1dcfdc9c5948c10e5e8c107a3820df9f357,2f97a3d9b7bd95494221b1dfdff7eb4ace940c8a..98eb49ac236e9e9d08d5da5167f7e257db173c41
@@@ -961,13 -961,13 +961,13 @@@ test_expect_success 'rebase -i produce
        set_fake_editor &&
        git rebase -i --onto I F branch-reflog-test &&
        cat >expect <<-\EOF &&
 -      rebase -i (start): checkout I
 -      rebase -i (pick): G
 -      rebase -i (pick): H
        rebase -i (finish): returning to refs/heads/branch-reflog-test
 +      rebase -i (pick): H
 +      rebase -i (pick): G
 +      rebase -i (start): checkout I
        EOF
 -      tail -n 4 .git/logs/HEAD |
 -      sed -e "s/.*    //" >actual &&
 +      git reflog -n4 HEAD |
 +      sed "s/[^:]*: //" >actual &&
        test_cmp expect actual
  '
  
@@@ -1102,27 -1102,6 +1102,27 @@@ test_expect_success 'rebase -i commits 
        test $(git cat-file commit HEAD | sed -ne \$p) = I
  '
  
 +test_expect_success 'rebase --continue removes CHERRY_PICK_HEAD' '
 +      git checkout -b commit-to-skip &&
 +      for double in X 3 1
 +      do
 +              test_seq 5 | sed "s/$double/&&/" >seq &&
 +              git add seq &&
 +              test_tick &&
 +              git commit -m seq-$double
 +      done &&
 +      git tag seq-onto &&
 +      git reset --hard HEAD~2 &&
 +      git cherry-pick seq-onto &&
 +      set_fake_editor &&
 +      test_must_fail env FAKE_LINES= git rebase -i seq-onto &&
 +      test -d .git/rebase-merge &&
 +      git rebase --continue &&
 +      git diff --exit-code seq-onto &&
 +      test ! -d .git/rebase-merge &&
 +      test ! -f .git/CHERRY_PICK_HEAD
 +'
 +
  rebase_setup_and_clean () {
        test_when_finished "
                git checkout master &&
@@@ -1261,4 -1240,16 +1261,16 @@@ test_expect_success 'static check of ba
        test E = $(git cat-file commit HEAD | sed -ne \$p)
  '
  
+ test_expect_success 'editor saves as CR/LF' '
+       git checkout -b with-crlf &&
+       write_script add-crs.sh <<-\EOF &&
+       sed -e "s/\$/Q/" <"$1" | tr Q "\\015" >"$1".new &&
+       mv -f "$1".new "$1"
+       EOF
+       (
+               test_set_editor "$(pwd)/add-crs.sh" &&
+               git rebase -i HEAD^
+       )
+ '
  test_done