On 2014-05-05 23.46, Jeff King wrote: [] >> 2. Do all index filename comparisons under Mac OS X using a UTF-8 aware >> comparison function regardless if core.precomposeunicode is set. >> This would probably have bad performance, and somewhat >> defeats the point of converting the filenames at the >> readdir level in the first place. > > Right, I'm concerned about performance here, but I wonder if we can > reuse the name-hash solutions from ignorecase. Some short question, (sorry being short) What do you think about this: diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c index 95fe849..c807f38 100644 --- a/compat/precompose_utf8.c +++ b/compat/precompose_utf8.c @@ -57,6 +57,22 @@ void probe_utf8_pathname_composition(char *path, int len) } +char *inverscompose_str_len(const char *in, size_t insz, int *outsz) +{ + char *prec_str = NULL; + + if (has_non_ascii(in, insz, NULL)) { + int old_errno = errno; + prec_str = reencode_string_len(in, (int)insz, + precomposed_unicode ? path_encoding : repo_encoding, + precomposed_unicode ? repo_encoding : path_encoding, + outsz); + errno = old_errno; + } + return prec_str; +} + + void precompose_argv(int argc, const char **argv) { int i = 0; diff --git a/compat/precompose_utf8.h b/compat/precompose_utf8.h index 3b73585..b9ac099 100644 --- a/compat/precompose_utf8.h +++ b/compat/precompose_utf8.h @@ -26,6 +26,7 @@ typedef struct { struct dirent_prec_psx *dirent_nfc; } PREC_DIR; +char *inverscompose_str_len(const char *in, size_t insz, int *outsz); void precompose_argv(int argc, const char **argv); void probe_utf8_pathname_composition(char *, int); diff --git a/git-compat-util.h b/git-compat-util.h index f6d3a46..5ae5f57 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -177,7 +177,7 @@ typedef unsigned long uintptr_t; #ifdef PRECOMPOSE_UNICODE #include "compat/precompose_utf8.h" #else -#define precompose_str(in,i_nfd2nfc) +#define inverscompose_str_len(s,i,o) NULL #define precompose_argv(c,v) #define probe_utf8_pathname_composition(a,b) #endif diff --git a/name-hash.c b/name-hash.c index 97444d0..3c4a4ee 100644 --- a/name-hash.c +++ b/name-hash.c @@ -210,7 +210,7 @@ struct cache_entry *index_dir_exists(struct index_state *istate, const char *nam return NULL; } -struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int icase) +static struct cache_entry *index_file_exists_int(struct index_state *istate, const char *name, int namelen, int icase) { struct cache_entry *ce; struct hashmap_entry key; @@ -227,6 +227,25 @@ struct cache_entry *index_file_exists(struct index_state *istate, const char *na return NULL; } + +struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int icase) +{ + struct cache_entry *ce; + ce = index_file_exists_int(istate, name, namelen, icase); + if (ce) + return ce; + else { + int prec_len; + char *prec_name = inverscompose_str_len(name, namelen, &prec_len); + if (prec_name) { + ce = index_file_exists_int(istate, prec_name, prec_len, icase); + free(prec_name); + } + } + return ce; +} + + void free_name_hash(struct index_state *istate) { if (!istate->name_hash_initialized) diff --git a/t/t3910-mac-os-precompose.sh b/t/t3910-mac-os-precompose.sh index e4ba601..4414658 100755 --- a/t/t3910-mac-os-precompose.sh +++ b/t/t3910-mac-os-precompose.sh @@ -140,6 +140,22 @@ test_expect_success "Add long precomposed filename" ' git add * && git commit -m "Long filename" ' + +test_expect_success 'handle existing decomposed filenames' ' + git checkout master && + git reset --hard && + git checkout -b exist_decomposed && + echo content >"verbatim.$Adiarnfd" && + git -c core.precomposeunicode=false add "verbatim.$Adiarnfd" && + git commit -m "existing decomposed file" && + echo \"verbatim.A\\314\\210\" >expect && + git ls-files >actual && + test_cmp expect actual && + >expect && + git status | grep verbatim || : >actual && + test_cmp expect actual +' + # Test if the global core.precomposeunicode stops autosensing # Must be the last test case test_expect_success "respect git config --global core.precomposeunicode" ' diff --git a/utf8.c b/utf8.c index 77c28d4..fb8a99a 100644 --- a/utf8.c +++ b/utf8.c @@ -519,7 +519,7 @@ char *reencode_string_iconv(const char *in, size_t insz, iconv_t conv, int *outs char *out, *outpos; iconv_ibp cp; - outsz = insz; + outsz = 3*insz; /* for decompose */ outalloc = outsz + 1; /* for terminating NUL */ out = xmalloc(outalloc); outpos = out; -- To unsubscribe from this list: 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