mirror of
https://gerrit.googlesource.com/git-repo
synced 2026-05-29 22:29:36 +00:00
project: Avoid skipping fetches for shallow clones without .git/shallow
When optimizing fetches for projects with immutable revisions, the fetch should not be skipped if the project is configured for a shallow clone (depth > 0) but the .git/shallow file is missing. The absence of the .git/shallow file means the repository is not a shallow clone, or the shallow clone is incomplete, so a fetch is necessary to ensure the revision is present. Bug: 503081454 Change-Id: Ic3549612bcd69050a926652ee4e522c79ad8124c Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/573821 Tested-by: Becky Siegel <beckysiegel@google.com> Reviewed-by: Gavin Mak <gavinmak@google.com> Commit-Queue: Becky Siegel <beckysiegel@google.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
import contextlib
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
from typing import Optional
|
||||
@@ -683,3 +684,113 @@ class StatelessSyncTests(unittest.TestCase):
|
||||
|
||||
self.assertTrue(res.success)
|
||||
self.assertFalse(getattr(proj, "stateless_prune_needed", False))
|
||||
|
||||
|
||||
class SyncOptimizationTests(unittest.TestCase):
|
||||
"""Tests for sync optimization logic involving shallow clones."""
|
||||
|
||||
def _get_project(self, tempdir, depth=None):
|
||||
manifest = mock.MagicMock()
|
||||
manifest.manifestProject.depth = depth
|
||||
manifest.manifestProject.dissociate = False
|
||||
manifest.manifestProject.clone_filter = None
|
||||
manifest.is_multimanifest = False
|
||||
manifest.manifestProject.config.GetBoolean.return_value = False
|
||||
manifest.IsMirror = False
|
||||
|
||||
remote = mock.MagicMock()
|
||||
remote.name = "origin"
|
||||
remote.url = "http://"
|
||||
|
||||
proj = project.Project(
|
||||
manifest=manifest,
|
||||
name="test-project",
|
||||
remote=remote,
|
||||
gitdir=os.path.join(tempdir, "gitdir"),
|
||||
objdir=os.path.join(tempdir, "objdir"),
|
||||
worktree=tempdir,
|
||||
relpath="test-project",
|
||||
revisionExpr="0123456789abcdef0123456789abcdef01234567",
|
||||
revisionId=None,
|
||||
)
|
||||
proj._CheckForImmutableRevision = mock.MagicMock(return_value=True)
|
||||
proj.DeleteWorktree = mock.MagicMock()
|
||||
proj._InitGitDir = mock.MagicMock()
|
||||
proj._InitRemote = mock.MagicMock()
|
||||
proj._InitMRef = mock.MagicMock()
|
||||
return proj
|
||||
|
||||
def test_sync_network_half_shallow_missing_fetches(self):
|
||||
"""Test Sync_NetworkHalf fetches if shallow file is missing."""
|
||||
with utils_for_test.TempGitTree() as tempdir:
|
||||
proj = self._get_project(tempdir, depth=1)
|
||||
# Ensure gitdir does not exist to simulate new project
|
||||
if os.path.exists(proj.gitdir):
|
||||
shutil.rmtree(proj.gitdir)
|
||||
shallow_path = os.path.join(proj.gitdir, "shallow")
|
||||
if os.path.exists(shallow_path):
|
||||
os.unlink(shallow_path)
|
||||
|
||||
proj._RemoteFetch = mock.MagicMock(return_value=True)
|
||||
|
||||
res = proj.Sync_NetworkHalf(optimized_fetch=True)
|
||||
|
||||
self.assertTrue(res.success)
|
||||
proj._RemoteFetch.assert_called_once()
|
||||
|
||||
def test_sync_network_half_shallow_exists_skips(self):
|
||||
"""Test Sync_NetworkHalf skips fetch if shallow file exists."""
|
||||
with utils_for_test.TempGitTree() as tempdir:
|
||||
proj = self._get_project(tempdir, depth=1)
|
||||
os.makedirs(proj.gitdir, exist_ok=True)
|
||||
os.makedirs(proj.objdir, exist_ok=True)
|
||||
with open(os.path.join(proj.gitdir, "shallow"), "w") as f:
|
||||
f.write("")
|
||||
|
||||
proj._RemoteFetch = mock.MagicMock()
|
||||
|
||||
res = proj.Sync_NetworkHalf(optimized_fetch=True)
|
||||
|
||||
self.assertTrue(res.success)
|
||||
proj._RemoteFetch.assert_not_called()
|
||||
|
||||
def test_remote_fetch_shallow_missing_fetches(self):
|
||||
"""Test _RemoteFetch fetches if shallow file is missing."""
|
||||
with utils_for_test.TempGitTree() as tempdir:
|
||||
proj = self._get_project(tempdir, depth=1)
|
||||
shallow_path = os.path.join(proj.gitdir, "shallow")
|
||||
if os.path.exists(shallow_path):
|
||||
os.unlink(shallow_path)
|
||||
|
||||
with mock.patch("project.GitCommand") as mock_git_cmd:
|
||||
mock_cmd_instance = mock.MagicMock()
|
||||
mock_cmd_instance.Wait.return_value = 0
|
||||
mock_git_cmd.return_value = mock_cmd_instance
|
||||
|
||||
res = proj._RemoteFetch(
|
||||
current_branch_only=True,
|
||||
depth=1,
|
||||
use_superproject=False,
|
||||
)
|
||||
|
||||
self.assertTrue(res)
|
||||
mock_git_cmd.assert_called()
|
||||
|
||||
def test_remote_fetch_shallow_exists_skips(self):
|
||||
"""Test _RemoteFetch skips fetch if shallow file exists."""
|
||||
with utils_for_test.TempGitTree() as tempdir:
|
||||
proj = self._get_project(tempdir, depth=1)
|
||||
os.makedirs(proj.gitdir, exist_ok=True)
|
||||
os.makedirs(proj.objdir, exist_ok=True)
|
||||
with open(os.path.join(proj.gitdir, "shallow"), "w") as f:
|
||||
f.write("")
|
||||
|
||||
with mock.patch("project.GitCommand") as mock_git_cmd:
|
||||
res = proj._RemoteFetch(
|
||||
current_branch_only=True,
|
||||
depth=1,
|
||||
use_superproject=False,
|
||||
)
|
||||
|
||||
self.assertTrue(res)
|
||||
mock_git_cmd.assert_not_called()
|
||||
|
||||
Reference in New Issue
Block a user