This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new b32603f5066 Fix Git corruption recovery by moving fetch into retry
context (#56913)
b32603f5066 is described below
commit b32603f50668391c2bba55579336023fab6dbf0f
Author: Dheeraj Turaga <[email protected]>
AuthorDate: Mon Oct 27 19:56:14 2025 -0500
Fix Git corruption recovery by moving fetch into retry context (#56913)
* Fix Git corruption recovery by moving fetch into retry context
Move _fetch_bare_repo call from _ensure_version_in_bare_repo into
_clone_bare_repo_if_required so that fetch failures (e.g., corrupted packs
with unresolved deltas) trigger the existing @retry mechanism to clean up
and re-clone the bare repository automatically.
* Fix tests
---
providers/git/src/airflow/providers/git/bundles/git.py | 5 ++++-
providers/git/tests/unit/git/bundles/test_git.py | 7 +++++--
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/providers/git/src/airflow/providers/git/bundles/git.py
b/providers/git/src/airflow/providers/git/bundles/git.py
index 89c7f7af084..2bf1f9980ae 100644
--- a/providers/git/src/airflow/providers/git/bundles/git.py
+++ b/providers/git/src/airflow/providers/git/bundles/git.py
@@ -175,9 +175,12 @@ class GitDagBundle(BaseDagBundle):
env=self.hook.env if self.hook else None,
)
self.bare_repo = Repo(self.bare_repo_path)
+
+ # Fetch to ensure we have latest refs and validate repo integrity
+ self._fetch_bare_repo()
except (InvalidGitRepositoryError, GitCommandError) as e:
self._log.warning(
- "Bare repository clone/open failed, cleaning up and retrying",
+ "Bare repository clone/open/fetch failed, cleaning up and
retrying",
bare_repo_path=self.bare_repo_path,
exc=e,
)
diff --git a/providers/git/tests/unit/git/bundles/test_git.py
b/providers/git/tests/unit/git/bundles/test_git.py
index cf85e71758b..b6c110e3547 100644
--- a/providers/git/tests/unit/git/bundles/test_git.py
+++ b/providers/git/tests/unit/git/bundles/test_git.py
@@ -377,7 +377,8 @@ class TestGitDagBundle:
tracking_ref=GIT_DEFAULT_BRANCH,
)
bundle.initialize()
- assert mock_gitRepo.return_value.remotes.origin.fetch.call_count == 2
# 1 in bare, 1 in main repo
+ # 1 in _clone_bare_repo_if_required, 1 in refresh() for bare repo, 1
in refresh() for working repo
+ assert mock_gitRepo.return_value.remotes.origin.fetch.call_count == 3
mock_gitRepo.return_value.remotes.origin.fetch.reset_mock()
bundle.refresh()
assert mock_gitRepo.return_value.remotes.origin.fetch.call_count == 2
@@ -730,7 +731,9 @@ class TestGitDagBundle:
EXPECTED_ENV = {"GIT_SSH_COMMAND": "ssh -i /id_rsa -o
StrictHostKeyChecking=no"}
mock_gitRepo.clone_from.side_effect = _fake_clone_from
- mock_gitRepo.return_value = types.SimpleNamespace()
+ # Mock needs to support the fetch operation called in
_clone_bare_repo_if_required
+ mock_repo_instance = mock.MagicMock()
+ mock_gitRepo.return_value = mock_repo_instance
with mock.patch("airflow.providers.git.bundles.git.GitHook") as
mock_githook:
mock_githook.return_value.repo_url =
"[email protected]:apache/airflow.git"