Git - 重命名含有非法字符的文件

mar*_*zko 2 windows git escaping file-rename

我们的团队在存储库中工作,其中包括一个目录,其中包含带有管道字符“|”的文件。我是 Windows 上唯一的一个,所以管道字符对于文件名是非法的。

  1. 有没有办法将目录“extra”中的文件从 ex 重命名为“extra”?当我进行“git pull”时,“2021|08|05”到“2021\08\05”?
  2. 有没有办法将目录“extra”中的文件从 ex 重命名为“extra”?当我进行“git Push”时,“2021 \ 08 \ 05”到“2021 | 08 | 05”?

tor*_*rek 5

    \n
  1. 不。
  2. \n
  3. 不。
  4. \n
\n

这些是您所问问题的正确答案,但问题是您问了错误的问题唉,正确问题的答案是:“是的,但这是一个可怕的解决方案”。问题是:是否有解决方案来解决 Git 提交中存储的文件名中存在错误/无效字符的问题?

\n

在 Git 的早期,当它是只有少数人能够成功使用的 shell 脚本的集合时,\xc2\xa0 可以从其他地方用 获取新的提交git fetch,然后用 读取这些提交到 Git 的索引git read-tree

\n

Git 的索引(Git 也称为暂存区,有时也称为缓存可以保存这些文件名。事实上,即使在 Windows 上,Git 的索引也可以保存名为 的文件aux.h,而 Windows 不允许您创建这些文件。索引也没有文件夹:它只有名称带有嵌入(正)斜杠的文件,例如path/to/file. Git 的索引中可以保存两个不同的文件,一个是named ,README一个是named 。readmeWIndows 不能有两个不同的文件,其名称仅大小写不同。

\n

因此,Git 的索引/暂存区可以很好地保存这些文件。当你处理这些文件时,问题就出现了。Git 索引中的文件以特殊的 Git 专用格式存储,Git 称之为blob 对象。您无法直接读取或写入 blob 对象。您必须使用更多 Git 命令才能完成此操作。实在是太不方便了。

\n

为了方便地使用 Git ,我们通常不会使用所有单独的一次一步的内部 Git 操作:我们使用某种更高级别的、面向用户的命令,例如git checkout. 我们检查整个提交: Git 将找到该提交中存储的所有文件,将它们读入 Git 的索引,然后将所有内部仅包含 Git 的 blob 对象复制并展开为具有普通文件名的普通文件。

\n

这一步\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

\n

此时,您可以做的是下拉到那些较低级别的命令。你可以运行:

\n
git rev-parse :path/to/2021|08|05\n
Run Code Online (Sandbox Code Playgroud)\n

如果需要,也许可以加上引号,具体取决于您的 shell:

\n
git rev-parse ":path/to/2021|08|05"\n
Run Code Online (Sandbox Code Playgroud)\n

git rev-parse命令将显示文件的blob 哈希 ID 。然后您可以通过以下方式访问文件的内容

\n
git cat-file -p <hash>\n
Run Code Online (Sandbox Code Playgroud)\n

它将这些内容打印到标准输出。如果您的 shell 支持重定向,则可以将输出重定向到您选择名称的文件。这使您可以查看并使用文件的内容。

\n

git cat-file -p命令可以直接获取索引路径名,因此:

\n
git cat-file -p ":path/to/2021|08|05" > path/to/2021-08-05\n
Run Code Online (Sandbox Code Playgroud)\n

是将文件提取为可用名称的一种方法。

\n

不幸的是,git add\xe2\x80\x94(通常是更新文件的方式)\xe2\x80\x94 将坚持使用您在文件系统中为文件指定的名称。再次,您必须依靠内部 Git管道命令来解决此问题。例如,如果您需要更新该特定文件,您将:

\n
    \n
  1. 运行git hash-object -w -t blob path/to/2021-08-05将更新后的文件数据转换为内部 Git 对象;
  2. \n
  3. 使用参数运行git update-index以使 Git 更新条目以path/to/2021|08|05使用步骤 1 中获得的哈希 ID。
  4. \n
\n

完成所有这些后,您可以返回正常的 Git 命令,因为git commit从 Git 的索引/暂存区域中的内容进行新的提交。

\n

这里的(相当大的)缺点是你不能使用很多正常的日常 Git 命令:

\n
    \n
  1. git pull通常是不行的,因为它运行git rebasegit merge,两者都需要使用您的工作树(操作系统级文件)。首先运行git fetch,然后根据需要进行尽可能多的手动工作。
  2. \n
  3. git checkout将会失败:你可以使用它,但是你必须手动对 Git 索引中的每个错误文件名执行一些操作。
  4. \n
  5. git diff将显示差异,包括删除名称错误的文件,并将git status调整名称的文件显示为未跟踪的文件(因为它们)。
  6. \n
  7. git add您也不能对这些文件进行任何更改;使用git hash-object -wandgit update-index代替。
  8. \n
  9. git rebasegit merge变得困难。您可能可以按照步骤 2 和 4 处理它们,但这充其量只是痛苦的。
  10. \n
\n