From 40855aefa1cc364c4d12266591ac473937e648e8 Mon Sep 17 00:00:00 2001 From: dualc Date: Tue, 30 Sep 2025 16:49:30 +0800 Subject: [PATCH 1/2] fix checkout remote branch when branch name contains slash --- jupyterlab_git/git.py | 2 +- jupyterlab_git/tests/test_branch.py | 41 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/jupyterlab_git/git.py b/jupyterlab_git/git.py index a4ae5e9e8..ae6dc2651 100644 --- a/jupyterlab_git/git.py +++ b/jupyterlab_git/git.py @@ -1137,7 +1137,7 @@ async def checkout_branch(self, branchname, path): is_remote_branch = self._is_remote_branch(reference_name) if is_remote_branch: - local_branchname = branchname.split("/")[-1] + local_branchname = "/".join(branchname.split("/")[1:]) cmd = ["git", "checkout", "-B", local_branchname, branchname] else: cmd = ["git", "checkout", branchname] diff --git a/jupyterlab_git/tests/test_branch.py b/jupyterlab_git/tests/test_branch.py index c78d62e66..14acc1783 100644 --- a/jupyterlab_git/tests/test_branch.py +++ b/jupyterlab_git/tests/test_branch.py @@ -174,6 +174,47 @@ async def test_checkout_branch_remoteref_success(): assert {"code": rc, "message": stdout_message} == actual_response +@pytest.mark.asyncio +async def test_checkout_branch_remoteref_success_when_has_slash(): + branch = "origin/test-branch/test" + local_branch = "test-branch/test" + curr_path = str(Path("/bin/test_curr_path")) + stdout_message = "checkout output from git" + stderr_message = "" + rc = 0 + + with patch("jupyterlab_git.git.execute") as mock_execute: + with patch.object( + Git, + "_get_branch_reference", + return_value=maybe_future("refs/remotes/remote_branch"), + ) as mock__get_branch_reference: + # Given + mock_execute.return_value = maybe_future( + (rc, stdout_message, stderr_message) + ) + + # When + actual_response = await Git().checkout_branch( + branchname=branch, path=curr_path + ) + + # Then + mock__get_branch_reference.assert_has_calls([call(branch, curr_path)]) + + cmd = ["git", "checkout", "-B", local_branch, branch] + mock_execute.assert_called_once_with( + cmd, + cwd=str(Path("/bin") / "test_curr_path"), + timeout=20, + env=None, + username=None, + password=None, + is_binary=False, + ) + + assert {"code": rc, "message": stdout_message} == actual_response + @pytest.mark.asyncio async def test_checkout_branch_headsref_failure(): branch = "test-branch" From 81d90f1940d666cef2450adcffe2f5264461feb7 Mon Sep 17 00:00:00 2001 From: dualc Date: Tue, 30 Sep 2025 22:17:13 +0800 Subject: [PATCH 2/2] reformat code --- jupyterlab_git/tests/test_branch.py | 1 + 1 file changed, 1 insertion(+) diff --git a/jupyterlab_git/tests/test_branch.py b/jupyterlab_git/tests/test_branch.py index 14acc1783..fbb048602 100644 --- a/jupyterlab_git/tests/test_branch.py +++ b/jupyterlab_git/tests/test_branch.py @@ -215,6 +215,7 @@ async def test_checkout_branch_remoteref_success_when_has_slash(): assert {"code": rc, "message": stdout_message} == actual_response + @pytest.mark.asyncio async def test_checkout_branch_headsref_failure(): branch = "test-branch"