GitPython
GitPython copied to clipboard
Failure to run as Windows Service ( [WinError 6] on subprocess.Popen )
While configuring a working application to be run via a Windows Service (Windows 7) ( via nssm ), the application was failing (only when ran as a Windows Service) with:
2018-02-07 14:05:51.560: File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\git\cmd.py", line 294, in refresh
2018-02-07 14:05:51.560: raise ImportError(err)
2018-02-07 14:05:51.560: ImportError: Bad git executable.
2018-02-07 14:05:51.560: The git executable must be specified in one of the following ways:
2018-02-07 14:05:51.560: - be included in your $PATH
2018-02-07 14:05:51.560: - be set via $GIT_PYTHON_GIT_EXECUTABLE
2018-02-07 14:05:51.560: - explicitly set via git.refresh()
After debugging the issue a bit, the problem was coming from the Popen call in Git.execute() - throwing Exception '[WinError 6] The handle is invalid'
The issue / workaround is described here (see stackoverflow link) - subprocess throws exception where it fails to find std-in handle with argument stdin=None to Popen(). Using the same work around from the link corrected my issue running as a Windows Service:
The work-around, was to add something like the stdout_sink for stdin (see below) prior to calling Popen() within Git.execute():
log.debug("Popen(%s, cwd=%s, universal_newlines=%s, shell=%s)",
command, cwd, universal_newlines, shell)
+ if( istream is None):
+ istream = subprocess.DEVNULL
try:
proc = Popen(command,
Not sure this if is the best solution, but it allows me to use GitPython running as Windows Service.
Thanks a lot for the summary! It looks like a simple change that could easily become a PR. The only problem might be that subprocess.DEVNULL
is not available in all versions of Python that GitPython supports.
FWIW, we are experiencing the flood of similar issues on windows in DataLad. Unfortunately I do not see a permalink to the appveyor log, so here is a sample of tracebacks:
======================================================================
ERROR: datalad.support.tests.test_gitrepo.test_GitRepo_get_merge_base
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Miniconda35\envs\test-environment\lib\site-packages\git\cmd.py", line 735, in execute
**subprocess_kwargs
File "C:\Miniconda35\envs\test-environment\lib\subprocess.py", line 845, in __init__
_cleanup()
File "C:\Miniconda35\envs\test-environment\lib\subprocess.py", line 505, in _cleanup
res = inst._internal_poll(_deadstate=sys.maxsize)
File "C:\Miniconda35\envs\test-environment\lib\subprocess.py", line 1255, in _internal_poll
if _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0:
OSError: [WinError 6] The handle is invalid
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Miniconda35\envs\test-environment\lib\site-packages\nose\case.py", line 198, in runTest
self.test(*self.arg)
File "C:\Miniconda35\envs\test-environment\lib\site-packages\datalad\tests\utils.py", line 591, in newfunc
return t(*(arg + (filename,)), **kw)
File "C:\Miniconda35\envs\test-environment\lib\site-packages\datalad\support\tests\test_gitrepo.py", line 802, in test_GitRepo_get_merge_base
repo = GitRepo(src, create=True)
File "C:\Miniconda35\envs\test-environment\lib\site-packages\datalad\support\repo.py", line 146, in __call__
instance = type.__call__(cls, *new_args, **new_kwargs)
File "C:\Miniconda35\envs\test-environment\lib\site-packages\datalad\support\gitrepo.py", line 586, in __init__
**git_opts)
File "C:\Miniconda35\envs\test-environment\lib\site-packages\datalad\cmd.py", line 189, in __call__
return self.call(cmd, *args, **kwargs)
File "C:\Miniconda35\envs\test-environment\lib\site-packages\datalad\cmd.py", line 570, in call
return f(*args, **kwargs)
File "C:\Miniconda35\envs\test-environment\lib\site-packages\git\repo\base.py", line 906, in init
git.init(**kwargs)
File "C:\Miniconda35\envs\test-environment\lib\site-packages\git\cmd.py", line 548, in <lambda>
return lambda *args, **kwargs: self._call_process(name, *args, **kwargs)
File "C:\Miniconda35\envs\test-environment\lib\site-packages\git\cmd.py", line 1014, in _call_process
return self.execute(call, **exec_kwargs)
File "C:\Miniconda35\envs\test-environment\lib\site-packages\git\cmd.py", line 738, in execute
raise GitCommandNotFound(command, err)
git.exc.GitCommandNotFound: Cmd('git') not found due to: OSError('[WinError 6] The handle is invalid')
cmdline: git init
On a quick try the aforementioned trick with stdin didn't help. It would be really appreciated if someone got down to the bottom of the issue here.