diff --git a/samcli/lib/utils/git_repo.py b/samcli/lib/utils/git_repo.py index 47f6ede128..de3f1c4840 100644 --- a/samcli/lib/utils/git_repo.py +++ b/samcli/lib/utils/git_repo.py @@ -129,8 +129,15 @@ def clone(self, clone_dir: Path, clone_name: str, replace_existing: bool = False temp_path = os.path.normpath(os.path.join(tempdir, clone_name)) git_executable: str = GitRepo._git_executable() LOG.info("\nCloning from %s (process may take a moment)", self.url) + command = [git_executable, "clone", self.url, clone_name] + if platform.system().lower() == "windows": + LOG.debug( + "Configure core.longpaths=true in git clone. " + "You might also need to enable long paths in Windows registry." + ) + command += ["--config", "core.longpaths=true"] check_output( - [git_executable, "clone", self.url, clone_name], + command, cwd=tempdir, stderr=subprocess.STDOUT, ) diff --git a/tests/unit/lib/utils/test_git_repo.py b/tests/unit/lib/utils/test_git_repo.py index c3ce27b6df..a7f789de25 100644 --- a/tests/unit/lib/utils/test_git_repo.py +++ b/tests/unit/lib/utils/test_git_repo.py @@ -53,6 +53,7 @@ def test_git_executable_fails(self, mock_popen): @patch("samcli.lib.utils.git_repo.subprocess.Popen") @patch("samcli.lib.utils.git_repo.platform.system") def test_clone_happy_case(self, platform_mock, popen_mock, check_output_mock, shutil_mock, path_exist_mock): + platform_mock.return_value = "Not Windows" path_exist_mock.return_value = False self.repo.clone(clone_dir=self.local_clone_dir, clone_name=REPO_NAME) self.local_clone_dir.mkdir.assert_called_once_with(mode=0o700, parents=True, exist_ok=True) @@ -207,6 +208,7 @@ def test_checkout_commit_when_commit_not_exist(self, check_output_mock, log_mock @patch("samcli.lib.utils.git_repo.subprocess.Popen") @patch("samcli.lib.utils.git_repo.platform.system") def test_clone_with_commit(self, platform_mock, popen_mock, check_output_mock, shutil_mock, path_exist_mock): + platform_mock.return_value = "Not Windows" path_exist_mock.return_value = False self.repo.clone(clone_dir=self.local_clone_dir, clone_name=REPO_NAME, commit=COMMIT) self.local_clone_dir.mkdir.assert_called_once_with(mode=0o700, parents=True, exist_ok=True) @@ -221,3 +223,29 @@ def test_clone_with_commit(self, platform_mock, popen_mock, check_output_mock, s shutil_mock.rmtree.assert_not_called() shutil_mock.copytree.assert_called_with(ANY, EXPECTED_DEFAULT_CLONE_PATH, ignore=ANY) shutil_mock.ignore_patterns.assert_called_with("*.git") + + @patch("samcli.lib.utils.git_repo.Path.exists") + @patch("samcli.lib.utils.git_repo.shutil") + @patch("samcli.lib.utils.git_repo.check_output") + @patch("samcli.lib.utils.git_repo.subprocess.Popen") + @patch("samcli.lib.utils.git_repo.platform.system") + def test_clone_with_longpaths_configured_in_windows( + self, platform_mock, popen_mock, check_output_mock, shutil_mock, path_exist_mock + ): + platform_mock.return_value = "windows" + path_exist_mock.return_value = False + self.repo.clone(clone_dir=self.local_clone_dir, clone_name=REPO_NAME) + self.local_clone_dir.mkdir.assert_called_once_with(mode=0o700, parents=True, exist_ok=True) + popen_mock.assert_called_once_with(["git"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + check_output_mock.assert_has_calls( + [ + call( + ["git", "clone", self.repo.url, REPO_NAME, "--config", "core.longpaths=true"], + cwd=ANY, + stderr=subprocess.STDOUT, + ) + ] + ) + shutil_mock.rmtree.assert_not_called() + shutil_mock.copytree.assert_called_with(ANY, EXPECTED_DEFAULT_CLONE_PATH, ignore=ANY) + shutil_mock.ignore_patterns.assert_called_with("*.git")