Repository: gitpython-developers/GitPython

Issue #637: Fails on import with custom exception
Created: 2017-06-12T15:41:44Z
On Windows, without git available on path, the following happens on import of GitPython:
[package stack]
    from git.exc import GitError
  File "C:\Miniconda3\lib\site-packages\git\__init__.py", line 45, in <module>
    from git.repo import Repo               # @NoMove @IgnorePep8
  File "C:\Miniconda3\lib\site-packages\git\repo\__init__.py", line 4, in <module>
    from .base import *
  File "C:\Miniconda3\lib\site-packages\git\repo\base.py", line 31, in <module>
    from git.remote import Remote, add_progress, to_progress_instance
  File "C:\Miniconda3\lib\site-packages\git\remote.py", line 190, in <module>
    class FetchInfo(object):
  File "C:\Miniconda3\lib\site-packages\git\remote.py", line 219, in FetchInfo
    v = Git().version_info[:2]
  File "C:\Miniconda3\lib\site-packages\git\cmd.py", line 461, in version_info
    return self._version_info
  File "C:\Miniconda3\lib\site-packages\git\cmd.py", line 424, in __getattr__
    return LazyMixin.__getattr__(self, name)
  File "C:\Miniconda3\lib\site-packages\gitdb\util.py", line 256, in __getattr__
    self._set_cache_(attr)
  File "C:\Miniconda3\lib\site-packages\git\cmd.py", line 444, in _set_cache_
    version_numbers = self._call_process('version').split(' ')[2]
  File "C:\Miniconda3\lib\site-packages\git\cmd.py", line 877, in _call_process
    return self.execute(call, **exec_kwargs)
  File "C:\Miniconda3\lib\site-packages\git\cmd.py", line 602, in execute
    raise GitCommandNotFound(command, err)
git.exc.GitCommandNotFound: Cmd('git') not found due to: FileNotFoundError('[WinError 2] The system cannot find the file specified')
  cmdline: git version
Since it fails while trying to import the exception type that it raises (GitError), the only way to catch the error is with a try: ... except Exception: block, which is needlessly wide. It would be nice if a better pattern was available for conditional use of the package.

Duplicate issue #657: [GitPython >= 2.1.4] Can't import without git CLI
Created: 2017-08-10T21:08:55Z
Description of Problem
Since GitPython 2.1.4, the initial import git fails because it invokes the git CLI, raising a git.exc.GitCommandNotFound error. However, due to the chicken-and-egg nature of this import, it is impossible for one to catch a git.exc.GitCommandNotFound error.
Steps to Reproduce
Install GitPython >= 2.1.4 on a box without git installed on it. An easy way to do this is to launch a Cent 7 docker container (which does not come with git installed off the base image), and then install GitPython (first installing EPEL repo and pip for ease of installation).
% docker run --rm -it centos:7 bash
[root@c1c079f693dc /]# yum --quiet -y install epel-release
warning: /var/cache/yum/x86_64/7/extras/packages/epel-release-7-9.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
Public key for epel-release-7-9.noarch.rpm is not installed
Importing GPG key 0xF4A80EB5:
 Userid     : "CentOS-7 Key (CentOS 7 Official Signing Key) <security@centos.org>"
 Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5
 Package    : centos-release-7-3.1611.el7.centos.x86_64 (@CentOS)
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
[root@c1c079f693dc /]# yum --quiet -y install python-pip
warning: /var/cache/yum/x86_64/7/epel/packages/python2-pip-8.1.2-5.el7.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID 352c64e5: NOKEY
Public key for python2-pip-8.1.2-5.el7.noarch.rpm is not installed
Importing GPG key 0x352C64E5:
 Userid     : "Fedora EPEL (7) <epel@fedoraproject.org>"
 Fingerprint: 91e9 7d7c 4a5e 96f1 7f3e 888f 6a2f aea2 352c 64e5
 Package    : epel-release-7-9.noarch (@extras)
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
[root@c1c079f693dc /]# command -v git && echo git is installed || echo git is not installed
git is not installed
root@c1c079f693dc /]# pip install GitPython
Collecting GitPython
  Downloading GitPython-2.1.5-py2.py3-none-any.whl (443kB)
    100% |################################| 450kB 1.0MB/s
Collecting gitdb2>=2.0.0 (from GitPython)
  Downloading gitdb2-2.0.2-py2.py3-none-any.whl (63kB)
    100% |################################| 71kB 2.1MB/s
Collecting smmap2>=2.0.0 (from gitdb2>=2.0.0->GitPython)
  Downloading smmap2-2.0.3-py2.py3-none-any.whl
Installing collected packages: smmap2, gitdb2, GitPython
Successfully installed GitPython-2.1.5 gitdb2-2.0.2 smmap2-2.0.3
You are using pip version 8.1.2, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

Now attempt to import:
[root@c1c079f693dc /]# python -c 'import git'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python2.7/site-packages/git/__init__.py", line 45, in <module>
    from git.repo import Repo               # @NoMove @IgnorePep8
  File "/usr/lib/python2.7/site-packages/git/repo/__init__.py", line 4, in <module>
    from .base import *
  File "/usr/lib/python2.7/site-packages/git/repo/base.py", line 31, in <module>
    from git.remote import Remote, add_progress, to_progress_instance
  File "/usr/lib/python2.7/site-packages/git/remote.py", line 190, in <module>
    class FetchInfo(object):
  File "/usr/lib/python2.7/site-packages/git/remote.py", line 219, in FetchInfo
    v = Git().version_info[:2]
  File "/usr/lib/python2.7/site-packages/git/cmd.py", line 461, in version_info
    return self._version_info
  File "/usr/lib/python2.7/site-packages/git/cmd.py", line 424, in __getattr__
    return LazyMixin.__getattr__(self, name)
  File "/usr/lib/python2.7/site-packages/gitdb/util.py", line 256, in __getattr__
    self._set_cache_(attr)
  File "/usr/lib/python2.7/site-packages/git/cmd.py", line 444, in _set_cache_
    version_numbers = self._call_process('version').split(' ')[2]
  File "/usr/lib/python2.7/site-packages/git/cmd.py", line 877, in _call_process
    return self.execute(call, **exec_kwargs)
  File "/usr/lib/python2.7/site-packages/git/cmd.py", line 602, in execute
    raise GitCommandNotFound(command, err)
git.exc.GitCommandNotFound: Cmd('git') not found due to: OSError('[Errno 2] No such file or directory')
  cmdline: git version

If you then downgrade to before version 2.1.4, the import works fine since the initial import no longer seems to be trying to invoke the git CLI:
[root@c1c079f693dc /]# pip install 'GitPython<2.1.4'
Collecting GitPython<2.1.4
  Downloading GitPython-2.1.3-py2.py3-none-any.whl (442kB)
    100% |################################| 450kB 993kB/s
Requirement already satisfied (use --upgrade to upgrade): gitdb2>=2.0.0 in /usr/lib/python2.7/site-packages (from GitPython<2.1.4)
Requirement already satisfied (use --upgrade to upgrade): smmap2>=2.0.0 in /usr/lib/python2.7/site-packages (from gitdb2>=2.0.0->GitPython<2.1.4)
Installing collected packages: GitPython
  Found existing installation: GitPython 2.1.5
    Uninstalling GitPython-2.1.5:
      Successfully uninstalled GitPython-2.1.5
Successfully installed GitPython-2.1.3
You are using pip version 8.1.2, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
[root@c1c079f693dc /]# python -c 'import git'
[root@c1c079f693dc /]#

Closing comment (2017-08-14T12:25:47Z): This is the same as #637, and as I mentioned there another solution would be #640.
The PR's fundamental change allows the user to dynamically set their git executable path after importing the module. This change just happens to also address the import issue.