Revise comments, docstrings, some messages, and a bit of code by EliahKagan · Pull Request #1725 · gitpython-developers/GitPython

added 30 commits

October 21, 2023 23:49
This intended '\' literally, but it was actually '' because the \'
became just ' (backslash-apostrophe becomes just aspostrophe).
This improves consistency, because most were already. For a few it
allows backslashes to removed, improving readability. Even for the
others, some editors will highlight them as regular expressions now
that they are raw string literals.
These are a couple strings that, in addition to not having any
escape sequences, don't represent regular expressions, Windows
paths, or anything else that would be clarified by raw literals.
In the git.diff.Diff class, the _index_from_patch_format and
_index_from_raw_format methods' docstrings had still described them
as reading from streams, even though they have instead read from
processes (and taken "proc", not "stream", arguments) since gitpython-developers#519
when the change was made in a5db3d3 to fix a freezing bug.

This updates the docstrings to reflect that they read from
processes.
The message refers to the (public) working_tree_dir attribute by
name, so that should be uncapitalized to reflect the case by which
it must be accessed, even when it appears at the beginning of a
sentence.
The git.objects.commit.Commit._deserialize method stopped accepting
a param_from_rev_list argument in ae5a69f, but the documentation
for that parameter was never removed.

Because that was the only part of the method's docstring, and it is
a nonpublic method, and the associated _serialize method does not
have a docstring, this change simply removes the _deserialize
method's docstring without adding anything.
The local (i.e. late) import was removed in 7b3ef45, but the
comment about it on (what was) the preceding line has persisted
until now.
This changes

    master repository

to
    superproject (master repository)

in the RootModule class docstring and in the tutorial, to make even
clearer what this is referring to. This way, users who are less
familiar with submodules will be less likely to confuse this with
a "master" branch (since "master" is one of the popular default
branch names), while users who are more familiar with submodules
and may search for the official term "superproject" will find the
docs when doing so.

This retains "master repository" parenthesized rather than
completely replacing it because although "superproject" is the
official term for this, it is a bit obscure and unintuitive.
Since the hyphen spelling is what the official Git docs use.

This change affects only docstrings.
Reference.set_object explains its handling of oldbinsha by quoting
a comment from refs.c in the Git source code. However, that comment
now appears in refs/files-backend.c in that codebase. This updates
the reference so readers can look it up and find the comment in its
surrounding context.

The commit to the git project's source code that moved the code
that includes that comment is:

git/git@7bd9bcf
This rarely-seen ValueError message had said SymbolicRef, and is
now changed to SymbolicReference.
Since the value of __class__ is a type, comparing it to another
type object should use "is" rather than "==".

Some of these, involving type(), were fixed in bf7af69, but flake8
did not catch the .__class__ variation addressed here.
In the git module (including the modules it contains).

This also makes one small change in doc/ to synchronize with a
change made in a docstring.
The is_cygwin_git function returns False when we have is_win,
because is_win is not True on Cygwin systems. The existing comment
explained why, but was tentative. The claims are accurate, so this
rewrites the comment to state it more definitively.
Within the git module.

In Python 2, it was necessary to inherit from object to have a
new-style class. In Python 3, all classes are new-style classes,
and inheritance from object is implied.

Usually, removing explicit inheritance from object is only a small
clarity benefit while modernizing Python codebases. However, in
GitPython, the benefit is greater, because it is possible to
confuse object (the root of the Python class hierarchy) with
Object (the root of the GitPython subhierarchy of classes
representing things in the git object model).
Most already were, but a few were strings.
Intentionally untouched test modules in this commit:

- Modules where there are no such changes to be made.

- Modules in test/performance/ -- will be done separately.

- test/lib/ modules (these are test *helpers* and will be done
  separately).

- test/test_util.py, because although it has a few comments that
  might be improved, it may make more sense to do that together
  with some further refactoring changes.
It benefits from a docstring because it is not referenced in code
or documentation, and its purpose is/was otherwise unclear.

The docstring includes a reference to gitpython-developers#1188 for more information.
This modifies content of the strings themselves, but only slightly.

- Make an exception message more readable.

- Improve spacing of the "python -c" script string in the sys.path
  test.
This futher improves some wording in docstrings and comments in a
handful of places within the git module.
:return: was used extensively, while :returns: only appeared in two
docstrings.
Changes that fix the message itself:

- Add a missing space between words (two parts were concatenated,
  with no space at the edge of either).

- Capitalize "GitPython" since that is the repo and project name.

Changes that improve how the message is produced:

- Make the entire literal part of the string the format string,
  instead of formatting the first part and concatenating the second
  part.

- Pass the format string and k_env_git_repo variable as separate
  arguments to logging.info, so the logging machinery takes care of
  substituting it for %s, rather than doing the substitution.
This removes the Windows-specific information in the warning
message in git_daemon_launched.

After the associated functionality was updated in gitpython-developers#1684 and the
warning message was abridged accordingly, the functionality was
updated again in gitpython-developers#1697, causing the message to be outdated and no
longer helpeful (since having git-daemon.exe in a PATH directory is
no longer necessary or useful), without any corresponding change to
the message.
In the git module (including modules it contains).

This does not add any new "# end" or "# END" comments. Instead, it
improves the consistency and clarity of existing ones by converting
each "# end" comment to "# END" (since capitalization was not used
systematically to indicate nesting level or other semantic
information, and capitalizing "END" makes clear the nature of the
comment), and by adding some information to a few of the comments.

This also removes end comments that did not provide information or
significant visual indication that a "section" was ending, or where
the visual indication they provided was at least as well provided
by replacing them with a blank line. However, it does *not* attempt
to apply this change everywhere it might be applicable.

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Nov 3, 2023
This removes a comment noting that a try-finally block had been
present (or had been intended), but was removed because some
version of Python had imposed a limitation on yield appearing in
try-finally.

That comment was obsolete as of 58c5b99 (gitpython-developers#326), which wrapped the
relevant code in a with-statement, because:

1. Since then, the cleanup is done in a manner equivaent to
   try-finally.

2. It turned out, as noted in that PR, that cleanup had not
   always been done automatically. (This was contrary to the
   prediction given in the comment.)

3. At some point before that, the limitation that had prevented
   the use of try-finally no longer affected any supported version
   of Python.

   Specifically, it appears the only limitation that this could be
   was the limitation lifted in Python 2.5, where along with the
   addition of the close() method which causes try-finally to be
   called (and is itself called when a generator object is
   finalized), yield in a try-block with an associated
   finally-block became permitted, since the call to close() was
   sufficient to run the finally-block (by raising GeneratorExit).

   For details, see:
   https://docs.python.org/3/whatsnew/2.5.html#pep-342-new-generator-features

(This obsolete comment was one of the things I discovered while
working on gitpython-developers#1725, but I didn't include this change there, having
not yet looked into the history of the code enough to be sure.)

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Nov 3, 2023
This removes a comment noting that a try-finally block had been
present (or had been intended), but was removed because some
version of Python had imposed a limitation on yield appearing in
try-finally.

That comment was obsolete as of 58c5b99 (gitpython-developers#326), which wrapped the
relevant code in a with-statement, because:

1. Since then, the cleanup is done in a manner equivaent to
   try-finally.

2. It turned out, as noted in that PR, that cleanup had not
   always been done automatically. (This was contrary to the
   prediction given in the comment.)

3. At some point before that, the limitation that had prevented
   the use of try-finally no longer affected any supported version
   of Python.

   Specifically, it appears the only limitation that this could be
   was the limitation lifted in Python 2.5, where along with the
   introduction of close(), which is automatically called when a
   generator object is finalized, it became permitted for yield to
   appear in a try-block with an associated finally-block, on the
   grounds that calling close() runs the finally-block (by raising
   GeneratorExit).

   For details, see:
   https://docs.python.org/3/whatsnew/2.5.html#pep-342-new-generator-features

(This obsolete comment was one of the things I discovered while
working on gitpython-developers#1725, but I didn't include this change there, having
not yet looked into the history of the code enough to be sure.)

This was referenced

Nov 3, 2023

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Dec 22, 2023

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Dec 22, 2023

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Dec 22, 2023
These are "non-reified docstrings" as described in gitpython-developers#1734. They are
not made part of the data model, but most editors will display
them, including on symbols present in code of other projects that
use the GitPython library. A number of these have already been
added, but this adds what will probably be most of the remaining
ones.

For the most part, this doesn't create documentation where there
wasn't any, but instead converts existing comments to "docstrings."
In a handful of cases, they are expanded, reworded, or a docstring
added.

This also fixes some small style inconsistencies that were missed
in gitpython-developers#1725, and moves a comment that had become inadvertently
displaced due to autoformatting to the item it was meant for.

The major omission here is HIDE_WINDOWS_KNOWN_ERRORS and
HIDE_WINDOWS_FREEZE_ERRORS. This doesn't convert the comments above
them to "docstrings," for a few reasons. They are not specific to
either of the symbols, they are oriented toward considerations that
are not really relevant except when developing GitPython itself,
and they are out of date. Also, because HIDE_WINDOWS_KNOWN_ERRORS
is listed in __all__, increasing the level of documentation for it
might be taken as a committment to preserve some aspect of its
current behavior, which could interfere with progress on gitpython-developers#790. So
I've kept those comments as comments, and unchanged, for now.

lettuce-bot bot referenced this pull request in lettuce-financial/github-bot-signed-commit

Jan 10, 2024

renovate bot referenced this pull request in allenporter/flux-local

Jan 11, 2024

This was referenced

Jan 16, 2024

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Feb 25, 2024
Except for:

- git.cmd, where docstrings were revised in a374b8c.

- git.types, where docstring changes may best be made together with
  changes to how imports are organized and documented, which seems
  not to be in the same scope as the changes in this commit.

This change, as well as those in a374b8c, are largely along the
lines gitpython-developers#1725, with most revisions here being to docstrings and a few
being to comments.

The major differences between the kinds of docstring changes here
and those ind gitpython-developers#1725 are that the changes here push somewhat harder
for consistency and apply some kinds of changes I was reluctant to
apply widely in gitpython-developers#1725:

- Wrap all docstrings and comments to 88 columns, except for parts
  that are decisively clearer when not wrapped. Note that semi-
  paragraph changes represented as single newlines are still kept
  where meaningful, which is one reason this is not always the same
  effect as automatic wrapping would produce.

- Avoid code formatting (double backticks) for headings that
  precede sections and code blocks. This was done enough that it
  seems to have been intentional, but it doesn't really have the
  right semantics, and the documentation is currently rendering in
  such a way (including on readthedocs.org) where removing that
  formatting seems clearly better.

- References (single backticks with a role prefix) and code spans
  (double backticks) everywhere applicable, even in the first lines
  of docstrings.

- Single-backticks around parameter names, with no role prefix.
  These were mostly either formatted that way or emphasized (with
  asterisks). This is one of the rare cases that I have used single
  backticks without a role prefix, which ordinarily should be
  avoided, but to get a role for references to a function's
  parameters within that function, a plugin would be needed. In the
  rare case that one function's docstring refers to another
  function's parameters by names those are double-backticked as
  code spans (and where applicable the name of the referred-to
  function is single-backticked with the :func: or :meth: role).

- All sections, such as :param blah:, :note:, and :return:, now
  have a newline before any text in them. This was already often
  but far from always done, and the style was overall inconsistent.
  Of consistent approaches that are clear and easy to write, this
  is the simplest. It also seems to substantially improve
  readability, when taken together with...

- Sections are always separated by a blank line, even if they are
  very short.

- Essentially unlimited use of `~a.b.c`, where applicable, to refer
  and link to the documentation for a.b.c while showing the text
  "a" and revealing "a.b.c" on hover. I had previously somewhat
  limited my use of this tilde notation in case readers of the
  source code itself (where it is not rendered) weren't familiar
  with it, but at the cost of less consistency in when an entity
  was referred to. There remain a couple places in git.util where
  I do not do this because the explicit form `a <a.b.c>`, which is
  equivalent, lined things up better and was thus easier to read.

Those are the major differences between the approach taken here
and in gitpython-developers#1725, but not necessarily most of the changes done here
(many of which are the same kinds of revisions as done there).

Note that this commit only modifies some git/*.py files, and there
are more git/**/*.py files that remain to be revised accordingly.

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Feb 25, 2024
Except for:

- git.cmd, where docstrings were revised in a374b8c.

- git.types, where docstring changes may best be made together with
  changes to how imports are organized and documented, which seems
  not to be in the same scope as the changes in this commit.

This change, as well as those in a374b8c, are largely along the
lines of gitpython-developers#1725, with most revisions here being to docstrings and a
few being to comments.

The major differences between the kinds of docstring changes here
and those ind gitpython-developers#1725 are that the changes here push somewhat harder
for consistency and apply some kinds of changes I was reluctant to
apply widely in gitpython-developers#1725:

- Wrap all docstrings and comments to 88 columns, except for parts
  that are decisively clearer when not wrapped. Note that semi-
  paragraph changes represented as single newlines are still kept
  where meaningful, which is one reason this is not always the same
  effect as automatic wrapping would produce.

- Avoid code formatting (double backticks) for headings that
  precede sections and code blocks. This was done enough that it
  seems to have been intentional, but it doesn't really have the
  right semantics, and the documentation is currently rendering in
  such a way (including on readthedocs.org) where removing that
  formatting seems clearly better.

- References (single backticks with a role prefix) and code spans
  (double backticks) everywhere applicable, even in the first lines
  of docstrings.

- Single-backticks around parameter names, with no role prefix.
  These were mostly either formatted that way or emphasized (with
  asterisks). This is one of the rare cases that I have used single
  backticks without a role prefix, which ordinarily should be
  avoided, but to get a role for references to a function's
  parameters within that function, a plugin would be needed. In the
  rare case that one function's docstring refers to another
  function's parameters by names those are double-backticked as
  code spans (and where applicable the name of the referred-to
  function is single-backticked with the :func: or :meth: role).

- All sections, such as :param blah:, :note:, and :return:, now
  have a newline before any text in them. This was already often
  but far from always done, and the style was overall inconsistent.
  Of consistent approaches that are clear and easy to write, this
  is the simplest. It also seems to substantially improve
  readability, when taken together with...

- Sections are always separated by a blank line, even if they are
  very short.

- Essentially unlimited use of `~a.b.c`, where applicable, to refer
  and link to the documentation for a.b.c while showing the text
  "a" and revealing "a.b.c" on hover. I had previously somewhat
  limited my use of this tilde notation in case readers of the
  source code itself (where it is not rendered) weren't familiar
  with it, but at the cost of less consistency in when an entity
  was referred to. There remain a couple places in git.util where
  I do not do this because the explicit form `a <a.b.c>`, which is
  equivalent, lined things up better and was thus easier to read.

Those are the major differences between the approach taken here
and in gitpython-developers#1725, but not necessarily most of the changes done here
(many of which are the same kinds of revisions as done there).

Note that this commit only modifies some git/*.py files, and there
are more git/**/*.py files that remain to be revised accordingly.

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Feb 26, 2024
Except for:

- git.cmd, where docstrings were revised in e08066c.

- git.types, where docstring changes may best be made together with
  changes to how imports are organized and documented, which seems
  not to be in the same scope as the changes in this commit.

This change, as well as those in e08066c, are largely along the
lines of gitpython-developers#1725, with most revisions here being to docstrings and a
few being to comments.

The major differences between the kinds of docstring changes here
and those ind gitpython-developers#1725 are that the changes here push somewhat harder
for consistency and apply some kinds of changes I was reluctant to
apply widely in gitpython-developers#1725:

- Wrap all docstrings and comments to 88 columns, except for parts
  that are decisively clearer when not wrapped. Note that semi-
  paragraph changes represented as single newlines are still kept
  where meaningful, which is one reason this is not always the same
  effect as automatic wrapping would produce.

- Avoid code formatting (double backticks) for headings that
  precede sections and code blocks. This was done enough that it
  seems to have been intentional, but it doesn't really have the
  right semantics, and the documentation is currently rendering in
  such a way (including on readthedocs.org) where removing that
  formatting seems clearly better.

- References (single backticks with a role prefix) and code spans
  (double backticks) everywhere applicable, even in the first lines
  of docstrings.

- Single-backticks around parameter names, with no role prefix.
  These were mostly either formatted that way or emphasized (with
  asterisks). This is one of the rare cases that I have used single
  backticks without a role prefix, which ordinarily should be
  avoided, but to get a role for references to a function's
  parameters within that function, a plugin would be needed. In the
  rare case that one function's docstring refers to another
  function's parameters by names those are double-backticked as
  code spans (and where applicable the name of the referred-to
  function is single-backticked with the :func: or :meth: role).

- All sections, such as :param blah:, :note:, and :return:, now
  have a newline before any text in them. This was already often
  but far from always done, and the style was overall inconsistent.
  Of consistent approaches that are clear and easy to write, this
  is the simplest. It also seems to substantially improve
  readability, when taken together with...

- Sections are always separated by a blank line, even if they are
  very short.

- Essentially unlimited use of `~a.b.c`, where applicable, to refer
  and link to the documentation for a.b.c while showing the text
  "a" and revealing "a.b.c" on hover. I had previously somewhat
  limited my use of this tilde notation in case readers of the
  source code itself (where it is not rendered) weren't familiar
  with it, but at the cost of less consistency in when an entity
  was referred to. There remain a couple places in git.util where
  I do not do this because the explicit form `a <a.b.c>`, which is
  equivalent, lined things up better and was thus easier to read.

Those are the major differences between the approach taken here
and in gitpython-developers#1725, but not necessarily most of the changes done here
(many of which are the same kinds of revisions as done there).

Note that this commit only modifies some git/*.py files, and there
are more git/**/*.py files that remain to be revised accordingly.

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Feb 27, 2024
The original problem where the backslash wasn't included in the
docstring at all was fixed in 7dd2095 (gitpython-developers#1725), but the backslash
still did not appear in rendered Sphinx documentation, because it
was also treated as a reStructuredText metacharacter.

Although that can be addressed by adding a further backslash to
escape it, the effect is ambiguous when the docstring is read in
the code. So this just encloses it in a double-backticked code
span instead, which is a somewhat clearer way to show it anyway.

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Feb 28, 2024

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Mar 4, 2024

otc-zuul bot pushed a commit to opentelekomcloud-infra/eyes_on_docs that referenced this pull request

Mar 6, 2024

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Mar 8, 2024
In 6126997 (gitpython-developers#1725), I had meant to have the git.objects.tag module
docstring say that the module defined the TagObject class, to help
ensure no one would confuse this with the TagReference class. But I
instead had it wrongly say it defined the TagReference class! This
fixes that.

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Mar 8, 2024
In cd16a35 (gitpython-developers#1725), I had taken "Treeish" to mean the type of that
exact name, git.index.base.Treeish. But that type is only used
within the git.index package (actually only in git.index.base
itself). It is also nonpublic: git.index.base.__all__ exists and
does not list it.

So most likely this was not intended in the git.diff.Diffable.diff
docstring. Even if intended, it does not appear accurate, since the
git.index.base.Treeish union includes bytes, and the logic in
Diffable.diff and its helpers does not appear to accommodate bytes.

A closer type is the public git.types.Tree_ish union, which is
narrower than git.index.base.Treeish, including neither str nor
bytes. However, it does not include str, and Diffable.diff does
accept str to specify a tree-ish for diff-ing. It may be that
"Treeish" in the pre-gitpython-developers#1725 docstring was capitalized for some
reason other than to identify a type defined in GitPython's code.

For now, I've changed it to refer to git.types.Tree_ish, but also
explicitly documented that a string can be used to specify a
tree-ish -- which is independently valuable, since previously the
effect of passing a str instance to the diff method was not stated
anywhere in the method docstring. To clarify further, I included a
link to tree-ish in gitglossary(7) as well.

In addition, the original wording before cd16a35 had included
"(type)", which I had erroneously assumed was just meant to state
that it is a type (i.e. a class), so I had wrongly removed it
without replacing it with anything when making it into a reference
to a type. But it was really an attempt to clarify that
Diffable.Index should be used directly, rather than an instance of
it. That is in effect the opposite of merely pointing out that it
is a class; it is to express that it should be used in a way that
does not depend in any way on it being a class. This commit has the
docstring explicitly state that.

EliahKagan added a commit to EliahKagan/GitPython that referenced this pull request

Mar 8, 2024
In cd16a35 (gitpython-developers#1725), I had taken "Treeish" to mean the type of that
exact name, git.index.base.Treeish. But that type is only used
within the git.index package (actually only in git.index.base
itself). It is also nonpublic: git.index.base.__all__ exists and
does not list it.

So most likely this was not intended in the git.diff.Diffable.diff
docstring. Even if intended, it does not appear accurate, since the
git.index.base.Treeish union includes bytes, and the logic in
Diffable.diff and its helpers does not appear to accommodate bytes.

A closer type is the public git.types.Tree_ish union, which is
narrower than git.index.base.Treeish, including neither str nor
bytes. However, it does not include str, and Diffable.diff does
accept str to specify a tree-ish for diff-ing. It may be that
"Treeish" in the pre-gitpython-developers#1725 docstring was capitalized for some
reason other than to identify a type defined in GitPython's code.

For now, I've changed it to refer to git.types.Tree_ish, but also
explicitly documented that a string can be used to specify a
tree-ish -- which is independently valuable, since previously the
effect of passing a str instance to the diff method was not stated
anywhere in the method docstring. To clarify further, I included a
link to tree-ish in gitglossary(7) as well.

In addition, the original wording before cd16a35 had included
"(type)", which I had erroneously assumed was just meant to state
that it is a type (i.e. a class), so I had wrongly removed it
without replacing it with anything when making it into a reference
to a type. But it was really an attempt to clarify that
Diffable.Index should be used directly, rather than an instance of
it. That is in effect the opposite of merely pointing out that it
is a class; it is to express that it should be used in a way that
does not depend in any way on it being a class. This commit has the
docstring explicitly state that.

JoeWang1127 referenced this pull request in googleapis/sdk-platform-java

Apr 6, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [GitPython](https://togithub.com/gitpython-developers/GitPython) |
`==3.1.40` -> `==3.1.41` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/GitPython/3.1.41?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/GitPython/3.1.41?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/GitPython/3.1.40/3.1.41?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/GitPython/3.1.40/3.1.41?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

### GitHub Vulnerability Alerts

####
[CVE-2024-22190](https://togithub.com/gitpython-developers/GitPython/security/advisories/GHSA-2mqj-m65w-jghx)

### Summary

This issue exists because of an incomplete fix for CVE-2023-40590. On
Windows, GitPython uses an untrusted search path if it uses a shell to
run `git`, as well as when it runs `bash.exe` to interpret hooks. If
either of those features are used on Windows, a malicious `git.exe` or
`bash.exe` may be run from an untrusted repository.

### Details

Although GitPython often avoids executing programs found in an untrusted
search path since 3.1.33, two situations remain where this still occurs.
Either can allow arbitrary code execution under some circumstances.

#### When a shell is used

GitPython can be told to run `git` commands through a shell rather than
as direct subprocesses, by passing `shell=True` to any method that
accepts it, or by both setting `Git.USE_SHELL = True` and not passing
`shell=False`. Then the Windows `cmd.exe` shell process performs the
path search, and GitPython does not prevent that shell from finding and
running `git` in the current directory.

When GitPython runs `git` directly rather than through a shell, the
GitPython process performs the path search, and currently omits the
current directory by setting `NoDefaultCurrentDirectoryInExePath` in its
own environment during the `Popen` call. Although the `cmd.exe` shell
will honor this environment variable when present, GitPython does not
currently pass it into the shell subprocess's environment.

Furthermore, because GitPython sets the subprocess CWD to the root of a
repository's working tree, using a shell will run a malicious `git.exe`
in an untrusted repository even if GitPython itself is run from a
trusted location.

This also applies if `Git.execute` is called directly with `shell=True`
(or after `Git.USE_SHELL = True`) to run any command.

#### When hook scripts are run

On Windows, GitPython uses `bash.exe` to run hooks that appear to be
scripts. However, unlike when running `git`, no steps are taken to avoid
finding and running `bash.exe` in the current directory.

This allows the author of an untrusted fork or branch to cause a
malicious `bash.exe` to be run in some otherwise safe workflows. An
example of such a scenario is if the user installs a trusted hook while
on a trusted branch, then switches to an untrusted feature branch
(possibly from a fork) to review proposed changes. If the untrusted
feature branch contains a malicious `bash.exe` and the user's current
working directory is the working tree, and the user performs an action
that runs the hook, then although the hook itself is uncorrupted, it
runs with the malicious `bash.exe`.

Note that, while `bash.exe` is a shell, this is a separate scenario from
when `git` is run using the unrelated Windows `cmd.exe` shell.

### PoC

On Windows, create a `git.exe` file in a repository. Then create a
`Repo` object, and call any method through it (directly or indirectly)
that supports the `shell` keyword argument with `shell=True`:

```powershell
mkdir testrepo
git init testrepo
cp ... testrepo git.exe # Replace "..." with any executable of choice.
python -c "import git; print(git.Repo('testrepo').git.version(shell=True))"
```

The `git.exe` executable in the repository directory will be run.

Or use no `Repo` object, but do it from the location with the `git.exe`:

```powershell
cd testrepo
python -c "import git; print(git.Git().version(shell=True))"
```

The `git.exe` executable in the current directory will be run.

For the scenario with hooks, install a hook in a repository, create a
`bash.exe` file in the current directory, and perform an operation that
causes GitPython to attempt to run the hook:

```powershell
mkdir testrepo
cd testrepo
git init
mv .git/hooks/pre-commit.sample .git/hooks/pre-commit
cp ... bash.exe # Replace "..." with any executable of choice.
echo "Some text" >file.txt
git add file.txt
python -c "import git; git.Repo().index.commit('Some message')"
```

The `bash.exe` executable in the current directory will be run.

### Impact

The greatest impact is probably in applications that set `Git.USE_SHELL
= True` for historical reasons. (Undesired console windows had, in the
past, been created in some kinds of applications, when it was not used.)
Such an application may be vulnerable to arbitrary code execution from a
malicious repository, even with no other exacerbating conditions. This
is to say that, if a shell is used to run `git`, the full effect of
CVE-2023-40590 is still present. Furthermore, as noted above, running
the application itself from a trusted directory is not a sufficient
mitigation.

An application that does not direct GitPython to use a shell to run
`git` subprocesses thus avoids most of the risk. However, there is no
such straightforward way to prevent GitPython from running `bash.exe` to
interpret hooks. So while the conditions needed for that to be exploited
are more involved, it may be harder to mitigate decisively prior to
patching.

### Possible solutions

A straightforward approach would be to address each bug directly:

- When a shell is used, pass `NoDefaultCurrentDirectoryInExePath` into
the subprocess environment, because in that scenario the subprocess is
the `cmd.exe` shell that itself performs the path search.
- Set `NoDefaultCurrentDirectoryInExePath` in the GitPython process
environment during the `Popen` call made to run hooks with a `bash.exe`
subprocess.

These need only be done on Windows.

---

### Release Notes

<details>
<summary>gitpython-developers/GitPython (GitPython)</summary>

###
[`v3.1.41`](https://togithub.com/gitpython-developers/GitPython/releases/tag/3.1.41):
- fix Windows security issue

[Compare
Source](https://togithub.com/gitpython-developers/GitPython/compare/3.1.40...3.1.41)

The details about the Windows security issue [can be found in this
advisory](https://togithub.com/gitpython-developers/GitPython/security/advisories/GHSA-2mqj-m65w-jghx).

Special thanks go to
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) who reported the
issue and fixed it in a single stroke, while being responsible for an
incredible amount of improvements that he contributed over the last
couple of months ❤️.

#### What's Changed

- Add `__all__` in git.exc by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1719](https://togithub.com/gitpython-developers/GitPython/pull/1719)
- Set submodule update cadence to weekly by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1721](https://togithub.com/gitpython-developers/GitPython/pull/1721)
- Never modify sys.path by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1720](https://togithub.com/gitpython-developers/GitPython/pull/1720)
- Bump git/ext/gitdb from `8ec2390` to `ec58b7e` by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/gitpython-developers/GitPython/pull/1722](https://togithub.com/gitpython-developers/GitPython/pull/1722)
- Revise comments, docstrings, some messages, and a bit of code by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1725](https://togithub.com/gitpython-developers/GitPython/pull/1725)
- Use zero-argument super() by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1726](https://togithub.com/gitpython-developers/GitPython/pull/1726)
- Remove obsolete note in \_iter_packed_refs by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1727](https://togithub.com/gitpython-developers/GitPython/pull/1727)
- Reorganize test_util and make xfail marks precise by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1729](https://togithub.com/gitpython-developers/GitPython/pull/1729)
- Clarify license and make module top comments more consistent by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1730](https://togithub.com/gitpython-developers/GitPython/pull/1730)
- Deprecate compat.is\_<platform>, rewriting all uses by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1732](https://togithub.com/gitpython-developers/GitPython/pull/1732)
- Revise and restore some module docstrings by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1735](https://togithub.com/gitpython-developers/GitPython/pull/1735)
- Make the rmtree callback Windows-only by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1739](https://togithub.com/gitpython-developers/GitPython/pull/1739)
- List all non-passing tests in test summaries by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1740](https://togithub.com/gitpython-developers/GitPython/pull/1740)
- Document some minor subtleties in test_util.py by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1749](https://togithub.com/gitpython-developers/GitPython/pull/1749)
- Always read metadata files as UTF-8 in setup.py by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1748](https://togithub.com/gitpython-developers/GitPython/pull/1748)
- Test native Windows on CI by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1745](https://togithub.com/gitpython-developers/GitPython/pull/1745)
- Test macOS on CI by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1752](https://togithub.com/gitpython-developers/GitPython/pull/1752)
- Let close_fds be True on all platforms by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1753](https://togithub.com/gitpython-developers/GitPython/pull/1753)
- Fix IndexFile.from_tree on Windows by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1751](https://togithub.com/gitpython-developers/GitPython/pull/1751)
- Remove unused TASKKILL fallback in AutoInterrupt by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1754](https://togithub.com/gitpython-developers/GitPython/pull/1754)
- Don't return with operand when conceptually void by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1755](https://togithub.com/gitpython-developers/GitPython/pull/1755)
- Group .gitignore entries by purpose by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1758](https://togithub.com/gitpython-developers/GitPython/pull/1758)
- Adding dubious ownership handling by
[@&#8203;marioaag](https://togithub.com/marioaag) in
[https://github.com/gitpython-developers/GitPython/pull/1746](https://togithub.com/gitpython-developers/GitPython/pull/1746)
- Avoid brittle assumptions about preexisting temporary files in tests
by [@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1759](https://togithub.com/gitpython-developers/GitPython/pull/1759)
- Overhaul noqa directives by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1760](https://togithub.com/gitpython-developers/GitPython/pull/1760)
- Clarify some Git.execute kill_after_timeout limitations by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1761](https://togithub.com/gitpython-developers/GitPython/pull/1761)
- Bump actions/setup-python from 4 to 5 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/gitpython-developers/GitPython/pull/1763](https://togithub.com/gitpython-developers/GitPython/pull/1763)
- Don't install black on Cygwin by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1766](https://togithub.com/gitpython-developers/GitPython/pull/1766)
- Extract all "import gc" to module level by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1765](https://togithub.com/gitpython-developers/GitPython/pull/1765)
- Extract remaining local "import gc" to module level by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1768](https://togithub.com/gitpython-developers/GitPython/pull/1768)
- Replace xfail with gc.collect in TestSubmodule.test_rename by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1767](https://togithub.com/gitpython-developers/GitPython/pull/1767)
- Enable CodeQL by [@&#8203;EliahKagan](https://togithub.com/EliahKagan)
in
[https://github.com/gitpython-developers/GitPython/pull/1769](https://togithub.com/gitpython-developers/GitPython/pull/1769)
- Replace some uses of the deprecated mktemp function by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1770](https://togithub.com/gitpython-developers/GitPython/pull/1770)
- Bump github/codeql-action from 2 to 3 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/gitpython-developers/GitPython/pull/1773](https://togithub.com/gitpython-developers/GitPython/pull/1773)
- Run some Windows environment variable tests only on Windows by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1774](https://togithub.com/gitpython-developers/GitPython/pull/1774)
- Fix TemporaryFileSwap regression where file_path could not be Path by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1776](https://togithub.com/gitpython-developers/GitPython/pull/1776)
- Improve hooks tests by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1777](https://togithub.com/gitpython-developers/GitPython/pull/1777)
- Fix if items of Index is of type PathLike by
[@&#8203;stegm](https://togithub.com/stegm) in
[https://github.com/gitpython-developers/GitPython/pull/1778](https://togithub.com/gitpython-developers/GitPython/pull/1778)
- Better document IterableObj.iter_items and improve some subclasses by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1780](https://togithub.com/gitpython-developers/GitPython/pull/1780)
- Revert "Don't install black on Cygwin" by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1783](https://togithub.com/gitpython-developers/GitPython/pull/1783)
- Add missing pip in $PATH on Cygwin CI by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1784](https://togithub.com/gitpython-developers/GitPython/pull/1784)
- Shorten Iterable docstrings and put IterableObj first by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1785](https://togithub.com/gitpython-developers/GitPython/pull/1785)
- Fix incompletely revised Iterable/IterableObj docstrings by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1786](https://togithub.com/gitpython-developers/GitPython/pull/1786)
- Pre-deprecate setting Git.USE_SHELL by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1782](https://togithub.com/gitpython-developers/GitPython/pull/1782)
- Deprecate Git.USE_SHELL by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1787](https://togithub.com/gitpython-developers/GitPython/pull/1787)
- In handle_process_output don't forward finalizer result by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1788](https://togithub.com/gitpython-developers/GitPython/pull/1788)
- Fix mypy warning "Missing return statement" by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1789](https://togithub.com/gitpython-developers/GitPython/pull/1789)
- Fix two remaining Windows untrusted search path cases by
[@&#8203;EliahKagan](https://togithub.com/EliahKagan) in
[https://github.com/gitpython-developers/GitPython/pull/1792](https://togithub.com/gitpython-developers/GitPython/pull/1792)

#### New Contributors

- [@&#8203;marioaag](https://togithub.com/marioaag) made their first
contribution in
[https://github.com/gitpython-developers/GitPython/pull/1746](https://togithub.com/gitpython-developers/GitPython/pull/1746)
- [@&#8203;stegm](https://togithub.com/stegm) made their first
contribution in
[https://github.com/gitpython-developers/GitPython/pull/1778](https://togithub.com/gitpython-developers/GitPython/pull/1778)

**Full Changelog**:
gitpython-developers/GitPython@3.1.40...3.1.41

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "" (UTC), Automerge - At any time (no
schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/googleapis/sdk-platform-java).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4yNjkuMiIsInVwZGF0ZWRJblZlciI6IjM3LjI2OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9-->