diff --git a/copier/_vcs.py b/copier/_vcs.py index 33c454455..24cb217ae 100644 --- a/copier/_vcs.py +++ b/copier/_vcs.py @@ -212,7 +212,9 @@ def clone(url: str, ref: str | None = None) -> str: ) with local.cwd(location): - git("checkout", "-f", ref or "HEAD") + ## The `git checkout -f ` command doesn't works when repo is local, dirty and core.fsmonitor is enabled + ## ref: https://github.com/copier-org/copier/issues/1887 + git("-c", "core.fsmonitor=false", "checkout", "-f", ref or "HEAD") git("submodule", "update", "--checkout", "--init", "--recursive", "--force") return location diff --git a/tests/test_vcs.py b/tests/test_vcs.py index cd7dff14e..0c6d09533 100644 --- a/tests/test_vcs.py +++ b/tests/test_vcs.py @@ -7,14 +7,15 @@ import pytest from packaging.version import Version from plumbum import local +from pytest_gitconfig.plugin import GitConfig from copier import run_copy, run_update from copier._main import Worker from copier._user_data import load_answersfile_data from copier._vcs import checkout_latest_tag, clone, get_git_version, get_repo -from copier.errors import ShallowCloneWarning +from copier.errors import DirtyLocalWarning, ShallowCloneWarning -from .helpers import git +from .helpers import build_file_tree, git, git_save def test_get_repo() -> None: @@ -88,6 +89,33 @@ def test_local_clone() -> None: shutil.rmtree(local_tmp, ignore_errors=True) +def test_local_dirty_clone( + tmp_path_factory: pytest.TempPathFactory, gitconfig: GitConfig +) -> None: + """ + When core.fsmonitor is enabled, normal `git checkout` command won't works. + """ + + gitconfig.set({"core.fsmonitor": "true"}) + src = tmp_path_factory.mktemp("src") + print(src) + + build_file_tree({src / "version.txt": "0.1.0"}) + git_save(src) + + build_file_tree({src / "version.txt": "0.2.0", src / "README.md": "hello world"}) + + with pytest.warns(DirtyLocalWarning): + local_tmp = clone(str(src)) + + assert local_tmp + assert Path(local_tmp, "version.txt").exists() + assert Path(local_tmp, "version.txt").read_text() == "0.2.0" + assert Path(local_tmp, "README.md").exists() + assert Path(local_tmp, "README.md").read_text() == "hello world" + shutil.rmtree(local_tmp, ignore_errors=True) + + @pytest.mark.impure def test_shallow_clone(tmp_path: Path, recwarn: pytest.WarningsRecorder) -> None: # This test should always work but should be much slower if `is_git_shallow_repo()` is not