Git 和 Mac OS X 上的元音变音问题

Posted

技术标签:

【中文标题】Git 和 Mac OS X 上的元音变音问题【英文标题】:Git and the Umlaut problem on Mac OS X 【发布时间】:2011-07-31 17:04:39 【问题描述】:

今天我在 Mac OS X 上发现了一个 Git 错误。

例如,我将提交一个名称为 überschrift.txt 的文件,该文件以德语特殊字符 Ü 开头。从命令git status 我得到以下输出。

Users-iMac: user$ git status

On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   "U\314\210berschrift.txt"
nothing added to commit but untracked files present (use "git add" to track)

Git 1.7.2 在 Mac OS X 上似乎存在德语特殊字符问题。 有没有办法让 Git 正确读取文件名?

【问题讨论】:

另见commit 3a59e59(2015 年 7 月 1 日)Karsten Blees (kblees)。 (由 Junio C Hamano -- gitster -- 合并于 commit 81bc521,2015 年 8 月 3 日) 【参考方案1】:

在 mac 上启用 core.precomposeunicode

git config --global core.precomposeunicode true

为此,您至少需要有 Git 1.8.2。

Mountain Lion 随 1.7.5 一起发布。要获得更新的 git,请使用 git-osx-installer 或 homebrew(需要 Xcode)。

就是这样。

【讨论】:

奇怪的是,对我来说,相反起作用了 (git config --global core.precomposeunicode false)。我正在运行 OS X 10.9.2 和 Git 1.8.5.2,文件存储在带有 HFS+ 文件系统的磁盘映像中。会不会是 Apple 改变了他们的实现方式? Kudos @Philipp — 这一改变起到了作用。这将对答案进行重要更新! 我必须在 OS X 10.10 和 Git 2.0.0 上将配置参数设置为 false。我不必再次克隆或结帐。它刚刚奏效。 对我来说,将其设置为 true(Git 2.2.0/Mac OS X 10.9.5 上的默认设置)错误地将 5 个名称异常的文件显示为未跟踪。 4 用双引号括起来。如果我将其设置为 false,则其中 4 个被跟踪,但没有双引号的那个仍然未被跟踪。 4 个可能有韩文字符,而第 5 个有变音符号。有什么想法吗? 这对我有用,虽然只是在省略 --global 之后。【参考方案2】:

原因是文件系统存储文件名的方式不同。

在Unicode中,Ü可以用两种方式表示,一种是单独用Ü表示,另一种是用U+“组合变音符号”表示。一个 Unicode 字符串可以同时包含这两种形式,但同时拥有这两种形式会让人感到困惑,文件系统通过将每个变音 U 设置为 Ü 或 U +“组合变音字符”来规范化 Unicode 字符串。

Linux 使用前一种方法,称为 Normal-Form-Composed(或 NFC),而 Mac OS X 使用后一种方法,称为 Normal-Form-Decomposed (NFD)。

显然Git 并不关心这一点,只是使用文件名的字节序列,这会导致您遇到的问题。

邮件列表线程 Git, Mac OS X and German special characters 中有一个补丁,以便 Git 在规范化后比较文件名。

【讨论】:

变音符号标准化是一个巨大的错误。文件系统不应该以某种方式构建,因此在顶部运行的东西必须“关心”发生的奇怪修改。 Ken Thompson 会说这不是特征,而是症状。它几乎可以破坏任何系统——不仅仅是 git。我最近复制了一个网络转储。变音符号规范化破坏了它,因为 html 文件引用了文件名中带有变音符号的图像。我敢打赌这也是一个安全问题。 实际上,Linux 并不总是使用 NFC。 Linux(如在内核和文件系统中)只是不关心并将文件名视为字节数组。规范化取决于 C 库和应用程序;大多数人使用 NFC,但这只是惯例。【参考方案3】:

~/.gitconfig 中的以下内容适用于 10.12.1 Sierra 上的 UTF-8 名称:

precomposeunicode = true
quotepath = false

需要第一个选项以便 git '理解' UTF-8 和第二个选项以便它不会转义字符。

【讨论】:

【参考方案4】:

要使git add file 在 Mac OS X 上使用文件名中的变音符号,您可以使用 iconv 将文件路径字符串从组合转换为规范分解的 UTF-8。

# test case

mkdir testproject
cd testproject

git --version    # git version 1.7.6.1
locale charmap   # UTF-8

git init
file=$'\303\234berschrift.txt'    # composed UTF-8 (Linux-compatible)
touch "$file"
echo 'Hello, world!' > "$file"

# convert composed into canonically decomposed UTF-8
# cf. http://codesnippets.joyent.com/posts/show/12251
# printf '%s' "$file" | iconv -f utf-8 -t utf-8-mac | LC_ALL=C vis -fotc 
#git add "$file"
git add "$(printf '%s' "$file" | iconv -f utf-8 -t utf-8-mac)"  

git commit -a -m 'This is my commit message!'
git show
git status
git ls-files '*'
git ls-files -z '*' | tr '\0' '\n'

touch $'caf\303\251 1' $'caf\303\251 2' $'caf\303\251 3'
git ls-files --other '*'
git ls-files -z --other '*' | tr '\0' '\n'

【讨论】:

我试过这个,但无法正常工作。它仍然很困惑,无法找到该文件。【参考方案5】:

将存储库的 OSX 特定 core.precomposeunicode 标志更改为 true:

git config core.precomposeunicode.true

为确保新存储库获得该标志,请同时运行:

git config --global core.precomposeunicode true

这是手册页中相关的 sn-p:

此选项仅由 Git 的 Mac OS 实现使用。什么时候 core.precomposeunicode=true, Git 还原 unicode 分解 Mac OS 完成的文件名。这在共享存储库时很有用 在 Mac OS 和 Linux 或 Windows 之间。 (适用于 Windows 1.7.10 或更高版本的 Git 需要,或 cygwin 1.7 下的 Git)。当为 false 时,文件名是 由 Git 完全透明处理,向后兼容 旧版本的 Git。

【讨论】:

【参考方案6】:

没错。

您的文件名在UTF-8 中,Ü 表示为拉丁文大写字母 U + COMBINING DIAERESIS (Unicode 0x0308, utf8 0xcc 0x88) 而不是拉丁文大写字母 U WITH DIAERESIS (Unicode 0x00dc, utf8 0xc3 0x9c)。 Mac OS X HFS file system decomposes Unicode in a such way。 Git 依次显示非 ASCII 文件名字节的八进制转义形式。

请注意,Unicode 文件名会使您的存储库不可移植。例如,msysgit has had problems dealing with Unicode filenames。

【讨论】:

【参考方案7】:

我的个人存储库也有类似的问题,所以我用 Python 3 编写了一个帮助脚本。你可以在这里获取它:https://github.com/sjtoik/umlaut-cleaner

脚本需要一些体力劳动,但并不多。

【讨论】:

以上是关于Git 和 Mac OS X 上的元音变音问题的主要内容,如果未能解决你的问题,请参考以下文章

MPMediaQuery:搜索时查找元音变音和特殊字符

Lucene 为带有元音变音的单词创建索引

国际字符(例如元音变音字符)在电子邮件地址的本地部分是不是有效?

有没有办法在 Android 中检测德国元音变音

转 升级Mac OS X上的GIT

将 UTF8 输入从 JSP 表单传输到 Spring 控制器会破坏元音变音[重复]