git-diff-index in default mode has an annoying behaviour wrt filenames containing non-ascii chars. As suggested by Pasky, we can use -z mode, which gives us a much better way of handling all other special chars. With associated testcases ensuring it works with simple and double quotes, backslashes, and spaces as well. Signed-off-by: Yann Dirson <ydirson@xxxxxxxxxx> --- cg-commit | 10 ++++---- t/t9900-specialchars.sh | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/cg-commit b/cg-commit index 8dac57c..9ec8289 100755 --- a/cg-commit +++ b/cg-commit @@ -274,8 +274,8 @@ if [ "$ARGS" -o "$_git_relpath" ]; then echo "${_git_relpath}$file" >>"$filter" done - eval "commitfiles=($(cat "$filter" | path_xargs git-diff-index -r -m HEAD -- | \ - sed -e 's/"\|\\/\\&/g' -e 's/^\([^ ]*\)\(.\) \(.*\)\( .*\)*$/"\2 \3"/'))" + eval "commitfiles=($(cat "$filter" | path_xargs git-diff-index -z -r -m HEAD -- | \ + perl -n0e 'if (defined $meta) { s/([\"\\])/\\\1/; print "\"$meta $_\"\n"; $meta=undef } else { $meta = (split(/\s/))[4] }'))" customfiles=1 [ "$review" ] && cat "$filter" | path_xargs git-diff-index -r -m -p HEAD -- > "$PATCH" @@ -292,8 +292,8 @@ else if [ ! "$ignorecache" ]; then # \t instead of the tab character itself works only with new # sed versions. - eval "commitfiles=($(git-diff-index -r -m HEAD | \ - sed -e 's/"\|\\/\\&/g' -e 's/^\([^ ]*\)\(.\) \(.*\)\( .*\)*$/"\2 \3"/'))" + eval "commitfiles=($(git-diff-index -z -r -m HEAD | \ + perl -n0e 'if (defined $meta) { s/([\"\\])/\\\1/; print "\"$meta $_\"\n"; $meta=undef } else { $meta = (split(/\s/))[4] }'))" if [ -s "$_git/commit-ignore" ]; then newcommitfiles=() @@ -439,7 +439,7 @@ __END__ exit 1 fi if [ ! "$ignorecache" ] && [ ! "$merging" ] && [ ! "$review" ]; then - eval "newcommitfiles=($(grep ^CG:F "$LOGMSG2" | sed 's/^CG:F *\(.*\)$/"\1"/'))" + eval "newcommitfiles=($(grep ^CG:F "$LOGMSG2" | sed -e 's/\"/\\&/g' -e 's/^CG:F *\(.*\)$/"\1"/'))" if [ ! "$force" ] && [ ! "${newcommitfiles[*]}" ]; then rm "$LOGMSG" "$LOGMSG2" [ "$quiet" ] && exit 0 || die 'Nothing to commit' diff --git a/t/t9900-specialchars.sh b/t/t9900-specialchars.sh new file mode 100755 index 0000000..a705052 --- /dev/null +++ b/t/t9900-specialchars.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2006 Yann Dirson +# +test_description="Tests various commands with shell-special chars. + +Filenames with embedded spaces, quotes, non-ascii letter, you name it." + +. ./test-lib.sh + +rm -rf .git +cg-init -m . + +touch "a space" +test_expect_success 'add file with space' 'cg-add "a space"' +test_expect_success 'commit file with space' 'cg-commit -m . "a space"' + +touch "a'quote" +test_expect_success 'add file with quote' "cg-add \"a'quote\"" +test_expect_success 'commit file with quote' "cg-commit -m . \"a'quote\"" + +touch "d\"quote" +test_expect_success 'add file with accent' 'cg-add "d\"quote"' +test_expect_success 'commit file with quote' 'cg-commit -m . "d\"quote"' + +touch "back\\slash" +test_expect_success 'add file with accent' 'cg-add "back\\slash"' +test_expect_success 'commit file with quote' 'cg-commit -m . "back\\slash"' + +touch "acc�" +test_expect_success 'add file with accent' "cg-add acc�" +test_expect_success 'commit file with quote' "cg-commit -m . acc�" + +## same without a file arg to cg-commit + +rm -rf * .git +cg-init -m . + +touch "a space" +test_expect_success 'add file with space' 'cg-add "a space"' +test_expect_success 'commit file with space' 'cg-commit -m .' + +touch "a'quote" +test_expect_success 'add file with quote' "cg-add \"a'quote\"" +test_expect_success 'commit file with quote' "cg-commit -m ." + +touch "d\"quote" +test_expect_success 'add file with accent' 'cg-add "d\"quote"' +test_expect_success 'commit file with quote' 'cg-commit -m .' + +touch "back\\slash" +test_expect_success 'add file with accent' 'cg-add "back\\slash"' +test_expect_success 'commit file with quote' 'cg-commit -m .' + +touch "acc�" +test_expect_success 'add file with accent' "cg-add acc�" +test_expect_success 'commit file with quote' "cg-commit -m ." + +test_done - : send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html