diff options
| -rw-r--r-- | git_config.py | 12 | ||||
| -rw-r--r-- | tests/test_git_config.py | 20 |
2 files changed, 32 insertions, 0 deletions
diff --git a/git_config.py b/git_config.py index 84d347b1a..4facccda6 100644 --- a/git_config.py +++ b/git_config.py | |||
| @@ -266,6 +266,13 @@ class GitConfig: | |||
| 266 | except KeyError: | 266 | except KeyError: |
| 267 | old = [] | 267 | old = [] |
| 268 | 268 | ||
| 269 | if self.file != self._SYSTEM_CONFIG: | ||
| 270 | # `git config --file` does not create missing parent directories | ||
| 271 | # (e.g. ~/.repoconfig/ on first use). | ||
| 272 | parent_dir = os.path.dirname(self.file) | ||
| 273 | if parent_dir: | ||
| 274 | os.makedirs(parent_dir, exist_ok=True) | ||
| 275 | |||
| 269 | if value is None: | 276 | if value is None: |
| 270 | if old: | 277 | if old: |
| 271 | del self._cache[key] | 278 | del self._cache[key] |
| @@ -444,6 +451,11 @@ class GitConfig: | |||
| 444 | class RepoConfig(GitConfig): | 451 | class RepoConfig(GitConfig): |
| 445 | """User settings for repo itself.""" | 452 | """User settings for repo itself.""" |
| 446 | 453 | ||
| 454 | # Keep separate caches from GitConfig, otherwise ForUser()/ForSystem() | ||
| 455 | # would return the already-cached ~/.gitconfig instance of the parent. | ||
| 456 | _ForUser = None | ||
| 457 | _ForSystem = None | ||
| 458 | |||
| 447 | @staticmethod | 459 | @staticmethod |
| 448 | def _getUserConfig(): | 460 | def _getUserConfig(): |
| 449 | repo_config_dir = os.getenv("REPO_CONFIG_DIR", os.path.expanduser("~")) | 461 | repo_config_dir = os.getenv("REPO_CONFIG_DIR", os.path.expanduser("~")) |
diff --git a/tests/test_git_config.py b/tests/test_git_config.py index 4b4e4cabb..33b0466fa 100644 --- a/tests/test_git_config.py +++ b/tests/test_git_config.py | |||
| @@ -268,3 +268,23 @@ def test_remote_save_with_push_url_without_projectname( | |||
| 268 | def test_is_id(rev: str, expected: bool) -> None: | 268 | def test_is_id(rev: str, expected: bool) -> None: |
| 269 | """Test IsId identifies both SHA-1 and SHA-256 hashes.""" | 269 | """Test IsId identifies both SHA-1 and SHA-256 hashes.""" |
| 270 | assert git_config.IsId(rev) == expected | 270 | assert git_config.IsId(rev) == expected |
| 271 | |||
| 272 | |||
| 273 | def test_repo_config_for_user_is_not_shared_with_git_config( | ||
| 274 | monkeypatch: pytest.MonkeyPatch, tmp_home_dir: Path | ||
| 275 | ) -> None: | ||
| 276 | """RepoConfig.ForUser() must not reuse GitConfig.ForUser()'s cache.""" | ||
| 277 | monkeypatch.setattr(git_config.GitConfig, "_ForUser", None) | ||
| 278 | monkeypatch.setattr(git_config.RepoConfig, "_ForUser", None) | ||
| 279 | monkeypatch.delenv("REPO_CONFIG_DIR", raising=False) | ||
| 280 | |||
| 281 | # Populate the GitConfig cache first, as manifest loading does. | ||
| 282 | git_cfg = git_config.GitConfig.ForUser() | ||
| 283 | repo_cfg = git_config.RepoConfig.ForUser() | ||
| 284 | |||
| 285 | assert repo_cfg is not git_cfg | ||
| 286 | assert git_cfg.file == str(tmp_home_dir / ".gitconfig") | ||
| 287 | assert repo_cfg.file == str(tmp_home_dir / ".repoconfig" / "config") | ||
| 288 | # And the RepoConfig instance is cached on its own class. | ||
| 289 | assert git_config.RepoConfig.ForUser() is repo_cfg | ||
| 290 | assert git_config.GitConfig.ForUser() is git_cfg | ||
