Skip to content

Commit 69764cb

Browse files
Refactor git authentication handling with improved environment management
Co-authored-by: nicoragne <nicoragne@hotmail.fr>
1 parent 6ff8b89 commit 69764cb

File tree

4 files changed

+45
-97
lines changed

4 files changed

+45
-97
lines changed

src/gitingest/clone.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,14 @@ def perform_checkout():
129129
# Fetch the specific commit
130130
logger.debug("Fetching specific commit", extra={"commit": commit})
131131

132-
# Set up authentication for fetch operations
132+
# Set up authentication environment for fetch operations
133+
env = None
133134
if token and is_github_host(url):
134-
git_cmd = repo.git.with_custom_environment(GIT_CONFIG_PARAMETERS=create_git_auth_header(token, url=url))
135-
else:
136-
git_cmd = repo.git
135+
import os
136+
env = os.environ.copy()
137+
env["GIT_CONFIG_PARAMETERS"] = create_git_auth_header(token, url=url)
137138

138-
git_cmd.fetch("--depth=1", "origin", commit)
139+
repo.git.fetch("--depth=1", "origin", commit, env=env)
139140

140141
# Checkout the specific commit
141142
logger.info("Checking out commit", extra={"commit": commit})

src/gitingest/utils/git_utils.py

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,7 @@ async def fetch_remote_branches_or_tags(url: str, *, ref_type: str, token: str |
243243
await ensure_git_installed()
244244

245245
def fetch_refs():
246-
git_cmd = Git()
247-
248-
# Set up authentication if needed
249-
if token and is_github_host(url):
250-
git_cmd = git_cmd.with_custom_environment(GIT_CONFIG_PARAMETERS=create_git_auth_header(token, url=url))
246+
git_cmd = create_git_command_with_auth(token, url)
251247

252248
fetch_tags = ref_type == "tags"
253249
to_fetch = "tags" if fetch_tags else "heads"
@@ -278,7 +274,29 @@ def fetch_refs():
278274
]
279275

280276

281-
def create_git_command_with_auth(token: str | None, url: str) -> Git:
277+
class GitCommandWithAuth:
278+
"""A wrapper around Git command that stores authentication environment."""
279+
280+
def __init__(self, token: str | None, url: str):
281+
self.git = Git()
282+
self.env = None
283+
284+
if token and is_github_host(url):
285+
import os
286+
self.env = os.environ.copy()
287+
self.env["GIT_CONFIG_PARAMETERS"] = create_git_auth_header(token, url=url)
288+
289+
def execute(self, args: list[str]) -> str:
290+
"""Execute a git command with authentication if needed."""
291+
return self.git.execute(args, env=self.env)
292+
293+
@property
294+
def custom_environment(self) -> dict[str, str] | None:
295+
"""Get the custom environment for testing."""
296+
return self.env
297+
298+
299+
def create_git_command_with_auth(token: str | None, url: str) -> GitCommandWithAuth:
282300
"""Create a Git command object with authentication if needed.
283301
284302
Parameters
@@ -290,15 +308,11 @@ def create_git_command_with_auth(token: str | None, url: str) -> Git:
290308
291309
Returns
292310
-------
293-
Git
294-
A Git command object with authentication configured if needed.
311+
GitCommandWithAuth
312+
A Git command wrapper with authentication configured if needed.
295313
296314
"""
297-
if token and is_github_host(url):
298-
# Set authentication through environment
299-
auth_config = create_git_auth_header(token, url=url)
300-
return Git().with_custom_environment(GIT_CONFIG_PARAMETERS=auth_config)
301-
return Git()
315+
return GitCommandWithAuth(token, url)
302316

303317

304318
def create_git_auth_header(token: str, url: str = "https://github.com") -> str:
@@ -369,13 +383,15 @@ async def checkout_partial_clone(config: CloneConfig, token: str | None) -> None
369383
def setup_sparse_checkout():
370384
try:
371385
repo = Repo(config.local_path)
372-
git_cmd = repo.git
373386

374-
# Set up authentication if needed
387+
# Set up authentication environment if needed
388+
env = None
375389
if token and is_github_host(config.url):
376-
git_cmd = git_cmd.with_custom_environment(GIT_CONFIG_PARAMETERS=create_git_auth_header(token, url=config.url))
390+
import os
391+
env = os.environ.copy()
392+
env["GIT_CONFIG_PARAMETERS"] = create_git_auth_header(token, url=config.url)
377393

378-
git_cmd.execute(["sparse-checkout", "set", subpath])
394+
repo.git.execute(["sparse-checkout", "set", subpath], env=env)
379395
except Exception as e:
380396
raise RuntimeError(f"Failed to setup sparse checkout: {str(e)}") from e
381397

test_gitpython_integration.py

Lines changed: 0 additions & 69 deletions
This file was deleted.

tests/test_git_utils.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ def test_create_git_command_with_auth(
7373

7474
# Check if the git command has authentication environment configured
7575
if should_have_auth:
76-
assert hasattr(git_cmd, 'custom_environment')
76+
assert git_cmd.custom_environment is not None
7777
assert 'GIT_CONFIG_PARAMETERS' in git_cmd.custom_environment
7878
else:
79-
# For no auth case, should be basic Git command
80-
assert not hasattr(git_cmd, 'custom_environment') or 'GIT_CONFIG_PARAMETERS' not in (git_cmd.custom_environment or {})
79+
# For no auth case, should not have custom environment
80+
assert git_cmd.custom_environment is None
8181

8282

8383
@pytest.mark.parametrize(
@@ -118,7 +118,7 @@ def test_create_git_command_with_auth_calls(
118118

119119
if should_have_auth:
120120
header_mock.assert_called_once_with(token, url=url)
121-
assert hasattr(git_cmd, 'custom_environment')
121+
assert git_cmd.custom_environment is not None
122122
assert git_cmd.custom_environment['GIT_CONFIG_PARAMETERS'] == "HEADER"
123123
else:
124124
header_mock.assert_not_called()
@@ -194,7 +194,7 @@ def test_create_git_command_with_auth_ghe_urls(
194194
git_cmd = create_git_command_with_auth(token, url)
195195

196196
# Should have authentication configured
197-
assert hasattr(git_cmd, 'custom_environment')
197+
assert git_cmd.custom_environment is not None
198198
assert 'GIT_CONFIG_PARAMETERS' in git_cmd.custom_environment
199199
auth_header = git_cmd.custom_environment['GIT_CONFIG_PARAMETERS']
200200

@@ -220,4 +220,4 @@ def test_create_git_command_with_auth_ignores_non_github_urls(
220220
git_cmd = create_git_command_with_auth(token, url)
221221

222222
# Should not have authentication configured for non-GitHub URLs
223-
assert not hasattr(git_cmd, 'custom_environment') or 'GIT_CONFIG_PARAMETERS' not in (git_cmd.custom_environment or {})
223+
assert git_cmd.custom_environment is None

0 commit comments

Comments
 (0)