【问题标题】:github/git Checkout Returns 'error: invalid path' on Windowsgithub/git Checkout 在 Windows 上返回“错误:无效路径”
【发布时间】:2020-12-22 22:12:17
【问题描述】:

当我尝试从 github 签出存储库时,我收到错误:

error: invalid path 'configs/perl-modules/DIST.64/perl-HTML-Tree-1:5.03-1.el6.noarch.rpm'

我怀疑问题在于路径包含一个 :,这在 Windows 上是非法的。

研究错误后,我找到了 2 个可能的答案:
1) 更改存储库文件的路径。 不幸的是,这是一个团队资源,无法在可预见的未来。
2) 使用 sparse-checkout。 我已经尝试过,但没有效果,如下所示:

$ git clone -n​​ git@github.com:XXXXXX/deploy.git
克隆到“部署”...
远程:枚举对象:57,完成。
远程:计数对象:100% (57/57),完成。
远程:压缩对象:100% (49/49),完成。
远程:总计 86457(增量 10),重用 22(增量 8),打包重用 86400
接收对象:100% (86457/86457),1.50 GiB | 4.73 MiB/s,完成。
解决增量:100% (59779/59779),完成。
$ cd 部署/
$ git config core.sparsecheckout true
$ echo www >> .git/info/sparse-checkout
$ git checkout centos6
错误:无效路径 'configs/perl-modules/DIST.64/perl-HTML-Tree-1:5.03-1.el6.noarch.rpm'
错误:路径无效 'configs/perlbrew/perls/perl-5.24.1/man/man3/App::Cpan.3'
.
. (对许多文件重复)
.

这是使用 Git for Windows “git version 2.28.0.windows.1”完成的。我还尝试了两种类型的行尾,并使用了各种版本的 .git/info/sparse-checkout,例如:

/*
!/configs/perl-modules
!/configs/perlbrew/perls/perl-5.24.1/man/man3

Checkout 在 Linux、MacOS 和 WSL 上运行良好,唯一的问题是我的 IDE 不能在那里工作。为什么 sparse-checkout 不能在 Windows 上运行。还有其他可能吗?

【问题讨论】:

  • 我尝试过的其他事情是更改行尾,前导 /,\ 而不是 /(毕竟,这是 Windows),并在末尾添加 *。我还尝试了新的 svn sparse-checkout init 和 svn sparse-checkout add & set 命令。仍然没有快乐。
  • 创建一个fork,在真机上克隆,重命名有问题的文件,提交,推送?然后,您应该能够在倒霉的 Windows 系统上进行浅层结帐。
  • 文件夹名称的末尾也可能有空格。发生在我身上......而且很难被发现!

标签: git github sparse-checkout


【解决方案1】:

在我在 git-for-windows 错误跟踪器 (https://github.com/git-for-windows/git/issues/2803) 上打开一个问题后,我发现我的问题已被归档为https://github.com/git-for-windows/git/issues/2777。该问题表明我需要设置另一个 git 标志:

git config core.protectNTFS false

这 (#2777) 确实包含绕过我的问题。我希望 git 或 git-for-windows(响应速度非常快)能提供更好的警告消息,甚至是像文件路径映射方案这样的真正修复。

请注意,这只是在 Windows 中使用稀疏结帐时才会出现的问题。

【讨论】:

  • 有趣。我没有听说过 core.protectNTFS 这样做,但是通过 Git 源代码搜索,它就在那里。它周围的评论说它正在寻找双冒号,但它甚至拒绝一个冒号,所有这些拒绝都发生在任何稀疏结帐步骤之前。
  • 问题 2803 刚刚更新:github.com/git-for-windows/git/issues/…
  • @wdtj 你能得到这个工作吗?我有同样的问题,几天前打开了这个stackoverflow.com/questions/67926498/…。今天看到你的帖子,试过core.protectNTFS,但没有运气
  • 没有。最后制作了一个 Linux VM 来进行我的开发。
  • 是的,当我在克隆 repo 时遇到同样的错误,在执行命令“git config core.protectNTFS false”执行“git reset”和“git checkout *”之后,它也能解决同样的错误
【解决方案2】:

在我们的例子中,有一个文件名 aux.go,而 windows 不允许创建包含单词 aux 的文件

阅读有关此问题的更多信息here

【讨论】:

    【解决方案3】:

    对于那些只想通过命令解决问题的人:

    git clone --sparse -c core.protectNTFS=false -n <repo-URL>
    git sparse-checkout add "\!<pattern1>" "\!<pattern2>"
    git checkout <branch>
    

    模式与 repo root 相关,可以使用*

    【讨论】:

      【解决方案4】:

      我遇到了类似的问题,试图在 Windows 上从 GitHub 签出包含名称中带有“:”的文件的存储库。 (导致问题的示例文件名:“test-img.jpg:Zone.Identifier”)。已下载 repo,但文件未显示在文件夹中。

      我发现运行git config core.protectNTFS false 解决了我的问题,但前提是我在运行它之前和之后采取了一些步骤。整个过程是这样的:

      1. 在本地克隆 Git 存储库;
      2. 'cd'进入刚刚克隆的本地Git仓库文件夹;
      3. 运行git reset
      4. 运行git config core.protectNTFS false
      5. 运行git checkout(只需 git checkout,命令末尾没有 *)。

      之后,我可以看到文件。当然,从 Git 下载的一些额外内容通常会被忽略,但对我来说这没什么大不了的。

      【讨论】:

      • 非常感谢您的解决方案,这几乎让我成功了。我想添加“在那之后,我可以看到文件”:在我的例子中,我有一个名为“foo:bar.txt”的文件,在你的步骤之后,它变成了“foo”。但是,我注意到“foo”文件是空的(0 字节)。因此,另外,我 (1) 将我的原始 repo 下载为 zip 文件,(2) 将 zip 文件中的“foo:bar.txt”重命名为“foo_bar.txt”,(3) 将“foo”替换为(4) 提交。
      【解决方案5】:

      我怀疑问题在于路径包含 [冒号] :,这在 Windows 上是非法的。

      这实际上是问题所在。

      [稀疏结帐]!configs/perlbrew/perls/perl-5.24.1/man/man3

      这里被投诉的路径名是:

      configs/perl-modules/DIST.64/perl-HTML-Tree-1:5.03-1.el6.noarch.rpm
      

      它不以configs/perlbrew/ 开头,更不用说完整的要跳过的路径。

      您可以通过(痛苦地)枚举所有无效文件名来解决此问题。不过,Git 需要一个更好的通用机制。

      【讨论】:

      • 虽然您认为路径不匹配是正确的,但路径 /configs/per-modules/ 和 /configs/perlbrew/ 都发生错误(为简洁起见,我将其截断)。我用两个路径更新了稀疏检出文件,但仍然出现错误。很好的尝试。我会再更新一下描述。
      • 可能是错字,但您在上面的评论和编辑中都有per-modules,您的意思是perl-modules吗?
      • 你的权利,但这只会影响许多文件错误之一。谢谢。
      【解决方案6】:

      如果其他解决方案都不起作用,问题可能是 git 的版本。 我使用版本2.31.1 并显示错误,但后来我尝试使用2.15 并且它工作正常。 但对我来说,错误在于git clone 命令。

      【讨论】:

      • 谢谢!!!将版本从 2.3.2 更改为 2.2.8 后,它对我有用
      【解决方案7】:

      如果使用不同的操作系统,例如 linux 与 windows 或 Mac Os 与 Windows。检查文件路径中的字符。在我的情况下,我将项目保存在我的 Mac 上并提交,当拉动我的 Windows 机器时,文件路径错误发生。

      Windows 声明

      文件名不能包含以下任何字符:\ / : * ? " |

      但我保存的图像名称中包含“*”。因此,只需提交对您的团队使用的不同操作系统有效的新名称。或者通过寻找解决方法让自己更加沮丧

      简单对。

      【讨论】:

        【解决方案8】:

        附录 - git 版本 2.34.1.windows.1 & others(?)

        很遗憾,git config core.protectNTFS false 还不够; 带有冒号的文件名的内容丢失(文件大小 = 0)

        解决方案

        TL;DR

        git diff ec28c8ddd5f8c83d11604bcae69afb46d79b1029 > p.patch
        patch -R -f -i p.patch
        git add *
        git commit 
        

        细化

        事实证明git config core.protectNTFS false 确实有效,只要不再在git checkout 上产生致命错误

        然而,git 现在将生成文件名剪辑到冒号并且具有零内容

        例如Writing-Bops:-The-Bebop-Schema-Language.md (~9KB) --> Writing-Bops (0 KB)

        要解决此问题,我们需要以另一种方式获取原始违规文件内容的副本,以便恢复它。

        条件/假设

        • 这假设您出于某种原因不能不会使用稀疏克隆。
        • 同上git apply-filter 和其他“永久重写”git 历史的技术,例如当您跟踪第三方 git 存储库时。
        • 您正在运行 Windows,使用 NTFS 存储,git-for-windows 以 bash 作为您的 shell,并且有一个可用的 patch.exepatch --version 应该报告类似“GNU 补丁 2.7.6”的内容)李>

        (在我们的例子中,我们正在搞乱 github wiki 克隆并遇到了包含冒号的文件名的问题。当然,我们想解决这个问题,而不需要额外的“稀疏克隆”或WSL 英里。)

        事实证明,我们可以在完成之后得到缺失的内容

        git config core.protectNTFS false
        git checkout <hash>
        

        通过运行patch。 (顺便说一句:如果您尝试比较/比较这些提交,TortoiseGit 会永远挂起!)

        使用下一个命令获取包含所有缺失更改的补丁文件。如果您有多个带有冒号或其他问题的文件,所有补丁文件中将列出缺少的内容:一个补丁文件可以全部捕获!

        git diff ec28c8ddd5f8c83d11604bcae69afb46d79b1029 > p.patch
        # ^^^^ reference the git hash with the offending original file(s)
        

        现在你有了一个补丁文件,你可以将它应用到当前工作目录:它必须反向应用-R):

        patch -R -f -i p.patch
        

        如果你忘记了-R,补丁会询问(回答[y]es);如果你指定-R patch 会更厉害,所以-f (force) 是为了让 patch 闭嘴并完成工作。

        这应该列出一个或多个被修补的文件,例如

        $ patch -R -f -i p.patch
        patching file Writing-Bops:-The-Bebop-Schema-Language.md
        

        注意该文件名中的冒号:原来 Windows 上的 GNU 补丁(至少 v2.7.6)使用Unicode homoglyph模拟文件名中的冒号。另请参阅下文。

        您现在在工作目录中拥有了冒号文件的原始内容,您现在可以将这些文件添加到 git 索引并像往常一样提交它们:

        警告:在继续之前,您可能需要清理(删除)您之前的 git checkout 生成的空剪辑文件名!

        注意:如果您不喜欢分配给丢失内容的同形文件名patch -i,您可以在提交结果之前将其更改为您喜欢的任何内容。

        git add *
        git commit 
        

        验证结果

        当你做的一切正确时,最后一次提交应该将冒号文件列为 renamed 因为你没有更改内容,git commit 因此应该检测到“文件重命名操作”为-是。

        额外:用同形文字替换冒号

        found several Unicode homoglyphs 看起来或多或少像一个冒号,但在 NTFS 文件名中被视为合法

        经过一些实验,我决定使用,因为我想尽可能保持the github wiki page I was fiddling with 的完整性。

        一般来说,我会完全放弃冒号,或者用一个或多个连字符替换它,但在 wiki MarkDown 页面的情况下,这个决定可以采用另一种方式。

        【讨论】:

          【解决方案9】:

          我和你一样,你的文件名不正确或者没有保留,重命名你的文件就行了

          【讨论】:

          • 那将是一个最合理的解决方案,但请仔细阅读问题:“不幸的是,这是团队资源,在可预见的将来无法修复”。他们不愿意在短期内更改文件名。
          【解决方案10】:

          对于那些有类似错误的人:
          就个人而言,问题在于在 Linux 上的文件名中使用 ",而在 Windows 10 机器上尝试使用 pull

          【讨论】:

            【解决方案11】:

            在我的情况下,文件名末尾有一个额外的空格。在 Windows 上,这会导致问题。

            我能够通过删除这个空间来解决这个问题。由于我无法在 Windows 上克隆项目,因此直接在我们的存储库所在的位置(在我们的例子中是 GitHub)上完成了此更改。

            【讨论】:

              【解决方案12】:

              在使用git clone之前

              执行这个命令:

              git config --global core.protectNTFS false
              

              【讨论】:

              • 绝对不要这样做。这将不允许您编写带有: 等特殊字符的文件。这将只允许人们使用特定于 NTFS 的黑客来写入您的.git 目录。这使您容易受到攻击,但并不能解决问题。
              【解决方案13】:

              在我的例子中,repo 包含 Windows 中包含无效字符的文件,例如 []

              【讨论】:

                【解决方案14】:

                我发现了一个未被提及的选项。使用WSL 签出文件。

                我在 WSL/Bash 而不是 PowerShell/CMD 中运行 git clone。 WSL 透明地处理修复文件名,即使它们仍然存储在 NTFS 上并且我使用 VS Code for Windows 打开它们。我能够在 Windows 中修改文件,甚至在 Windows 上推送我的更改。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2022-01-05
                  • 2016-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-05-17
                  • 1970-01-01
                  相关资源
                  最近更新 更多