原始解决方案参看:https://stackoverflow.com/questions/26097568/git-pull-error-unable-to-create-file-invalid-argument
本问题解决于 2024-02-18,使用 git 版本 2.28.0.windows.1
解决方案
看 Git 抛出的出错的具体信息,比如如下都来自同一个文件夹的情况:
git clone -v "https://github.com/somebody/some-repo.git" "X:\Project\GitHub\somebody\some-repo"
Cloning into 'X:\Projects\GitHub\somebody\some-repo'...
POST git-upload-pack (200 bytes)
remote: Counting objects: 1234, done.
remote: Compressing objects: 100% (456/456), done.
Receiving objects: 100% (1234/1234), 2.70 MiB | 567.00 KiB/s, done.
Resolving deltas: 100% (234/234), done.
remote: Total 1234 (delta 234), reused 0 (delta 0)
Checking connectivity... error: unable to create file repo-root/some-folder/_wrong_filename_1234?ref=users (Invalid argument)
error: unable to create file repo-root/some-folder/_wrong_filename_5678?ref=users (Invalid argument)
error: unable to create file repo-root/some-folder/_wrong_filename_1234?params=test (Invalid argument)
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status' and retry the checkout with 'git checkout -f HEAD'
git did not exit cleanly (exit code 128) (12345 ms @ 1970-01-23 12:34:56)
则在项目路径下,在 git-bash 或 cmd 命令行使用 git config core.sparsecheckout true
将稀疏检出模式开启;
- 若在 git-bash 下则继续输入如下命令,仅检出除指定目录下所有内容之外的内容:
echo * >> .git/info/sparse-checkout
echo !repo-root/some-folder/* >> .git/info/sparse-checkout
- 若在 cmd 下则输入:
(ECHO * && ECHO !repo-root/some-folder/*) >> .\.git\info\sparse-checkout
然后就可以重新 git pull
了,这次应该不会报错了。
但是那些文件却也确实不会拉取了,请在编译或执行操作前确认好丢失文件的必要性哦。
多个不同位置的文件
主要看 Checking connectivity... error: unable to create file
后面跟的内容,有一个就加一行到 .git/info/sparse-checkout
文件里,然后重新拉取就好了。
原因
基本上就是 Windows 下 pull 到了别的操作系统(文件系统)下允许但 NTFS 不允许的文件命名格式,如文件名中带有英文 ? 等,此时 pull 或 merge 操作会被中断 Aborting。
那么解决思路是利用 Git 的稀疏检出规则,强行绕过这些可能出错的文件(我不拉了,我摆烂了)。
等到那些系统上的提交者(或者你自己在自己的分支上)更新文件命名后再重新 clone 或者 pull(抑或者就此摆烂)。
验证
验证稀疏检出是否成功开启,可以在 git-bash 里打开项目文件夹,发现后面会变成形如:
User@MACHINE_NAME MINGW64 ~/my-project (master|SPARSE)
$
的样式,就算成功开启了;
而后你需要打开文件夹选项,选择显示隐藏的项目,或者直接在地址栏的最后追加上\.git\info
,检查一下info文件夹下是否有 sparse-checkout;
可以右键打开方式为记事本,检查内容是否是:
*
!repo-root/some-folder/*
第一行为通配符,表示任意文件;
第二行 ! 开头表示排除,* 表示通配符,即排除 repo-root/some-folder
路径下的所有文件。