gpt4 book ai didi

Git 与文件名中的 ä 混淆

转载 作者:太空狗 更新时间:2023-10-29 13:52:53 26 4
gpt4 key购买 nike

由于文件名带有 ä,我的 git 情况很糟糕。这是一个可能存在多年的旧文件:

所以它用\303\244 标记为未跟踪,但如果我删除它,它反而标记为已删除,但用\314\210。非常混淆。我真的不关心文件,但想知道 future ......

~/d/p/uniply ❯❯❯ git status                                                                           master ◼
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add <file>..." 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 <file>..." to update what will be committed)
(use "git checkout -- <file>..." 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 <file>..." 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)

最佳答案

简短版本:您显然使用的是 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'

这些格式的全称是Normalization Form D(Canonical Decomposition)和Normalization Form C(Canonical Decomposition,followed by Canonical Composition),它们定义在UAX #15 .

在不区分大小写的文件系统上可能会发生类似的事情——尝试在 Windows 或 Mac 上检查 Linux 内核树! — 除了您可能希望找到一些同时包含 Makefilemakefile 的存储库之外,但是头脑正常的人不会 checkin 同时命名为 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"

通过在 C 语言环境中使用 ls,我可以看到文件名中的字节,其中包含分解值。但是 git 是将字符组合成一个单一的代码点,这样不同平台的用户就不会产生不同的结果。 patch that introduced precomposed unicode explains in detail各种 git 命令会发生什么。

如果提交中的两个文件在 Unicode 规范化(或大小写折叠)之前具有相同的名称,那么当 git checkout 文件时它们将出现“打架”:

$ 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 将准确存储您告诉它的文件名字节,但这可能比它的值(value)更麻烦。我可能建议创建一个将所有文件名转换为 NFC 的提交,这样 git 就不会认为文件丢失了。

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

关于Git 与文件名中的 ä 混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41765181/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com