[PATCH] Make cogito work with accented letters.
From: Yann Dirson <hidden>
Date: 2016-06-15 22:42:23
Subsystem:
the rest · Maintainer:
Linus Torvalds
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. This is an improved version of the previous patch, which fixes other commands like cg-switch which use tree_timewarp. A couple of other commands using git-diff-index still need to be fixed in a similar manner. Signed-off-by: Yann Dirson <redacted> --- cg-Xlib | 7 ++---- cg-commit | 10 ++++---- t/t9900-specialchars.sh | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 9 deletions(-)
diff --git a/cg-Xlib b/cg-Xlib
index 38172a0..e594986 100755
--- a/cg-Xlib
+++ b/cg-Xlib@@ -555,10 +555,9 @@ tree_timewarp() [ "$no_head_update" ] || git-update-ref HEAD "$branch" || : # Kill gone files - git-diff-tree -r "$base" "$branch" | - # match ":100755 000000 14d43b1abf... 000000000... D" - sed -ne 's/^:[^\t]* D\t//p' | - xargs rm -f -- + git-diff-tree -z --name-status -r "$base" "$branch" | + perl -n0e 'chomp; if (defined $meta) { print "$_\0" if $meta eq 'D'; $meta=undef } else { $meta = $_ }' | + xargs --null rm -f -- git-checkout-index -u -f -a # FIXME: Can produce bogus "contains only garbage" messages.
diff --git a/cg-commit b/cg-commit
index 8dac57c..1d8de92 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 --name-status -z -r -m HEAD -- | \ + perl -n0e 'chomp; if (defined $meta) { s/([\"\\])/\\\1/; print "\"$meta $_\"\n"; $meta=undef } else { $meta = $_ }'))" 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 --name-status -z -r -m HEAD | \ + perl -n0e 'chomp; if (defined $meta) { s/([\"\\])/\\\1/; print "\"$meta $_\"\n"; $meta=undef } else { $meta = $_ }'))" 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ént" +test_expect_success 'add file with accent' "cg-add accént" +test_expect_success 'commit file with quote' "cg-commit -m . accént" + +## 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ént" +test_expect_success 'add file with accent' "cg-add accént" +test_expect_success 'commit file with quote' "cg-commit -m ." + +test_done