threads / discuss / 24297

Commit ending in \ breaks rebase commitlog parsing

Subject: Commit ending in \ breaks rebase commitlog parsing

## tl;dr

2 messages between Jul 5, 2010 and Jul 6, 2010.

replies: 1people: 2as markdown or json

Joshua ben Jore· Jul 5, 2010, 20:24 UTC · lore

Hi, Through typos on my part, I have a commit with a message ending in a \.

    Prefer ! and && to \\not\ and 'and\

The rebase command or something it is using is parsing this incorrectly and leaving my .git in a "bad" state.

    pick 43d2369 Prefer ! and && to
    ot and 'and8c7ee99 Upgrade to Devel::PPPort-3.19
That should have read:
    pick 43d2369 Perefer ! and && to \\not\ and 'and\
    pick 8c7ee99 Upgrade to Devel::PPPort-3.19

Initially, I started editing my pick list to be proper and was receiving some strange sort of parsing errors but now am not. I'd manually edited the backup picklist file in .git as well. For a repro, I tried the following. This also seems to show up a perhaps related problem of a commit message consisting of only a single backslash. The pick list just *drops* the commit, perhaps because some layer thinks the commit message is empty?

    mkdir slash
    cd slash
    git init
    echo data1 > foo
    git add foo
    git commit -m root
    export PARENT=$(git rev-parse HEAD)
    echo data2 > foo
    git add foo
    git commit -m \\
    echo data3 > foo
    git add foo
    git commit -m next
    git rebase -i $PARENT
    # .git/rebase-merge/git-rebase-todo is now incorrect
Josh
Junio C Hamano· Jul 6, 2010, 05:57 UTC · re: Joshua ben Jore · lore

Re: Commit ending in \ breaks rebase commitlog parsing

Joshua ben Jore <twists@gmail.com> writes:
> ... The
> pick list just *drops* the commit, perhaps because some layer thinks
> the commit message is empty?

The problem is that we use "read" in shell to read these insn in the todo list line by line, but a backslash at the end of line acts as a line continuation signal. POSIX compliant shells are supposed to understand "read -r", so perhaps something like this may help.

 git-rebase--interactive.sh |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index ed57552..31e6860 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -450,7 +450,7 @@ record_in_rewritten() {
 
 do_next () {
 	rm -f "$MSG" "$AUTHOR_SCRIPT" "$AMEND" || exit
-	read command sha1 rest < "$TODO"
+	read -r command sha1 rest < "$TODO"
 	case "$command" in
 	'#'*|''|noop)
 		mark_action_done
@@ -591,7 +591,7 @@ do_rest () {
 # skip picking commits whose parents are unchanged
 skip_unnecessary_picks () {
 	fd=3
-	while read command sha1 rest
+	while read -r command sha1 rest
 	do
 		# fd=3 means we skip the command
 		case "$fd,$command,$(git rev-parse --verify --quiet $sha1^)" in
@@ -644,13 +644,13 @@ rearrange_squash () {
 	test -s "$1.sq" || return
 
 	used=
-	while read pick sha1 message
+	while read -r pick sha1 message
 	do
 		case " $used" in
 		*" $sha1 "*) continue ;;
 		esac
 		echo "$pick $sha1 $message"
-		while read squash action msg
+		while read -r squash action msg
 		do
 			case "$message" in
 			"$msg"*)
@@ -891,7 +891,7 @@ first and then run 'git rebase --continue' again."
 			--abbrev=7 --reverse --left-right --topo-order \
 			$REVISIONS | \
 			sed -n "s/^>//p" |
-		while read shortsha1 rest
+		while read -r shortsha1 rest
 		do
 			if test t != "$PRESERVE_MERGES"
 			then

← back to recent threads