diff --git a/.github/workflows/cygwin-test.yml b/.github/workflows/cygwin-test.yml new file mode 100644 index 000000000..6fe501249 --- /dev/null +++ b/.github/workflows/cygwin-test.yml @@ -0,0 +1,57 @@ +name: test-cygwin + +on: + push: + branches: + main + pull_request: + branches: + main + +jobs: + build: + runs-on: windows-latest + env: + CHERE_INVOKING: 1 + SHELLOPTS: igncr + TMP: "/tmp" + TEMP: "/tmp" + + steps: + - name: Force LF line endings + run: git config --global core.autocrlf input + - uses: actions/checkout@v3 + with: + fetch-depth: 9999 + - uses: cygwin/cygwin-install-action@v2 + with: + packages: python39 python39-pip python39-virtualenv git + - name: Tell git to trust this repo + shell: bash.exe -eo pipefail -o igncr "{0}" + run: /usr/bin/git config --global --add safe.directory $(pwd) + - name: Install dependencies and prepare tests + shell: bash.exe -eo pipefail -o igncr "{0}" + run: | + set -x + /usr/bin/python -m pip install --upgrade pip setuptools wheel + /usr/bin/python --version; /usr/bin/git --version + /usr/bin/git submodule update --init --recursive + /usr/bin/git fetch --tags + /usr/bin/python -m pip install -r requirements.txt + /usr/bin/python -m pip install -r test-requirements.txt + TRAVIS=yes ./init-tests-after-clone.sh + /usr/bin/git config --global user.email "travis@ci.com" + /usr/bin/git config --global user.name "Travis Runner" + # If we rewrite the user's config by accident, we will mess it up + # and cause subsequent tests to fail + cat test/fixtures/.gitconfig >> ~/.gitconfig + - name: Lint with flake8 + shell: bash.exe -eo pipefail -o igncr "{0}" + run: | + set -x + /usr/bin/python -m flake8 + - name: Test with pytest + shell: bash.exe -eo pipefail -o igncr "{0}" + run: | + /usr/bin/python -m pytest + continue-on-error: false diff --git a/git/repo/base.py b/git/repo/base.py index 111a350e9..5a85cc4e2 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -29,7 +29,7 @@ from git.util import ( Actor, finalize_process, - decygpath, + cygpath, hex_to_bin, expand_path, remove_password_if_present, @@ -175,7 +175,10 @@ def __init__( if not epath: epath = os.getcwd() if Git.is_cygwin(): - epath = decygpath(epath) + # Given how the tests are written, this seems more likely to catch + # Cygwin git used from Windows than Windows git used from Cygwin. + # Therefore changing to Cygwin-style paths is the relevant operation. + epath = cygpath(epath) epath = epath or path or os.getcwd() if not isinstance(epath, str): diff --git a/git/repo/fun.py b/git/repo/fun.py index 8a07c2abd..2ca2e3d6f 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -7,7 +7,7 @@ from git.exc import WorkTreeRepositoryUnsupported from git.objects import Object from git.refs import SymbolicReference -from git.util import hex_to_bin, bin_to_hex, decygpath +from git.util import hex_to_bin, bin_to_hex, cygpath from gitdb.exc import ( BadObject, BadName, @@ -109,7 +109,9 @@ def find_submodule_git_dir(d: "PathLike") -> Optional["PathLike"]: if Git.is_cygwin(): ## Cygwin creates submodules prefixed with `/cygdrive/...` suffixes. - path = decygpath(path) + # Cygwin git understands Cygwin paths much better than Windows ones + # Also the Cygwin tests are assuming Cygwin paths. + path = cygpath(path) if not osp.isabs(path): path = osp.normpath(osp.join(osp.dirname(d), path)) return find_submodule_git_dir(path) diff --git a/git/util.py b/git/util.py index 11139156c..6a4a65579 100644 --- a/git/util.py +++ b/git/util.py @@ -310,7 +310,7 @@ def _cygexpath(drive: Optional[str], path: str) -> str: else: p = cygpath(p) elif drive: - p = "/cygdrive/%s/%s" % (drive.lower(), p) + p = "/proc/cygdrive/%s/%s" % (drive.lower(), p) p_str = str(p) # ensure it is a str and not AnyPath return p_str.replace("\\", "/") @@ -334,7 +334,7 @@ def cygpath(path: str) -> str: """Use :meth:`git.cmd.Git.polish_url()` instead, that works on any environment.""" path = str(path) # ensure is str and not AnyPath. # Fix to use Paths when 3.5 dropped. or to be just str if only for urls? - if not path.startswith(("/cygdrive", "//")): + if not path.startswith(("/cygdrive", "//", "/proc/cygdrive")): for regex, parser, recurse in _cygpath_parsers: match = regex.match(path) if match: @@ -348,7 +348,7 @@ def cygpath(path: str) -> str: return path -_decygpath_regex = re.compile(r"/cygdrive/(\w)(/.*)?") +_decygpath_regex = re.compile(r"(?:/proc)?/cygdrive/(\w)(/.*)?") def decygpath(path: PathLike) -> str: @@ -377,7 +377,9 @@ def is_cygwin_git(git_executable: PathLike) -> bool: def is_cygwin_git(git_executable: Union[None, PathLike]) -> bool: - if not is_win: + if is_win: + # is_win seems to be true only for Windows-native pythons + # cygwin has os.name = posix, I think return False if git_executable is None: diff --git a/test/test_docs.py b/test/test_docs.py index bea34a0b8..20027c191 100644 --- a/test/test_docs.py +++ b/test/test_docs.py @@ -5,6 +5,9 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php import os +import sys + +import pytest from test.lib import TestBase from test.lib.helper import with_rw_directory @@ -475,6 +478,11 @@ def test_references_and_objects(self, rw_dir): repo.git.clear_cache() + @pytest.mark.xfail( + sys.platform == "cygwin", + reason="Cygwin GitPython can't find SHA for submodule", + raises=ValueError + ) def test_submodules(self): # [1-test_submodules] repo = self.rorepo diff --git a/test/test_repo.py b/test/test_repo.py index 30db13920..75b590fe7 100644 --- a/test/test_repo.py +++ b/test/test_repo.py @@ -11,9 +11,12 @@ import os import pathlib import pickle +import sys import tempfile from unittest import mock, skipIf, SkipTest +import pytest + from git import ( InvalidGitRepositoryError, Repo, @@ -903,6 +906,11 @@ def test_repo_odbtype(self): target_type = GitCmdObjectDB self.assertIsInstance(self.rorepo.odb, target_type) + @pytest.mark.xfail( + sys.platform == "cygwin", + reason="Cygwin GitPython can't find submodule SHA", + raises=ValueError + ) def test_submodules(self): self.assertEqual(len(self.rorepo.submodules), 1) # non-recursive self.assertGreaterEqual(len(list(self.rorepo.iter_submodules())), 2) diff --git a/test/test_submodule.py b/test/test_submodule.py index 2930ce032..d72fe5d3a 100644 --- a/test/test_submodule.py +++ b/test/test_submodule.py @@ -3,8 +3,11 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php import os import shutil +import sys from unittest import skipIf +import pytest + import git from git.cmd import Git from git.compat import is_win @@ -437,6 +440,11 @@ def test_base_rw(self, rwrepo): def test_base_bare(self, rwrepo): self._do_base_tests(rwrepo) + @pytest.mark.xfail( + sys.platform == "cygwin", + reason="Cygwin GitPython can't find submodule SHA", + raises=ValueError + ) @skipIf( HIDE_WINDOWS_KNOWN_ERRORS, """