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 上的元音变音问题的主要内容,如果未能解决你的问题,请参考以下文章