Unfortunately v3 still doesn't work. 'git ls-files NFD' works but 'git ls-files NFC' does not. I think it better to test both "ls-config NFD" and "ls-config NFC". The reason of the failure seems to be the same as v2, but I describe it here in more detail (or too detailed). (one of?) The problem is the_repository->config->hash_initialized is set to 1 before the_repository->commondir is set to ".git". Due to this, .git/config is never read, and precomposed_unicode is never set to 1 (remains -1). run_builtin() { setup_git_directory() { strbuf_getcwd() { # setup.c:1542 precompose_{strbuf,string}_if_needed() { # precomposed_unicode is still -1 git_congig_get_bool("core.precomposeunicode") { git_config_check_init() { repo_read_config() { git_config_init() { # !!! the_repository->config->hash_initialized=1 # !!! } # does not read .git/config since # the_repository->commondir is still NULL } } } returns without converting to NFC } returns cwd in NFD } setup_discovered_git_dir() { set_git_work_tree(".") { repo_set_worktree() { # this function indirectly calls strbuf_getcwd() # --> precompose_{strbuf,string}_if_needed() --> # {git,repo}_config_get_bool("core.precomposeunicode"), # but does not try to read .git/config since # the_repository->config->hash_initialized # is already set to 1 above. And it will not read # .git/config even if hash_initialized is 0 # since the_repository->commondir is still NULL. the_repository->worktree = NFD } } } setup_git_env() { repo_setup_gitdir() { repo_set_commondir() { # finally commondir is set here the_repository->commondir = ".git" } } } } // END setup_git_directory precompose_argv_prefix() { # since the_repository->config->hash_initialized is still 1 # .git/config is not read and precomposed_unicode remains -1, # and argv (if in NFD) is not converted to NFC } cmd_ls_files() { parse_pathspec(.., argv /* may be in NFD, see above */) { init_path_spec_item() { prefix_path_gently() { abspath_part_inside_repo() { work_tree = precomose_string_if_needed( get_git_work_gree()) # get_git_work_tree() returns NFD, and # precompose_string_if_needed() does not # convert it to NFC since # the_repository->config->hash_initialized is 1 worktree = NFD returns 0 for "ls-files NFD" since both argv and work_tree are in NFD, but returns -1 for "ls-files NFC" since argv is in NFC. } returns NULL for "ls-files NFC" } die() at pathspec.c:499 for "ls-files NFC" } } } } END run_builtin I don't know how to fix the problem, but I think it better to avoid calling precompose_{strbuf,string}_if_needed() before commondir is set to ".git" and .git/config is successfully read. Or reset the_repository->config->hash_initialized at some point?