Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't read "installation" config from GIT_CONFIG #1583

Merged
merged 4 commits into from
Sep 6, 2024

Conversation

EliahKagan
Copy link
Member

This makes it so GIT_HIGHEST_SCOPE_CONFIG_PATH never uses the value of the GIT_CONFIG environment variable. Previously it used it because git config uses it, treating it as though its value were an operand to --file. But no other git commands use it.

It was previously used in most situations when present, since it causes git config -l to list nothing else of any scope (even if very high scoped configuration is available). The main and possibly only significant situation where it was not used was the EXEPATH optimization on Windows (which in practice only occurs in Git Bash environments). I think this inconsistency--since it never has anything to do with whether a user would want GIT_CONFIG to have an effect--is one of the most significant reasons to omit it.

However, when reviewing this, I recommend considering if possible uses where a user would set GIT_CONFIG to view configuration from an arbitrary file with commands like gix config--even though it would not work from Git Bash--might be something people are doing. I have prefixed the commit message fix: but maybe I should have written fix!: for this reason? I am not sure. But as far as I know, this is not altering any behavior to become inconsistent with what was previously documented or otherwise stated.

There is more information in the commit messages, especially the one prefixed fix:, eb72d31. This also adds tests related to GIT_CONFIG, in the two commits that precede that, 340ff37 and f8e38d0.

I have also unset some other environment variables (that would only occasionally be set in the first place) besides GIT_CONFIG. This is in the first commit, 01a412f, and it is for a different reason: it is to ensure that even if some version of git behaves weirdly, or if my understanding of its intended behavior is incorrect, then we still get the full effect of setting GIT_DIR. The commit message has more information about that. I mostly included that here rather than in a separate PR to avoid a merge conflict (or decreased code readability if the remove_env calls were to be merged in an unintuitive order).

This has the `git config -l ...` invocation `gix-path` uses to find
a configuration file to treat as associated with the `git`
installation remove more environment variables related to `GIT_DIR`
besides `GIT_COMMON_DIR`.

The new removals probably don't make a difference, because they are
only used if `GIT_DIR` is either unset or set to a location that
actually has a Git repository (that `git` is willing to use).

Unsetting these others is thus more to make clear that they have no
effect than to prevent them from having an effect, though various
versions and downstream releases of `git` exist, so it's narrowly
possible that this is also avoiding a problem somewhere, I guess.

This change is motivated by my realization in 9d4dd12 (GitoxideLabs#1581) that
it could be slightly beneficial. Other differences between the
variables unset here and in `gix-testtools` remain due to the
differences described in that commit message.
These tests should not pass yet, because we currently do allow
`GIT_CONFIG` to be read. Although the optimization that reads
`EXEPATH` will sometimes prevent it from being used, it will
usually be used, becuase `EXEPATH` is usually not set on Windows
(and outside of Windows, that optimization is inapplicable).
Furthermore, the tests in `gix-path/src/env/git/tests.rs` bypass
that optimization.

Two of the three new tests rightly fail. But one of them,
`never_from_git_config_env_var`, wrongly passes, due to a big in
the test, described in the comments there.
So it fails too, as expected.
When `gix-path` runs `git config -l ...` to obtain the path of a
configuration file to regard as being associated with the `git`
installation itself, it now no longer allows `GIT_CONFIG` to affect
this path.

Previously, setting `GIT_CONFIG` would treat it as the path of a
`GitInstallation` configuration file. Although it is possible that
this may have been used intentionally, it was never documented, did
not work reliably on all platforms, and carried significant
disadvantages. This is most likely a non-breaking change.

The disadvantages of treating a path in `GIT_CONFIG` as the path
to a configuration file associated with the `git` installation
were:

- For `git`, the `GIT_CONFIG` environment variable *only* affects
  `git config` commands, and not other commands that use
  configuration variables (which are most `git` commands). But when
  `gix-path` would obtain a path from `git config -l ...` that came
  from `GIT_CONFIG`, that configuration file would be used
  anywhere, and not only `gix config` commands.

- Even for `gix config`, it is not at all clear that the
  `GIT_CONFIG` environment variable ought to be honored, because
  `gix config` has a different interface from and is not meant to
  be a drop-in replacement for `git config`, and because this
  environment variable is only even supported by `git config` for
  historical reasons. (In `git config`, one should typically use
  `--file` instead.)

- The installation path is generally the path of a high-scoped
  configuration file, usually the system scope or, with Apple Git
  on macOS, the "unknown" scope even higher than that (of a file
  located under `/Library` or `/Applications`). In contrast, the
  `GIT_CONFIG` environment variable is really command scope, since
  it is an alternative way of achieving the same goal as `--file`
  when running `git config`, which `git` supports only for backward
  compatibility.

- On Windows, when `EXEPATH` is set in a way that indentifies a
  Git for Windows installation directory, which is typically the
  case in a Git Bash environment (and not otherwise), `GIT_CONFIG`
  is not used by the public `gix-path` functions that ordinarily
  get information from calling `git config -l ...`, because this
  call is not performed and instead the location of a configuration
  file associated with the installation is inferred from that
  value.

  Although this also applies to some other ways the environment
  affects the behavior of `git config -l ...`, it is much stranger
  for `GIT_CONFIG`, because whether `GIT_CONFIG` should be used
  does not intuitively seem like it should be related to what other
  sources of information are available; the semantics of
  `GIT_CONFIG` for `git` are to be ignored by most commands, but to
  always be used commands (`git config`) that do not ignore it.

- The effect on finding other files associated with the
  installation, such as a gitattributes file, may be especially
  hard to reason about for `GIT_CONFIG`. Such paths are sometimes
  inferred from the path that `gix-path` reports. In particular,
  this is how `installation_config_prefix()` works.

This change only prevents `GIT_CONFIG` from specifying an
installation config file or suppressing the search for it. This
does not affect how other `GIT_CONFIG_*` environment variables are
used.
Copy link
Member

@Byron Byron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much, I really appreciate your work (and sometimes feel I don't make that explicit often enough 😅).

There is more information in the commit messages, especially the one prefixed fix:, eb72d31. This also adds tests related to GIT_CONFIG, in the two commits that precede that, 340ff37 and f8e38d0.

I would only indicate breaking changes if the API breaks - changes in behaviour could qualify, of course, but thus far I didn't encounter them.

@Byron Byron merged commit 130db3b into GitoxideLabs:main Sep 6, 2024
15 checks passed
@EliahKagan EliahKagan deleted the config-origin-env branch September 6, 2024 10:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants