mar*_*zko 2 windows git escaping file-rename
我们的团队在存储库中工作,其中包括一个目录,其中包含带有管道字符“|”的文件。我是 Windows 上唯一的一个,所以管道字符对于文件名是非法的。
这些是您所问问题的正确答案,但问题是您问了错误的问题。唉,正确问题的答案是:“是的,但这是一个可怕的解决方案”。问题是:是否有解决方案来解决 Git 提交中存储的文件名中存在错误/无效字符的问题?
\n在 Git 的早期,当它是只有少数人能够成功使用的 shell 脚本的集合时,\xc2\xa0 可以从其他地方用 获取新的提交git fetch,然后用 读取这些提交到 Git 的索引中git read-tree。
Git 的索引(Git 也称为暂存区,有时也称为缓存)可以保存这些文件名。事实上,即使在 Windows 上,Git 的索引也可以保存名为 的文件aux.h,而 Windows 不允许您创建这些文件。索引也没有文件夹:它只有名称带有嵌入(正)斜杠的文件,例如path/to/file. Git 的索引中可以保存两个不同的文件,一个是named ,README一个是named 。readmeWIndows 不能有两个不同的文件,其名称仅大小写不同。
因此,Git 的索引/暂存区可以很好地保存这些文件。当你处理这些文件时,问题就出现了。Git 索引中的文件以特殊的 Git 专用格式存储,Git 称之为blob 对象。您无法直接读取或写入 blob 对象。您必须使用更多 Git 命令才能完成此操作。实在是太不方便了。
\n为了方便地使用 Git ,我们通常不会使用所有单独的一次一步的内部 Git 操作:我们使用某种更高级别的、面向用户的命令,例如git checkout. 我们检查整个提交: Git 将找到该提交中存储的所有文件,将它们读入 Git 的索引,然后将所有内部仅包含 Git 的 blob 对象复制并展开为具有普通文件名的普通文件。
这一步\xe2\x80\x94从 Git 索引中复制文件,使它们可用\xe2\x80\x94是 Windows 上出现问题的地方。例如,Git 索引中的文件名是path/to/2021|08|05. Git 认识到在 Windows 上path/to/必须将、和分成两个文件夹,以便 Git 可以在第二个文件夹中创建一个文件。 不幸的是,Git 无法重新映射该部分。 这部分将保留下来,正如您所看到的,Git无法创建具有该名称的文件:操作系统只是说“不”。path\\path\\to\\2021|08|05 2021|08|05
此时,您可以做的是下拉到那些较低级别的命令。你可以运行:
\ngit rev-parse :path/to/2021|08|05\nRun Code Online (Sandbox Code Playgroud)\n如果需要,也许可以加上引号,具体取决于您的 shell:
\ngit rev-parse ":path/to/2021|08|05"\nRun Code Online (Sandbox Code Playgroud)\n此git rev-parse命令将显示文件的blob 哈希 ID 。然后您可以通过以下方式访问文件的内容:
git cat-file -p <hash>\nRun Code Online (Sandbox Code Playgroud)\n它将这些内容打印到标准输出。如果您的 shell 支持重定向,则可以将输出重定向到您选择名称的文件。这使您可以查看并使用文件的内容。
\n该git cat-file -p命令可以直接获取索引路径名,因此:
git cat-file -p ":path/to/2021|08|05" > path/to/2021-08-05\nRun Code Online (Sandbox Code Playgroud)\n是将文件提取为可用名称的一种方法。
\n不幸的是,git add\xe2\x80\x94(通常是更新文件的方式)\xe2\x80\x94 将坚持使用您在文件系统中为文件指定的名称。再次,您必须依靠内部 Git管道命令来解决此问题。例如,如果您需要更新该特定文件,您将:
git hash-object -w -t blob path/to/2021-08-05将更新后的文件数据转换为内部 Git 对象;git update-index以使 Git 更新条目以path/to/2021|08|05使用步骤 1 中获得的哈希 ID。完成所有这些后,您可以返回正常的 Git 命令,因为git commit从 Git 的索引/暂存区域中的内容进行新的提交。
这里的(相当大的)缺点是你不能使用很多正常的日常 Git 命令:
\ngit pull通常是不行的,因为它运行git rebase或git merge,两者都需要使用您的工作树(操作系统级文件)。首先运行git fetch,然后根据需要进行尽可能多的手动工作。git checkout将会失败:你可以使用它,但是你必须手动对 Git 索引中的每个错误文件名执行一些操作。git diff将显示差异,包括删除名称错误的文件,并将git status调整名称的文件显示为未跟踪的文件(因为它们是)。git add您也不能对这些文件进行任何更改;使用git hash-object -wandgit update-index代替。git rebase并git merge变得困难。您可能可以按照步骤 2 和 4 处理它们,但这充其量只是痛苦的。