git.exe 拉取错误:无法生成 git:无效的参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48608113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
git.exe pull error: cannot spawn git: Invalid argument
提问by toouur
I have an error exactly as it's on the picture.
我有一个和图片上一样的错误。
Tried various settings, googled, reinstalled. Git pull doesn't work in TortoiseGit, I can commit and push, though.
尝试了各种设置,谷歌搜索,重新安装。Git pull 在 TortoiseGit 中不起作用,不过我可以提交和推送。
I have ssh client in network tab. What else can I try?
我在网络选项卡中有 ssh 客户端。我还能尝试什么?
采纳答案by MrTux
Update:
更新:
Git for Windows 2.16.1(4) is out and that should fix this issue: https://github.com/git-for-windows/git/releases
Git for Windows 2.16.1(4) 已经发布,应该可以解决这个问题:https: //github.com/git-for-windows/git/releases
Old answer:
旧答案:
This is a known issue in Git for Windows 2.16.1(2) and 2.16.1(3): https://github.com/git-for-windows/git/issues/1481
这是适用于 Windows 2.16.1(2) 和 2.16.1(3) 的 Git 中的一个已知问题:https: //github.com/git-for-windows/git/issues/1481
Only workaround is to use Git for Windows 2.16.1 (Download) (or older; 2.16.0 has other critical issues: TortoiseGit revert failed - unable to revert local changes).
唯一的解决方法是将 Git 用于 Windows 2.16.1(下载)(或更早版本;2.16.0 有其他严重问题:TortoiseGit 恢复失败 - 无法恢复本地更改)。
Just for the notes, bugreport in TortoiseGit: https://gitlab.com/tortoisegit/tortoisegit/issues/3156
只是为了笔记,TortoiseGit 中的错误报告:https: //gitlab.com/tortoisegit/tortoisegit/issues/3156
PS: For Git for Windows >= 2.16 you need at least TortoiseGit 2.5.7 (cf. https://stackoverflow.com/a/48457419/3906760).
PS:对于 Windows >= 2.16 的 Git,您至少需要 TortoiseGit 2.5.7(参见https://stackoverflow.com/a/48457419/3906760)。
回答by u8942599
I rolled back to the version 2.16.0, the problem has disappeared. Git for Windows 2.16.0(2)
我回滚到2.16.0版本,问题消失了。 Windows 版 Git 2.16.0(2)
回答by VonC
git-for-windows/git
issue 1481mentioned in 2018 for Git 2.16 is formally fixed with Git 2.25 (Q1 2020).
git-for-windows/git
2018 年针对 Git 2.16 提到的问题 1481已通过 Git 2.25(2020 年第一季度)正式修复。
A Work around has been introduced for an issue where a FD is left open when spawning a child process and is kept open in the child can interfere with the operation in the parent process on Windows.
已针对以下问题引入了变通办法:FD 在生成子进程时保持打开状态并在子进程中保持打开状态可能会干扰 Windows 上父进程中的操作。
See commit 3ba3720(02 Dec 2019), commit 4d0375c(30 Nov 2019), and commit ac33519, commit 9a780a3, commit c5a03b1, commit eea4a7f(22 Nov 2019) by Johannes Schindelin (dscho
).
(Merged by Junio C Hamano -- gitster
--in commit 55d607d, 10 Dec 2019)
见提交3ba3720(2019年12月2日),提交4d0375c(二○一九年十一月三十○日),以及提交ac33519,提交9a780a3,提交c5a03b1,提交eea4a7f(2019年11月22日)由约翰Schindelin( )dscho
。
(由Junio C gitster
Hamano合并-- --在commit 55d607d,2019 年 12 月 10 日)
mingw
: work around incorrect standard handlesSigned-off-by: Johannes Schindelin
For some reason, when being called via TortoiseGit the standard handles, or at least what is returned by
_get_osfhandle(
0) for standard input, can take on the value (HANDLE)-2 (which is not a legal value, according to the documentation).Even if this value is not documented anywhere,
CreateProcess()
seems to work fine without complaints ifhStdInput
set to this value.In contrast, the upcoming code to restrict which file handles get inherited by spawned processes would result in
ERROR_INVALID_PARAMETER
when including such handle values in the list.
mingw
:解决不正确的标准句柄签字人:约翰内斯·辛德林
出于某种原因,当通过 TortoiseGit 调用时,标准句柄,或者至少是
_get_osfhandle(
0返回的标准输入,可以采用值 (HANDLE)-2(根据文档,这不是合法值)。即使此值未在任何地方记录,
CreateProcess()
如果hStdInput
设置为此值,似乎也可以正常工作而不会抱怨。相比之下,即将发布的用于限制生成的进程继承哪些文件句柄的代码将导致在
ERROR_INVALID_PARAMETER
列表中包含此类句柄值时。
Note:
笔记:
mingw
: restrict file handle inheritance only on Windows 7 and laterSigned-off-by: Johannes Schindelin
Turns out that it don't work so well on Vista, see
git-for-windows/git
issue 1742 for details.According to Old New Thing, it shouldwork on Windows Vista and later.
But apparently there are issues on Windows Vista when pipes are involved. Given that Windows Vista is past its end of life (official support ended on April 11th, 2017), let's not spend toomuch time on this issue and just disable the file handle inheritance restriction on any Windows version earlier than Windows 7. To help this, special-case the value (HANDLE)-2 returned by
_get_osfhandle()
and replace it withINVALID_HANDLE_VALUE,
which will hopefully let the handle inheritance restriction work even when called from TortoiseGit.
mingw
: 仅在 Windows 7 及更高版本上限制文件句柄继承签字人:约翰内斯·辛德林
事实证明它在 Vista 上运行得不太好,有关详细信息,请参阅
git-for-windows/git
问题 1742。根据Old New Thing,它应该适用于 Windows Vista 及更高版本。
但是当涉及管道时,Windows Vista 上显然存在问题。鉴于 Windows Vista 已经过时(官方支持于 2017 年 4 月 11 日结束),让我们不要在这个问题上花太多时间,只需在 Windows 7 之前的任何 Windows 版本上禁用文件句柄继承限制即可。 , 特殊情况下返回的值 (HANDLE)-2
_get_osfhandle()
并将其替换为,INVALID_HANDLE_VALUE,
即使从 TortoiseGit 调用,也有望让句柄继承限制起作用。
That is why there is a new configuration setting:
这就是为什么有一个新的配置设置:
core.restrictinheritedhandles:
Windows-only: override whether spawned processes inherit only standard file handles (
stdin
,stdout
andstderr
) or all handles.
Can beauto
,true
orfalse
. Defaults toauto
, which meanstrue
on Windows 7 and later, andfalse
on older Windows versions.
core.restrictinheritedhandles:
仅限 Windows:覆盖生成的进程是仅继承标准文件句柄(
stdin
,stdout
和stderr
)还是所有句柄。
可以auto
,true
或false
。默认为auto
,这意味着true
在 Windows 7 及更高false
版本以及旧版 Windows 上。
mingw
: spawned processes need to inherit only standard handlesSigned-off-by: Johannes Schindelin
By default,
CreateProcess()
does not inherit any open file handles, unless thebInheritHandles
parameter is set toTRUE
. Which we do need to set because we need to pass in stdin/stdout/stderr to talk to the child processes.
Sadly, this means that all file handles (unless marked viaO_NOINHERIT
) are inherited.This lead to problems in VFS for Git(the Virtual File System for Git), where a long-running read-object hook is used to hydrate missing objects, and depending on the circumstances, might only be called afterGit opened a file handle.
Ideally, we would not open files without
O_NOINHERIT
unless reallynecessary (i.e. when we want to pass the opened file handle as standard handle into a child process), but apparently it is all-too-easy to introduce incorrectopen()
calls: this happened, and prevented updating a file after the read-object hook was started because the hook still held a handle on said file.Happily, there is a solution: as described in the "Old New Thing" there is a way, starting with Windows Vista, that lets us define precisely which handles should be inherited by the child process.
And since we bumped the minimum Windows version for use with Git for Windows to Vista with v2.10.1 (i.e. a longtime ago), we can use this method. So let's do exactly that.
We need to make sure that the list of handles to inherit does not contain duplicates; Otherwise
CreateProcessW()
would fail withERROR_INVALID_ARGUMENT
.While at it, stop setting
errno
toENOENT
unless it really is the correct value.Also, fall back to not limiting handle inheritance under certain error conditions (e.g. on Windows 7, which is a lot stricter in what handles you can specify to limit to).
mingw
: 产生的进程只需要继承标准句柄签字人:约翰内斯·辛德林
默认情况下,
CreateProcess()
不继承任何打开的文件句柄,除非bInheritHandles
参数设置为TRUE
。我们确实需要设置它,因为我们需要传入 stdin/stdout/stderr 来与子进程对话。
可悲的是,这意味着所有文件句柄(除非标记为 viaO_NOINHERIT
)都是继承的。这会导致VFS for Git(Git的虚拟文件系统)出现问题,其中使用长时间运行的读取对象挂钩来补充丢失的对象,并且根据情况,可能仅在Git 打开文件句柄后调用。
理想情况下,
O_NOINHERIT
除非真的有必要,否则我们不会打开文件(即,当我们想将打开的文件句柄作为标准句柄传递给子进程时),但显然引入不正确的open()
调用太容易了:这发生了,并且阻止了在读取对象钩子启动后更新文件,因为钩子仍然持有所述文件的句柄。令人高兴的是,有一个解决方案:如“旧的新事物”中所述,有一种方法可以从 Windows Vista 开始,让我们精确定义子进程应该继承哪些句柄。
并且由于我们将用于 Windows 的 Git 的最低 Windows 版本提升到带有 v2.10.1 的 Vista(即很久以前),我们可以使用这种方法。所以让我们这样做。
我们需要确保要继承的句柄列表不包含重复项;否则
CreateProcessW()
会失败ERROR_INVALID_ARGUMENT
。在此期间,停止设置
errno
为,ENOENT
除非它确实是正确的值。此外,在某些错误条件下(例如,在 Windows 7 上,您可以指定要限制的句柄要严格得多)回退到不限制句柄继承。
And:
和:
mingw
: do seterrno
correctly when trying to restrict handle inheritanceReported-by: Johannes Sixt
Signed-off-by: Johannes Schindelin
Acked-by: Johannes SixtIn 9a780a384de("
mingw
: spawned processes need to inherit only standard handles", 2019-11-22, Git v2.25.0 -- mergelisted in batch #5), we taught the Windows-specific part to restrict which file handles are passed on to the spawned processes.Since this logic seemed to be a bit fragile across Windows versions (we stillsupport Windows Vista in Git for Windows, for example), a fall-back was added to try spawning the process again, this time without restricting which file handles are to be inherited by the spawned process.
In the common case (i.e. when the process could not be spawned for reasons otherthan the file handle inheritance), the fall-back attempt would still fail, of course.
Crucially, one thing we missed in that code path was to set
errno
appropriately.Let's fix that by making sure that
errno
is set correctly. It even appears thaterrno
was set in the wrongcase previously:CreateProcessW()
returns non-zero upon success, buterrno
was set only in the non-zero case.However, when
mingw_spawnvpe()
wants to see whether the file in question is a script, it callsparse_interpreter()
, which in turn tries toopen()
the file. Obviously, this call fails, and setserrno
toENOENT
, deep inside the call chain started from that test helper.Instead, we force re-set
errno
at the beginning of the functionmingw_spawnve_fd()
, which shouldbe safe given that callers of that function will want to look aterrno
if -1 was returned. And if thaterrno
is 0 ("No error"), regression tests like t0061.2 will kick in.
mingw
:errno
尝试限制句柄继承时正确设置报告人:Johannes Sixt
签字人:Johannes Schindelin
认可:Johannes Sixt在9a780a384de(“
mingw
:生成的进程只需要继承标准句柄”,2019 年 11 月 22 日,Git v2.25.0 --合并在第 5 批中列出)中,我们教了 Windows 特定的部分来限制传递哪些文件句柄到生成的进程。由于此逻辑在 Windows 版本中似乎有点脆弱(例如,我们仍然支持 Windows Vista 中的 Git for Windows),因此添加了一个后备以尝试再次生成该进程,这次不限制要使用哪些文件句柄由衍生进程继承。
在通常情况下(即当进程无法催生的原因其他不是文件句柄继承),掉回的尝试仍然失败,当然。
至关重要的是,我们在该代码路径中遗漏的一件事是
errno
适当设置。让我们通过确保
errno
正确设置来解决这个问题。甚至似乎之前errno
在错误的情况下设置了:CreateProcessW()
成功时返回非零,但errno
仅在非零情况下设置。但是,当
mingw_spawnvpe()
想要查看有问题的文件是否是脚本时,它会调用parse_interpreter()
,而后者又会尝试访问open()
该文件。显然,此调用失败,并设置errno
为ENOENT
,在从该测试助手开始的调用链深处。相反,我们
errno
在函数的开头强制重新设置,考虑到该函数的调用者想要查看是否返回 -1mingw_spawnve_fd()
,这应该是安全的errno
。如果它errno
是 0(“没有错误”),像 t0061.2 这样的回归测试就会开始。