gitpython-developers / GitPython

GitPython is a python library used to interact with Git repositories.

Home Page:http://gitpython.readthedocs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Refreshing doesn't invalidate cached version_info

EliahKagan opened this issue Β· comments

The version_info property of Git instances is cached per-instance, while the git.refresh function and Git.refresh class method modify global state. When version_info has been read on a Git instance, refreshing affects the behavior of that instance, but does not invalidate the cache, causing the version_info property and dynamic version method to give inconsistent results even when no changes to environment variables or the filesystem have occurred.

Here's an example produced on a CentOS 7 system where I have both the system git and a newer upstream git installed:

ek in 🌐 Eald in GitPython on ξ‚  main via 🐍 v3.12.1 via πŸ…’ GitPython
❯ type -a git
git is /home/ek/bin/git
git is /usr/bin/git

ek in 🌐 Eald in GitPython on ξ‚  main via 🐍 v3.12.1 via πŸ…’ GitPython
❯ git --version
git version 2.43.0

ek in 🌐 Eald in GitPython on ξ‚  main via 🐍 v3.12.1 via πŸ…’ GitPython
❯ /usr/bin/git --version
git version 1.8.3.1

ek in 🌐 Eald in GitPython on ξ‚  main via 🐍 v3.12.1 via πŸ…’ GitPython
❯ python
Python 3.12.1 | packaged by conda-forge | (main, Dec 23 2023, 08:03:24) [GCC 12.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import git
>>> g1 = git.Git()
>>> g2 = git.Git()
>>> g1.version_info
(2, 43, 0)
>>> git.refresh("/usr/bin/git")
>>> g1.version()
'git version 1.8.3.1'
>>> g2.version()
'git version 1.8.3.1'
>>> g1.version_info
(2, 43, 0)
>>> g2.version_info
(1, 8, 3, 1)

Because I had accessed g1.version_info before refreshing, the stale version information is handed back even after the refresh.

This is admittedly consistent with how version_info is documented:

This value is generated on demand and is cached.

But it seems to me that the documentation, as currently written, does not prevent it from being surprising. I think that either this should be made clear in the version_info property docstring, or the behavior should be changed so that refreshing invalidates all Git instances' cached version_info properties. I am not sure which is better, because I don't know why version_info is cached (and cached per instance).

This issue can probably be considered minor. In particular, this does not prevent FetchInfo.refresh (which git.refresh calls after calling Git.refresh) from updating FetchInfo._flag_map correctly, because FetchInfo.refresh accesses version_info on a newly created Git instance:

if Git().version_info[:2] >= (2, 10):

Thanks for investigating!

Indeed, since version_info is also used within GitPython, it's definitely a mistake to leave it stale. But even if it wasn't, users might well rely on it.

The reason this didn't come up earlier is probably that people rather restart the program than refreshing the Git version after changes.