Mac OS X上的Git和Umlaut问题


69

今天,我在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正确读取文件名?


Answers:


87

在Mac上启用core.precomposeunicode

git config --global core.precomposeunicode true

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

Mountain Lion随附1.7.5。要获得更新的git,请使用git-osx-installerhomebrew(需要Xcode)。

而已。


24
奇怪的是,对我来说相反的工作(git config --global core.precomposeunicode false)。我正在运行OS X 10.9.2和Git 1.8.5.2,并将文件存储在具有HFS +文件系统的磁盘映像上。苹果可能会改变其实现方式吗?
菲利普2014年

1
荣誉@Philipp —这项改变成功了。这将对答案进行重要的更新!
danyowdee 2014年

2
我必须将配置参数设置为false在OS X 10.10和Git 2.0.0上。我不必克隆也不必再次结帐。它只是工作。
JB Rainsberger

2
对我来说,将其设置为true(在Git 2.2.0 / Mac OS X 10.9.5上为默认设置)会错误地显示5个具有异常名称的文件为未跟踪文件。图4用双引号括起来。如果我将其设置为false,则将跟踪其中的4个,但没有双引号的将保持未跟踪状态。这4个字符可能带有朝鲜语字符,而第5个字符则具有变音符号。有任何想法吗?
山姆·布莱曼2014年

2
尽管只是省略了,但这对我还是有用的--global
Tim-Erwin

32

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

在Unicode中,可以用两种方式表示Ü,一种是仅由Ü表示,另一种是由U +“组合变音符”表示。Unicode字符串可以同时包含两种形式,但是由于同时具有两种形式,因此文件系统通过将每个变音符号-U设置为Ü或U +“组合变音符号”来规范化unicode字符串。

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

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

邮件列表线程Git,Mac OS X和德语特殊字符中有一个补丁,因此Git在标准化后比较文件名。


2
Umlaut规范化是一个巨大的错误。文件系统的构建方式不应使运行在顶部的事物必须“关心”正在发生的奇怪修改。肯·汤普森(Ken Thompson)会说这不是功能,而是一种症状。它几乎可以破坏任何系统-不仅是git。我最近复制了一个Web转储。Umlaut规范化将其破坏了,因为html文件引用了文件名中带有变音符号的图像。我敢打赌这也是一个安全问题。
wnrph

1
实际上,Linux并不总是使用NFC。Linux(与内核和文件系统一样)只是不在乎,而是将文件名视为字节数组。规范化取决于C库和应用程序;大多数使用NFC,但这只是一个约定。
sleske 2014年

8

〜/ .gitconfig中的以下命令适用于我在10.12.1 Sierra上使用UTF-8名称:

precomposeunicode = true
quotepath = false

第一个选项是必需的,以便git'理解'UTF-8,第二个选项是使它不会转义字符。


5

git add file在Mac OS X上处理文件名中的变音符号,您可以使用来将文件路径字符串从composite转换为标准分解的UTF-8 iconv

# 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'

我试过了,但无法正常工作。它仍然很混乱,无法找到文件。
Petriborg

3

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

git config core.precomposeunicode.true

为了确保新的存储库获得该标志,还请运行:

git config --global core.precomposeunicode true

以下是手册页中的相关代码段:

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


1

它是正确的。

您的文件名采用UTF-8格式,Ü表示为拉丁字母大写U +组合大写字母(Unicode 0x0308,utf8 0xcc 0x88)而不是拉丁字母大写U与DIAERESIS(Unicode 0x00dc,utf8 0xc3 0x9c)。在Mac OS X的HFS文件系统分解的Unicode在这样的方式Git依次显示非ASCII文件名字节的八进制转义形式。

请注意,Unicode文件名可以使您的存储库不可移植。例如,msysgit在处理Unicode filenames时遇到问题


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.