Skip to content

Commit 0990424

Browse files
committed
dulwich: fix clone with file:// protocol on windows
- clone: add test for file://<path> and shallow_branch
1 parent 9d6574a commit 0990424

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

scmrepo/git/backend/dulwich/__init__.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,14 @@ def clone(
159159
from dulwich.porcelain import NoneStream
160160
from dulwich.porcelain import clone as git_clone
161161

162+
parsed = urlparse(url)
163+
if os.name == "nt":
164+
# NOTE: Dulwich client code doesn't handle mixed path seps when
165+
# passed a file:// URL (i.e. file://C:\foo\bar) but we can just
166+
# strip the prefix since Dulwich uses the same clone behavior
167+
# for both paths and file:// URLs (as opposed to C-git)
168+
if parsed.scheme == "file":
169+
url = url[7:]
162170
try:
163171
clone_from = partial(
164172
git_clone,
@@ -174,11 +182,10 @@ def clone(
174182
# NOTE: dulwich only supports shallow/depth for non-local
175183
# clones. This differs from CLI git, where depth is used for
176184
# file:// URLs but not direct local paths
177-
parsed = urlparse(url)
178-
if not parsed.scheme or parsed.scheme == "file":
179-
depth = 0
180-
else:
185+
if parsed.scheme in ("git", "git+ssh", "ssh", "http", "https"):
181186
depth = 1
187+
else:
188+
depth = 0
182189
repo = clone_from(
183190
depth=depth, branch=os.fsencode(shallow_branch)
184191
)

tests/test_git.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import os
22
import shutil
3-
from typing import Any, Dict, Iterator, Type
3+
from typing import Any, Dict, Iterator, Optional, Type
44

55
import pytest
66
from asyncssh import SFTPClient
@@ -885,15 +885,24 @@ async def test_git_ssh(
885885
assert (tmp_dir / "foo").read_text() == "foo"
886886

887887

888+
@pytest.mark.parametrize("scheme", ["", "file://"])
889+
@pytest.mark.parametrize("shallow_branch", [None, "master"])
888890
def test_clone(
889-
tmp_dir: TmpDir, scm: Git, git: Git, tmp_dir_factory: TempDirFactory
891+
tmp_dir: TmpDir,
892+
scm: Git,
893+
git: Git,
894+
tmp_dir_factory: TempDirFactory,
895+
scheme: str,
896+
shallow_branch: Optional[str],
890897
):
891898
tmp_dir.gen("foo", "foo")
892899
scm.add_commit("foo", message="init")
893900
rev = scm.get_rev()
894901

895902
target_dir = tmp_dir_factory.mktemp("git-clone")
896-
git.clone(str(tmp_dir), (target_dir))
903+
git.clone(
904+
f"{scheme}{tmp_dir}", str(target_dir), shallow_branch=shallow_branch
905+
)
897906
target = Git(str(target_dir))
898907
assert target.get_rev() == rev
899908
assert (target_dir / "foo").read_text() == "foo"

0 commit comments

Comments
 (0)