文件名中的变音符号导致 subversion 和 git (MacOS) 之间存在差异

2024-03-03

我的文件名带有变音符号(即 Exposé.pdf)。

$ svn stat
!    Exposé.pdf
?    Exposé.pdf

我正在使用 subversion 和 git(不是 git-svn)。 我正在从 subversion 迁移到 git,并希望能够共存一段时间。 所以我在多个设备上有大型存储库。当我使用 git 克隆存储库并将现有的 subversion .svn 文件夹添加到存储库时,我得到了 subversion 差异(!项目丢失,?项目不在 vcs 下),但文件名似乎完全相同,但在他们不是! 我已经尝试过(参见https://www.git-tower.com/help/mac/faq-and-tips/faq/unicode-filenames https://www.git-tower.com/help/mac/faq-and-tips/faq/unicode-filenames)

git config --global core.precomposeunicode true 

但这没有任何区别。有什么线索吗?


“多个设备”可能是问题所在。确切的修复或解决方法可能是什么尚不清楚。请参阅下面的技术细节。

In general, you should not set core.precomposeunicode yourself, in the same way that you should not set core.ignorecase yourself.1 These settings—along with core.symlnks—are something that Git sets by itself to record how your computer behaves, at the time you run git init or git clone.2 If you have set this with --global, I would recommend that you remove the setting from your personal Git configuration:

git config --global --unset core.precomposeunicode

全局取消设置的原因是设置一个值--global disables新存储库中的自动感应功能。

启用自动检测后,您始终可以将现有存储库克隆到新副本。新克隆将具有适合当前本地条件的正确(本地)设置。这个新的克隆不应该通过任何方式从一台机器传输到另一台机器,除了git clone.


1These can be spelled with any random capitalization you like. The Git documentation does so using camelCase https://en.wikipedia.org/wiki/Camel_case, calling them core.precomposeUnicode and core.ignoreCase. You can set them for specific testing purposes or for weird edge cases where you want to deal with a repository that was built in some sort of undesirable way. But this amounts to lying to Git, so be careful with it! Do it locally (not globally) while experimenting.

2There's another special case here. The OSes that have these ... "features" of doing harm to your file names, in the name of shielding you from ugly reality, often actually do this on a per-file-system basis. The case folding feature of MacOS, for instance, is changeable at the time you build a disk image. Symlink support on Windows depends on the version of Windows and several additional items. So it's possible to pick up a Git repository intact, move it to a different file system, and then need to change the settings. This is one reason it's often wiser to git clone from one file system to another, rather than using tar or rar or zip or even cp -r to move a Git repository: the clone will set the settings correctly, while the non-clone copy operation won't.


文件名是字节字符串,除非它们不是

The fundamental problem here is that Git wants to believe that file names are nothing but byte strings with two or three constraints,3 established by Linux, and no other constraints established by any other OS. These byte strings generally should be, but are not required to be, valid UTF-8 sequences as well. Ideally, the OS will let Git use these byte-strings as-is, unmolested.

在 Windows 和 MacOS 上,这种理想很快就会变成现实。最明显、最直接的问题是,在 Linux 上,您可以创建一个名为README然后创建第二个,不同的文件名为readme,并且两个文件将共存。在 Windows 和 MacOS 上,当您创建这些文件中的任何一个时,您将无法再创建second文件:任何这样做的尝试都只是重复使用第一个文件。

换句话说,Linux 区分大小写的文件名,而 Windows 和 MacOS 则不区分大小写。这意味着 Linux 用户可以自由创建README.txt and readme.txt文件并放置both到单个存储库中。克隆此存储库的 Windows 或 MacOS 用户无法同时使用这两个文件。

尽管如此,Windows 或 MacOS 上的 Git 用户can处理这些文件。这样做只是痛苦的。我在回答中展示了一种方法即使在 git commit -am b/c origin 具有文件名大写的文件之后,“更改也未暂存提交” https://stackoverflow.com/q/54490905/1256452。同样的方法也适用于此,但疼痛程度相同。

同样的规则也适用于某些 Unicode 文件名。特别是,Unicode 有多种方式来拼写一些重音字符,例如 á、ü 等。例如,如果我们有一个名为schön(漂亮),我们可以使用字母序列来拼写它:

s c h umlaut-o n

(每个都是一个单一的 Unicode代码点),或者我们可以使用以下方式拼写它:

s c h o combining-umlaut n

这些都是不同的字节码序列因此至少根据 Git 应该是不同的文件,尽管两者都会display正如名字schön在你的屏幕上。

macOS 说这两个名称将显示相同,因此我不会允许其中之一。如果您向操作系统提供“错误”的拼写,它要么会纠正它,要么干脆拒绝它。请注意,这与折叠情况有些不同:MacOS 将允许您创建either readme or README,但不能两者兼而有之。它将只允许一种形式schön.

因为 Git 从index,不是来自文件系统,而索引是一个普通的数据文件,你can将所需的拼写或两者都放入索引中。这意味着您可以将其中一个或两个放入新的提交中。任何现有提交均具有现有拼写且无法更改。

加载现有提交(通过git checkout) 将提交的拼写复制到索引中,并保持原样。这core.precomposeunicode设置告诉 Git 您的操作系统是否以及如何modifyGit 尝试复制文件时的文件名from索引to工作树。然后,如果合适的话,Git 可以尝试消除任何损坏。但并非所有情况都可以处理,特别是文件出现在提交中的情况both拼写,很像 README 与自述文件中的大小写折叠。

(另请参阅 Git 对 MacOS precompose-unicode 的内部自测试,位于t/t3910-mac-os-precompose.sh https://github.com/git/git/blob/master/t/t3910-mac-os-precompose.sh.)


3The constraints are:

  • 没有字符串以斜杠开头或结尾(后者可以通过 Git 不会存储目录的事实来简单处理,而前者则只需不使用前导斜杠(如果有的话);
  • 没有字符串有两个连续的斜杠;和
  • 没有字符串具有嵌入的 NUL 字节(此规则来自 Git 编写的 C 语言,并且is这些操作系统都支持,所以这并不是真正的问题)。

斜杠规则是因为 Linux 将斜杠视为目录/子目录或目录/文件名分隔符。当然,MacOS 的做法完全相同,而 Windows 的大多数界面都支持这一点,尽管内部使用了反斜杠。所以这三个系统都对斜线限制感到满意。然而,一些 Windows 文件系统也在内部使用 UTF-16-LE,这在所谓的代理转义周围创建了一个额外的雷区。我不知道Windows如何处理这些。理想情况下,雷区不会从内部接口泄漏到外部接口,但话又说回来,理想情况下,Windows 将使用正斜杠和 UTF-8。 :-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

文件名中的变音符号导致 subversion 和 git (MacOS) 之间存在差异 的相关文章

  • svn:使用vim合并冲突

    我正在尝试看看如何使 svn 中的合并变得容易 This page http svnbook red bean com en 1 7 svn advanced externaldifftools html提到可以使用外部工具进行合并 vim
  • 由于合并而不允许 git revert 但未给出 -m 选项

    我正在尝试使用 revert 命令恢复到 git 中的某个 哈希 号 我正在使用以下命令 git revert c14609d74eec3ccebafc73fa875ec58445471765 但是 我得到以下返回 错误 提交 c14609
  • 使用 Git 的 Spring Cloud 配置服务器 - 无法克隆或签出存储库连接超时

    我正在使用 GIT 在 Spring Cloud Config Server 上进行 POC Spring Boot 1 5 3 RELEASE 爪哇1 8 弹簧工具套件https github com kishornpatil https
  • 如何预览 Git 中的隐藏内容?

    我想检查一个存储 并找出如果我将其应用于当前状态的工作树 它会发生什么变化 我知道我可以对存储进行 git diff 但这向我展示了工作树和存储之间的所有差异 而我只是想知道存储应用将改变什么 git stash show将向您显示最近存储
  • 在两个单独的分支或存储库中管理项目后端和前端?

    我启动了一个移动应用程序项目 该项目将具有服务器端和应用程序本身 所以 在master分支我创建了2个项目myapp server and myapp然后我创建了另外 2 个分支backend and frontend我只想将与它们相对应的
  • Git - 推送到远程存储库中的远程跟踪分支

    当简单地做git push到远程存储库 其master分支得到更新 对于非裸存储库来说 这是不希望出现的情况 最近的 Git 版本显示的警告消息清楚地表明了这一点 我希望能够推送到远程存储库 并拥有其之一远程追踪分支进行更新 稍后 当我登录
  • Git:如何使外部存储库和嵌入式存储库作为通用/独立存储库工作?

    我有一个大项目 比方说A repo 其中有一个子文件夹来自B repo 当我提交时 我会遇到如下警告A repo warning adding embedded git repository extractor annotator serv
  • 如何在 Mac OS X 10.8 上安装 hg Convert 所需的 python subversion 绑定?

    我正在寻找一种解决方案 最好是干净且简单的 以启用hg convert使用 SVN 存储库在 OS X 10 8 上工作 目前 如果您尝试转换 SVN 存储库 您将得到一个could not load Subversion python b
  • 交互式变基后,本地 Git 分支已偏离原始分支

    我有一个本地分行 CRM ayrshireminis 其中有一些我已推送到原点的提交 origin CRM ayrshireminis 这个分支是从创建的develop大约一周前的一个分支 其他合作者已经在该分支上完成了一周的工作 我想做的
  • 从本地缓存恢复SVN密码

    有没有办法从本地缓存恢复密码 密码必须存储在某处 因为我可以运行 svn co http my svn server foo 但我自己丢失了密码 我是否必须重置它 或者是否可以 以及如何 找到并解密密码 我主要在 Windows 上使用 C
  • vscode通过SSH连接gitlab的问题

    我在尝试通过 SSH 连接到 GitLab 远程存储库时遇到问题 这里是迄今为止完成的步骤 成功生成 SSH 密钥 管理人员将密钥添加到存储库中 因此当我访问 GitLab 网站时 我可以提交和发布分支 我无法从 VSCODE 发布分支并收
  • 颠覆和混合修订:破坏构建的秘诀?

    在使用 TFS 一段时间后 我刚刚回到 subversion 一般来说我已经很退出了 有一件事情我记得不一样 我不记得能够从过时的工作副本中提交 或者也许我的记忆力让我无法理解 过时 的定义 我认为 过时 意味着自从我上次更新工作副本以来
  • Jenkins git 插件 - 有时太慢

    以下内容摘自 Jenkins 日志 00 00 03 135 gt git fetch tags progress email protected cdn cgi l email protection some org some repo
  • SSH 到 Openshift 服务器失败

    我正在 openshift 服务器上使用 jboss catridge 我希望与其他人共享此实例并添加其他用户的公钥 id rsa pub 当其他人尝试访问该实例时 他会收到以下错误 我在他的实例中尝试了同样的方法 但看到了同样的错误 与
  • SVN 行结束样式

    当我尝试在 SVN 中提交文件时 它显示错误为 提交失败 详细信息如下 提交 svn 行结束样式不一致 检查目录 文件上的 svn 属性 如果您定义了 svn eol style 但您的文件包含不同的样式 Unix 与 DOS 则提交将失败
  • 推送时发生 Git 错误 - update_ref 失败

    当我尝试推送本地提交时遇到问题 这可能是在 Android Studio 崩溃时发生的 这是错误 update ref 引用 refs remotes origin master 失败 无法锁定 ref refs remotes origi
  • 代表 Git 存储库的数学结构是什么

    我正在学习 Git 如果我能描述一下代表 Git 存储库的数学结构 那就太好了 例如 它是一个有向无环图 它的节点代表提交 它的节点有代表分支等的标签 每个节点最多一个标签 没有标签使用两次 我知道这个描述不正确 我只是想解释我正在寻找的内
  • 远程测试时如何搭建git开发环境

    这似乎是一个愚蠢的问题 但我觉得我对 GIT 相当了解 但我似乎无法按照我的意愿设置我的开发环境 我要么错过了一些非常简单的东西 要么我做错了 我在我的服务器上初始化了一个裸 git 存储库 将其克隆到我的本地计算机 提交我的文件并推送到原
  • git push heroku master 权限被拒绝

    我正在关注 ruby railstutorial 我运行命令 git push heroku master 它吐出了这个错误 Permission denied publickey fatal Could not read from rem
  • 使用 VisualSVN Server 和 Cruisecontrol.net 检查内容集成中的修改失败

    我正在使用 CruiseControl net 进行持续集成 我使用 VisualSvn 服务器 使用 Windows 身份验证 为我的项目创建了一个存储库 两台服务器都托管在同一系统 Os Microsoft Windows Server

随机推荐