Skip to content

Refreshing doesn't invalidate cached version_info #1829

Closed
@EliahKagan

Description

@EliahKagan

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):

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions