Git和Mac OS X上的变音问题

今天我在Mac OS X上发现了一个Git的bug。

例如,我将在一开始就提交一个名称为ü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上有德文特殊字符的问题。有没有解决scheme让Git读取文件名正确?

在mac上启用core.precomposeunicode

 git config --global core.precomposeunicode true 

为了这个工作,你至less需要Git 1.8.2。

山狮随船1.7.5。 要获得更新的git,可以使用git-osx-installer或homebrew (需要Xcode)。

而已。

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

在Unicode中,Ü可以用两种方式表示,一种是单独的,另一种是U +“结合变音符号”。 一个Unicodestring可以同时包含两种forms,但由于两者都有混淆,文件系统通过将每个混合U设置为Ü或U +“组合变音符”来规范unicodestring。

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

显然Git不关心这一点,只是使用文件名的字节序列,这导致了你有问题。

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

要使git add file在Mac OS X上的文件名中使用变音符号git add file ,您可以使用iconv将文件pathstring从合成文件转换为标准分解的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' 

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

 git config core.precomposeunicode.true 

为了确保新的仓库获得该标志,也运行:

 git config --global core.precomposeunicode true 

以下是manpage中的相关代码片段:

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

下面放在〜/ .gitconfig为我工作在10.12.1 Sierra为UTF-8名称:

 precomposeunicode = true quotepath = false 

第一个选项是需要的,所以git'理解'UTF-8和第二个,所以它不会逃离字符。

它是正确的。

你的文件名是UTF-8 ,代表拉丁文大写字母U +合并字符(Unicode 0x0308,UTF8 0xCC 0x88),而不是LATIN CAPITAL LETTER U WITH DIAERESIS(Unicode 0x00dc,utf8 0xc3 0x9c)。 Mac OS X HFS文件系统以这种方式分解Unicode 。 Git依次显示非ASCII文件名字节的八进制转义forms。

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

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

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