summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2021-02-12 14:21:04 -0800
committerLibravatar Junio C Hamano <gitster@pobox.com>2021-02-12 14:21:04 -0800
commit8b25dee6155fd3816f62649da196a4f42cf5584e (patch)
treeebf471c8cceee2aeed2e567fb485624a15613a50
parentMerge branch 'jk/complete-branch-force-delete' (diff)
parentMacOS: precompose_argv_prefix() (diff)
downloadtgif-8b25dee6155fd3816f62649da196a4f42cf5584e.tar.xz
Merge branch 'tb/precompose-prefix-too'
When commands are started from a subdirectory, they may have to compare the path to the subdirectory (called prefix and found out from $(pwd)) with the tracked paths. On macOS, $(pwd) and readdir() yield decomposed path, while the tracked paths are usually normalized to the precomposed form, causing mismatch. This has been fixed by taking the same approach used to normalize the command line arguments. * tb/precompose-prefix-too: MacOS: precompose_argv_prefix()
-rw-r--r--builtin/diff-files.c2
-rw-r--r--builtin/diff-index.c2
-rw-r--r--builtin/diff-tree.c2
-rw-r--r--builtin/diff.c2
-rw-r--r--builtin/submodule--helper.c2
-rw-r--r--compat/precompose_utf8.c52
-rw-r--r--compat/precompose_utf8.h2
-rw-r--r--git-compat-util.h4
-rw-r--r--git.c2
-rw-r--r--parse-options.c2
-rwxr-xr-xt/t3910-mac-os-precompose.sh16
11 files changed, 59 insertions, 29 deletions
diff --git a/builtin/diff-files.c b/builtin/diff-files.c
index 4742a4559b..bb85266102 100644
--- a/builtin/diff-files.c
+++ b/builtin/diff-files.c
@@ -36,7 +36,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
*/
rev.diffopt.ita_invisible_in_index = 1;
- precompose_argv(argc, argv);
+ prefix = precompose_argv_prefix(argc, argv, prefix);
argc = setup_revisions(argc, argv, &rev, NULL);
while (1 < argc && argv[1][0] == '-') {
diff --git a/builtin/diff-index.c b/builtin/diff-index.c
index 7f5281c461..c33d7af478 100644
--- a/builtin/diff-index.c
+++ b/builtin/diff-index.c
@@ -25,7 +25,7 @@ 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);
+ prefix = precompose_argv_prefix(argc, argv, prefix);
argc = setup_revisions(argc, argv, &rev, NULL);
for (i = 1; i < argc; i++) {
diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c
index 9fc95e959f..178d12f07f 100644
--- a/builtin/diff-tree.c
+++ b/builtin/diff-tree.c
@@ -126,7 +126,7 @@ 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);
+ prefix = precompose_argv_prefix(argc, argv, prefix);
argc = setup_revisions(argc, argv, opt, &s_r_opt);
memset(&w, 0, sizeof(w));
diff --git a/builtin/diff.c b/builtin/diff.c
index 5cfe1717e8..0f4859abf7 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -453,7 +453,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);
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index c2bd882d17..9d505a6329 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -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;
diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c
index 136250fbf6..ec560565a8 100644
--- a/compat/precompose_utf8.c
+++ b/compat/precompose_utf8.c
@@ -60,32 +60,46 @@ void probe_utf8_pathname_composition(void)
strbuf_release(&path);
}
-
-void precompose_argv(int argc, const char **argv)
+static inline const char *precompose_string_if_needed(const char *in)
{
- int i = 0;
- const char *oldarg;
- char *newarg;
- iconv_t ic_precompose;
+ size_t inlen;
+ size_t outlen;
+ if (has_non_ascii(in, (size_t)-1, &inlen)) {
+ iconv_t ic_prec;
+ char *out;
+ if (precomposed_unicode < 0)
+ git_config_get_bool("core.precomposeunicode", &precomposed_unicode);
+ if (precomposed_unicode != 1)
+ return in;
+ ic_prec = iconv_open(repo_encoding, path_encoding);
+ if (ic_prec == (iconv_t) -1)
+ return in;
+
+ out = reencode_string_iconv(in, inlen, ic_prec, 0, &outlen);
+ if (out) {
+ if (outlen == inlen && !memcmp(in, out, outlen))
+ free(out); /* no need to return indentical */
+ else
+ in = out;
+ }
+ iconv_close(ic_prec);
- if (precomposed_unicode != 1)
- return;
+ }
+ return in;
+}
- ic_precompose = iconv_open(repo_encoding, path_encoding);
- if (ic_precompose == (iconv_t) -1)
- return;
+const char *precompose_argv_prefix(int argc, const char **argv, const char *prefix)
+{
+ int i = 0;
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]);
i++;
}
- iconv_close(ic_precompose);
+ if (prefix) {
+ prefix = precompose_string_if_needed(prefix);
+ }
+ return prefix;
}
diff --git a/compat/precompose_utf8.h b/compat/precompose_utf8.h
index 6f843d3e1a..d70b84665c 100644
--- a/compat/precompose_utf8.h
+++ b/compat/precompose_utf8.h
@@ -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);
diff --git a/git-compat-util.h b/git-compat-util.h
index 5d5e47fbe2..838246289c 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -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
diff --git a/git.c b/git.c
index b5f63d346b..9bc077a025 100644
--- a/git.c
+++ b/git.c
@@ -423,7 +423,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);
diff --git a/parse-options.c b/parse-options.c
index f0507432ee..fbea16eaf5 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -869,7 +869,7 @@ int parse_options(int argc, const char **argv, const char *prefix,
usage_with_options(usagestr, options);
}
- precompose_argv(argc, argv);
+ precompose_argv_prefix(argc, argv, NULL);
free(real_options);
free(ctx.alias_groups);
return parse_options_end(&ctx);
diff --git a/t/t3910-mac-os-precompose.sh b/t/t3910-mac-os-precompose.sh
index a0b9208ce8..898267a6bd 100755
--- a/t/t3910-mac-os-precompose.sh
+++ b/t/t3910-mac-os-precompose.sh
@@ -194,6 +194,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" '