@@ -35,8 +35,6 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
*/
rev.diffopt.ita_invisible_in_index = 1;
- precompose_argv(argc, argv);
-
argc = setup_revisions(argc, argv, &rev, NULL);
while (1 < argc && argv[1][0] == '-') {
if (!strcmp(argv[1], "--base"))
@@ -25,7 +25,6 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
repo_init_revisions(the_repository, &rev, prefix);
rev.abbrev = 0;
- precompose_argv(argc, argv);
argc = setup_revisions(argc, argv, &rev, NULL);
for (i = 1; i < argc; i++) {
@@ -126,7 +126,6 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
memset(&s_r_opt, 0, sizeof(s_r_opt));
s_r_opt.tweak = diff_tree_tweak_rev;
- precompose_argv(argc, argv);
argc = setup_revisions(argc, argv, opt, &s_r_opt);
memset(&w, 0, sizeof(w));
@@ -452,7 +452,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
init_diff_ui_defaults();
git_config(git_diff_ui_config, NULL);
- precompose_argv(argc, argv);
+ prefix = precompose_argv_prefix(argc, argv, prefix);
repo_init_revisions(the_repository, &rev, prefix);
@@ -1257,7 +1257,7 @@ static int compute_summary_module_list(struct object_id *head_oid,
git_config(git_diff_basic_config, NULL);
init_revisions(&rev, info->prefix);
rev.abbrev = 0;
- precompose_argv(diff_args.nr, diff_args.v);
+ precompose_argv_prefix(diff_args.nr, diff_args.v, NULL);
setup_revisions(diff_args.nr, diff_args.v, &rev, NULL);
rev.diffopt.output_format = DIFF_FORMAT_NO_OUTPUT | DIFF_FORMAT_CALLBACK;
rev.diffopt.format_callback = submodule_summary_callback;
@@ -60,32 +60,44 @@ void probe_utf8_pathname_composition(void)
strbuf_release(&path);
}
+static inline const char *precompose_string_if_needed(const char *in,
+ iconv_t ic_precompose)
+{
+ size_t inlen;
+ size_t outlen;
+ if (has_non_ascii(in, (size_t)-1, &inlen)) {
+ char *out = reencode_string_iconv(in, inlen, ic_precompose,
+ 0, &outlen);
+ if (out && outlen == inlen && !memcmp(in, out, outlen))
+ free(out); /* identical: no need to return a new one */
+ else
+ in = out;
+ }
+ return in;
+}
-void precompose_argv(int argc, const char **argv)
+const char *precompose_argv_prefix(int argc, const char **argv, const char *prefix)
{
int i = 0;
- const char *oldarg;
- char *newarg;
iconv_t ic_precompose;
+ git_config_get_bool("core.precomposeunicode", &precomposed_unicode);
if (precomposed_unicode != 1)
- return;
+ return NULL;
ic_precompose = iconv_open(repo_encoding, path_encoding);
if (ic_precompose == (iconv_t) -1)
- return;
+ return NULL;
while (i < argc) {
- size_t namelen;
- oldarg = argv[i];
- if (has_non_ascii(oldarg, (size_t)-1, &namelen)) {
- newarg = reencode_string_iconv(oldarg, namelen, ic_precompose, 0, NULL);
- if (newarg)
- argv[i] = newarg;
- }
+ argv[i] = precompose_string_if_needed(argv[i], ic_precompose);
i++;
}
+ if (prefix) {
+ prefix = precompose_string_if_needed(prefix, ic_precompose);
+ }
iconv_close(ic_precompose);
+ return prefix;
}
@@ -28,7 +28,7 @@ typedef struct {
struct dirent_prec_psx *dirent_nfc;
} PREC_DIR;
-void precompose_argv(int argc, const char **argv);
+const char *precompose_argv_prefix(int argc, const char **argv, const char *prefix);
void probe_utf8_pathname_composition(void);
PREC_DIR *precompose_utf8_opendir(const char *dirname);
@@ -252,9 +252,9 @@ typedef unsigned long uintptr_t;
#ifdef PRECOMPOSE_UNICODE
#include "compat/precompose_utf8.h"
#else
-static inline void precompose_argv(int argc, const char **argv)
+static inline const char *precompose_argv_prefix(int argc, const char **argv, const char *prefix)
{
- ; /* nothing */
+ return prefix;
}
#define probe_utf8_pathname_composition()
#endif
@@ -420,7 +420,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
int nongit_ok;
prefix = setup_git_directory_gently(&nongit_ok);
}
-
+ prefix = precompose_argv_prefix(argc, argv, prefix);
if (use_pager == -1 && p->option & (RUN_SETUP | RUN_SETUP_GENTLY) &&
!(p->option & DELAY_PAGER_CONFIG))
use_pager = check_pager_config(p->cmd);
@@ -869,7 +869,6 @@ int parse_options(int argc, const char **argv, const char *prefix,
usage_with_options(usagestr, options);
}
- precompose_argv(argc, argv);
free(real_options);
free(ctx.alias_groups);
return parse_options_end(&ctx);
@@ -191,6 +191,22 @@ test_expect_failure 'handle existing decomposed filenames' '
test_must_be_empty untracked
'
+test_expect_success "unicode decomposed: git restore -p . " '
+ DIRNAMEPWD=dir.Odiarnfc &&
+ DIRNAMEINREPO=dir.$Adiarnfc &&
+ export DIRNAMEPWD DIRNAMEINREPO &&
+ git init $DIRNAMEPWD &&
+ (
+ cd $DIRNAMEPWD &&
+ mkdir $DIRNAMEINREPO &&
+ cd $DIRNAMEINREPO &&
+ echo "Initial" >file &&
+ git add file &&
+ echo "More stuff" >>file &&
+ echo y | git restore -p .
+ )
+'
+
# Test if the global core.precomposeunicode stops autosensing
# Must be the last test case
test_expect_success "respect git config --global core.precomposeunicode" '