git-rebase--interactive.sh: use printf instead of echo to print commit message
authorBrandon Casey <drafnel@gmail.com>
Thu, 22 Jul 2010 19:15:11 +0000 (14:15 -0500)
committerJunio C Hamano <gitster@pobox.com>
Mon, 26 Jul 2010 06:14:18 +0000 (23:14 -0700)
On systems with an echo which defaults to the XSI-conformant behavior
(Solaris, or others using Ksh), echo will interpret certain backslashed
characters as control sequences. This can cause a problem for interactive
rebase when it is used to rebase commits whose commit "subject" (the first
line) contains any of these backslashed sequences. In this case, echo will
substitute the control sequence for the backslashed characters and either
the rebased commit message will differ from the original, or the rebase
process will fail. Neither is desirable.

So work around this issue by replacing the echo statements used to print
out portions of the commit message, with printf.

Also, add a test to test for this breakage.

Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
Acked-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git-rebase--interactive.sh
t/t3404-rebase-interactive.sh
index 31e68603f4e8124fd67f42c8aae6033a792892cb..b94c2a03867ddcd1fa0c2051f81cf14547b550f0 100755 (executable)
@@ -119,7 +119,7 @@ run 'git rebase --continue'"
 export GIT_CHERRY_PICK_HELP
 
 warn () {
 export GIT_CHERRY_PICK_HELP
 
 warn () {
-       echo "$*" >&2
+       printf '%s\n' "$*" >&2
 }
 
 output () {
 }
 
 output () {
@@ -606,7 +606,7 @@ skip_unnecessary_picks () {
                        fd=1
                        ;;
                esac
                        fd=1
                        ;;
                esac
-               echo "$command${sha1:+ }$sha1${rest:+ }$rest" >&$fd
+               printf '%s\n' "$command${sha1:+ }$sha1${rest:+ }$rest" >&$fd
        done <"$TODO" >"$TODO.new" 3>>"$DONE" &&
        mv -f "$TODO".new "$TODO" &&
        case "$(peek_next_command)" in
        done <"$TODO" >"$TODO.new" 3>>"$DONE" &&
        mv -f "$TODO".new "$TODO" &&
        case "$(peek_next_command)" in
@@ -649,12 +649,12 @@ rearrange_squash () {
                case " $used" in
                *" $sha1 "*) continue ;;
                esac
                case " $used" in
                *" $sha1 "*) continue ;;
                esac
-               echo "$pick $sha1 $message"
+               printf '%s\n' "$pick $sha1 $message"
                while read -r squash action msg
                do
                        case "$message" in
                        "$msg"*)
                while read -r squash action msg
                do
                        case "$message" in
                        "$msg"*)
-                               echo "$action $squash $action! $msg"
+                               printf '%s\n' "$action $squash $action! $msg"
                                used="$used$squash "
                                ;;
                        esac
                                used="$used$squash "
                                ;;
                        esac
@@ -895,7 +895,7 @@ first and then run 'git rebase --continue' again."
                do
                        if test t != "$PRESERVE_MERGES"
                        then
                do
                        if test t != "$PRESERVE_MERGES"
                        then
-                               echo "pick $shortsha1 $rest" >> "$TODO"
+                               printf '%s\n' "pick $shortsha1 $rest" >> "$TODO"
                        else
                                sha1=$(git rev-parse $shortsha1)
                                if test -z "$REBASE_ROOT"
                        else
                                sha1=$(git rev-parse $shortsha1)
                                if test -z "$REBASE_ROOT"
@@ -914,7 +914,7 @@ first and then run 'git rebase --continue' again."
                                if test f = "$preserve"
                                then
                                        touch "$REWRITTEN"/$sha1
                                if test f = "$preserve"
                                then
                                        touch "$REWRITTEN"/$sha1
-                                       echo "pick $shortsha1 $rest" >> "$TODO"
+                                       printf '%s\n' "pick $shortsha1 $rest" >> "$TODO"
                                fi
                        fi
                done
                                fi
                        fi
                done
index 47ca88fc5231a5e0689b43a35eb660285a73190d..9f03ce699e8f4c3c654065deae675d1a7b259c74 100755 (executable)
@@ -637,13 +637,19 @@ test_expect_success 'set up commits with funny messages' '
        git commit -a -m "end with slash\\" &&
        echo >>file1 &&
        test_tick &&
        git commit -a -m "end with slash\\" &&
        echo >>file1 &&
        test_tick &&
+       git commit -a -m "something (\000) that looks like octal" &&
+       echo >>file1 &&
+       test_tick &&
+       git commit -a -m "something (\n) that looks like a newline" &&
+       echo >>file1 &&
+       test_tick &&
        git commit -a -m "another commit"
 '
 
 test_expect_success 'rebase-i history with funny messages' '
        git rev-list A..funny >expect &&
        test_tick &&
        git commit -a -m "another commit"
 '
 
 test_expect_success 'rebase-i history with funny messages' '
        git rev-list A..funny >expect &&
        test_tick &&
-       FAKE_LINES="1 2" git rebase -i A &&
+       FAKE_LINES="1 2 3 4" git rebase -i A &&
        git rev-list A.. >actual &&
        test_cmp expect actual
 '
        git rev-list A.. >actual &&
        test_cmp expect actual
 '