当前位置:  开发笔记 > 编程语言 > 正文

Git在文件名中与ä混淆

如何解决《Git在文件名中与ä混淆》经验,为你挑选了1个好方法。

由于带有ä的文件名,我的git情况很糟糕.这是一个很久以来可能存在的旧文件:

因此它被标记为未跟踪\ 303\244但是如果我将其删除,则将其标记为已删除,但使用\ 314\210.很混乱.我真的不关心文件,但想知道未来...

~/d/p/uniply ??? git status                                                                           master ?
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
  (use "git add ..." to include in what will be committed)

        "deployment/ec2/Prods\303\244ttning"

nothing added to commit but untracked files present (use "git add" to track)
~/d/p/uniply ??? rm deployment/ec2/Prodsättning                                                       master ?
~/d/p/uniply ??? git status                                                                           master ?
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add/rm ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

        deleted:    "deployment/ec2/Prodsa\314\210ttning"

no changes added to commit (use "git add" and/or "git commit -a")
~/d/p/uniply ??? git checkout -- deployment/ec2                                                       master ?
~/d/p/uniply ??? git status                                                                           master ?
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
  (use "git add ..." to include in what will be committed)

        "deployment/ec2/Prods\303\244ttning"

nothing added to commit but untracked files present (use "git add" to track)

Josh Lee.. 6

简短版本:你显然使用的是Mac,它将所有文件名转换为NFD,git用于盲目地将文件名视为字节,但现在将文件名转换为Mac上的NFC,以便更好地与其他系统兼容.因此,提交中的旧路径将表现得很奇怪.

$ python3
>>> import unicodedata
>>> unicodedata.normalize('NFC', b'a\314\210'.decode()).encode()
b'\xc3\xa4'
>>> unicodedata.normalize('NFD', b'\303\244'.decode()).encode()
b'a\xcc\x88'

这些格式的全名是规范化形式D(规范化分解)和规范化形式C(规范化分解,然后是规范化合成),它们在UAX#15中定义.

在不区分大小写的文件系统上可能会发生类似的事情 - 尝试在Windows或Mac上检查Linux内核树!-与您可能希望找到既包含一些回购的例外Makefilemakefile,但没有人在他们的脑子会检查在名为两个文件a\314\210\303\244,至少不是故意的.

核心问题是操作系统使相同的文件以不同的名称出现,因此git会根据所查找的内容看到不同的内容,如果它正在查找的内容不是操作系统提供的默认名称.

以下是这条道路今天的表现,从新鲜开始:

$ git init 
Initialized empty Git repository
$ git config --get core.precomposeUnicode
true  # this is the default in git 1.8.5 and higher
$ touch Prodsättning 
$ env -u LANG /bin/ls -b
Prodsa\314\210ttning
$ git status -s 
?? "Prods\303\244ttning"

通过ls在C语言环境中使用,我可以看到文件名中的字节,其中包含分解的值.但是git将角色组合成一个代码点,因此不同平台上的用户不会产生不同的结果.引入预组合unicode的补丁详细解释了各种git命令会发生什么.

如果提交中的两个文件具有相同的名称,直到Unicode规范化(或大小写折叠),那么当git检出文件时它们将显示为"战斗":

$ git clone https://gist.github.com/jleedev/228395a4378a75f9e630b989c346f153 
$ git reset --hard && git status -s 
HEAD is now at fe1abe4 
 M "Prods\303\244ttning"
$ git reset --hard && git status -s 
HEAD is now at fe1abe4 
 M "Prodsa\314\210ttning"

因此,如果您只想删除该文件,可以按照自己的意愿继续操作.如果您想要可靠地操作这些文件,请查看将core.precomposeUnicode选项设置为false,以便git将精确存储您告诉它的文件名字节,但这可能比它的价值更麻烦.我可能会建议创建一个将所有文件名转换为NFC的提交,以便git不会认为文件丢失.

在Git和Mac OS X上的Umlaut问题上,这个问题有一些较旧的答案,但其中许多都早于git规范化Unicode的能力,而设置core.quotepath=false只会在这种情况下引起混淆.



1> Josh Lee..:

简短版本:你显然使用的是Mac,它将所有文件名转换为NFD,git用于盲目地将文件名视为字节,但现在将文件名转换为Mac上的NFC,以便更好地与其他系统兼容.因此,提交中的旧路径将表现得很奇怪.

$ python3
>>> import unicodedata
>>> unicodedata.normalize('NFC', b'a\314\210'.decode()).encode()
b'\xc3\xa4'
>>> unicodedata.normalize('NFD', b'\303\244'.decode()).encode()
b'a\xcc\x88'

这些格式的全名是规范化形式D(规范化分解)和规范化形式C(规范化分解,然后是规范化合成),它们在UAX#15中定义.

在不区分大小写的文件系统上可能会发生类似的事情 - 尝试在Windows或Mac上检查Linux内核树!-与您可能希望找到既包含一些回购的例外Makefilemakefile,但没有人在他们的脑子会检查在名为两个文件a\314\210\303\244,至少不是故意的.

核心问题是操作系统使相同的文件以不同的名称出现,因此git会根据所查找的内容看到不同的内容,如果它正在查找的内容不是操作系统提供的默认名称.

以下是这条道路今天的表现,从新鲜开始:

$ git init 
Initialized empty Git repository
$ git config --get core.precomposeUnicode
true  # this is the default in git 1.8.5 and higher
$ touch Prodsättning 
$ env -u LANG /bin/ls -b
Prodsa\314\210ttning
$ git status -s 
?? "Prods\303\244ttning"

通过ls在C语言环境中使用,我可以看到文件名中的字节,其中包含分解的值.但是git将角色组合成一个代码点,因此不同平台上的用户不会产生不同的结果.引入预组合unicode的补丁详细解释了各种git命令会发生什么.

如果提交中的两个文件具有相同的名称,直到Unicode规范化(或大小写折叠),那么当git检出文件时它们将显示为"战斗":

$ git clone https://gist.github.com/jleedev/228395a4378a75f9e630b989c346f153 
$ git reset --hard && git status -s 
HEAD is now at fe1abe4 
 M "Prods\303\244ttning"
$ git reset --hard && git status -s 
HEAD is now at fe1abe4 
 M "Prodsa\314\210ttning"

因此,如果您只想删除该文件,可以按照自己的意愿继续操作.如果您想要可靠地操作这些文件,请查看将core.precomposeUnicode选项设置为false,以便git将精确存储您告诉它的文件名字节,但这可能比它的价值更麻烦.我可能会建议创建一个将所有文件名转换为NFC的提交,以便git不会认为文件丢失.

在Git和Mac OS X上的Umlaut问题上,这个问题有一些较旧的答案,但其中许多都早于git规范化Unicode的能力,而设置core.quotepath=false只会在这种情况下引起混淆.

推荐阅读
我我檬檬我我186
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有