GitPython icon indicating copy to clipboard operation
GitPython copied to clipboard

Failure to run as Windows Service ( [WinError 6] on subprocess.Popen )

Open mikkelcp1 opened this issue 7 years ago • 2 comments

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.

mikkelcp1 avatar Feb 07 '18 15:02 mikkelcp1

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.

Byron avatar Feb 24 '18 13:02 Byron

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.

yarikoptic avatar Sep 05 '18 17:09 yarikoptic