Skip to content

Commit 318769f

Browse files
committed
Add test for Git LFS repository cloning
Verifies that Poetry can successfully clone Git repositories that use Git Large File Storage (LFS) and that LFS files are properly retrieved with their actual content rather than just pointer files. This test uses dulwich's built-in LFS support to create a repository with LFS files and verifies that cloning works correctly without requiring manual configuration. Fixes #8723
1 parent ad9ab00 commit 318769f

1 file changed

Lines changed: 76 additions & 0 deletions

File tree

tests/vcs/git/test_backend.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,3 +424,79 @@ def test_clone_nested_annotated_tags(tmp_path: Path) -> None:
424424
assert (clone_dir / ".git").is_dir()
425425
assert (clone_dir / "test.txt").exists()
426426
assert (clone_dir / "test.txt").read_text(encoding="utf-8") == "nested tag test"
427+
428+
429+
@pytest.mark.skip_git_mock
430+
def test_clone_with_lfs_files(tmp_path: Path) -> None:
431+
"""Test cloning a repository with Git LFS files (issue #8723)."""
432+
from dulwich import porcelain
433+
from dulwich.lfs import LFSStore
434+
435+
# Create a source repository with LFS support
436+
source_path = tmp_path / "source-repo"
437+
source_path.mkdir()
438+
repo = Repo.init(str(source_path))
439+
440+
# Set up LFS in the repository
441+
lfs_dir = source_path / ".git" / "lfs"
442+
lfs_dir.mkdir(parents=True)
443+
lfs_store = LFSStore.create(str(lfs_dir))
444+
445+
# Configure .gitattributes to track large files with LFS
446+
gitattributes = source_path / ".gitattributes"
447+
gitattributes.write_text("*.bin filter=lfs diff=lfs merge=lfs -text\n")
448+
porcelain.add(repo, str(gitattributes))
449+
450+
# Create a regular file
451+
regular_file = source_path / "regular.txt"
452+
regular_file.write_text("This is a regular file")
453+
porcelain.add(repo, str(regular_file))
454+
455+
# Create an LFS file with a pointer
456+
lfs_content = b"This is a large binary file content for LFS storage"
457+
lfs_file = source_path / "large.bin"
458+
459+
# Store the actual content in LFS store and create pointer
460+
lfs_object_id = lfs_store.write_object([lfs_content])
461+
lfs_pointer = (
462+
f"version https://git-lfs.github.com/spec/v1\n"
463+
f"oid sha256:{lfs_object_id}\n"
464+
f"size {len(lfs_content)}\n"
465+
)
466+
lfs_file.write_text(lfs_pointer)
467+
porcelain.add(repo, str(lfs_file))
468+
469+
# Commit the files
470+
porcelain.commit(
471+
repo,
472+
message=b"Add files with LFS support",
473+
author=b"Test <test@example.com>",
474+
committer=b"Test <test@example.com>",
475+
)
476+
477+
# Clone the repository
478+
source_root_dir = tmp_path / "clone-root"
479+
source_root_dir.mkdir()
480+
Git.clone(
481+
url=source_path.as_uri(),
482+
source_root=source_root_dir,
483+
name="clone-test",
484+
)
485+
486+
# Verify the clone succeeded
487+
clone_dir = source_root_dir / "clone-test"
488+
assert (clone_dir / ".git").is_dir()
489+
490+
# Verify regular file is present
491+
assert (clone_dir / "regular.txt").exists()
492+
assert (clone_dir / "regular.txt").read_text() == "This is a regular file"
493+
494+
# Verify .gitattributes is present
495+
assert (clone_dir / ".gitattributes").exists()
496+
assert "filter=lfs" in (clone_dir / ".gitattributes").read_text()
497+
498+
# Verify LFS file is present with actual content (not just pointer)
499+
# The LFS system should automatically retrieve the actual content
500+
assert (clone_dir / "large.bin").exists()
501+
lfs_file_content = (clone_dir / "large.bin").read_bytes()
502+
assert lfs_file_content == lfs_content

0 commit comments

Comments
 (0)