GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — use `sys.platform == "cygwin"` to figure out when we are using cygwin by gcmarx · Pull Request #2027 · gitpython-developers/GitPython Conversation
Contributor
The current logic for detecting cygwin is:
In the python 3.7 docs for sys.platform, Cygwin systems have The logic I propose is:
This is simple enough for a single expression, so I replaced the body of the I don't know if there's such a thing as
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Byron
requested review from
EliahKagan and
Copilot
and removed request for
EliahKagan
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pull Request OverviewThis PR simplifies the detection of Cygwin Git by replacing the former multi-step logic with a concise check that relies on sys.platform.
Reviewed ChangesCopilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactionsUh oh!
There was an error while loading. Please reload this page. sys.platform == "cygwin" to figure out when we are using cygwin
EliahKagan
reviewed
|
|
Thanks for the thorough review! Neither the value of |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
I've looked into this further. Keeping
|
| if not is_win: | |
| return False |
Where:
Line 28 in e6e23ed
| is_win = (os.name == 'nt') |
I believe that, even at that time and even in Python 2, os.name on Cygwin evaluated to "posix" as it does today. Thus, the scenario where is_cygwin_git would return True was when the Python interpreter was a native Windows executable and git was a Cygwin executable! This makes sense, since the title of that PR was "Support Cygwin's Git on Windows".
At that time, AppVeyor was used for CI. The .appveyor.yml file from that time confirms that this is what was going on--the original purpose of is_cygwin_git was to allow native Windows Python programs to use GitPython with either Git for Windows or Cygwin git. In relevant part:
Lines 2 to 38 in cc77e6b
| environment: | |
| GIT_DAEMON_PATH: "C:\\Program Files\\Git\\mingw64\\libexec\\git-core" | |
| CYGWIN_GIT_PATH: "C:\\cygwin\\bin;%GIT_DAEMON_PATH%" | |
| CYGWIN64_GIT_PATH: "C:\\cygwin64\\bin;%GIT_DAEMON_PATH%" | |
| matrix: | |
| ## MINGW | |
| # | |
| - PYTHON: "C:\\Python27" | |
| PYTHON_VERSION: "2.7" | |
| GIT_PATH: "%GIT_DAEMON_PATH%" | |
| - PYTHON: "C:\\Python34-x64" | |
| PYTHON_VERSION: "3.4" | |
| GIT_PATH: "%GIT_DAEMON_PATH%" | |
| - PYTHON: "C:\\Python35-x64" | |
| PYTHON_VERSION: "3.5" | |
| GIT_PATH: "%GIT_DAEMON_PATH%" | |
| - PYTHON: "C:\\Miniconda35-x64" | |
| PYTHON_VERSION: "3.5" | |
| IS_CONDA: "yes" | |
| GIT_PATH: "%GIT_DAEMON_PATH%" | |
| ## Cygwin | |
| # | |
| - PYTHON: "C:\\Miniconda-x64" | |
| PYTHON_VERSION: "2.7" | |
| IS_CONDA: "yes" | |
| IS_CYGWIN: "yes" | |
| GIT_PATH: "%CYGWIN_GIT_PATH%" | |
| - PYTHON: "C:\\Python35-x64" | |
| PYTHON_VERSION: "3.5" | |
| GIT_PATH: "%CYGWIN64_GIT_PATH%" | |
| IS_CYGWIN: "yes" | |
| install: | |
| - set PATH=%PYTHON%;%PYTHON%\Scripts;%GIT_PATH%;%PATH% |
The second was Re-enable Cygwin CI and get most tests passing #1455 in 2022, which included this very significant change to is_cygwin_git in 96fae83:
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
Much as #533 was guided by testing on AppVeyor set up so that Cygwin git was being called only from native Windows builds of Python, #1455 was guided by testing on GitHub Actions set up so that Cygwin git was being called only from Cygwin builds of Python.
I cannot tell from the history whether this distinction was recognized at the time! It may be that this change was made based on the belief that is_cygwin_git had already been intended to return False except in Cygwin builds of Python, I am not sure. But it may be that it was intentional. It would make sense if, over time, it has become rarer and rarer to use anything but Git for Windows for git on Windows, except when operating entirely within some other specific environment.
An important question is whether, since #1455, there is anything in GitPython that actually works because of the ability to identify a non-Cygwin git executable from Cygwin. Operations with such an executable seem either to work on main, in the original #2026 (cffa264), and here... or not to work in any of the three. An example of something that should in principle work if GitPython on Cygwin supports non-Cygwin git, but that fails and fails the same way in all three, is:
(.venv) ✔ ~/repos-cygwin/GitPython [main|⚑ 1]
09:27 $ GIT_PYTHON_GIT_EXECUTABLE=/cygdrive/c/Users/ek/scoop/shims/git python3.9 -c 'import git; r1 = git.Repo.clone_from("https://github.com/EliahKagan/trivial.git", "trivial"); r2 = r1.clone("trivial-clone", bare=True); print(r2.git_dir)'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/ek/repos-cygwin/GitPython/git/repo/base.py", line 1482, in clone
return self._clone(
File "/home/ek/repos-cygwin/GitPython/git/repo/base.py", line 1414, in _clone
finalize_process(proc, stderr=stderr)
File "/home/ek/repos-cygwin/GitPython/git/util.py", line 504, in finalize_process
proc.wait(**kwargs)
File "/home/ek/repos-cygwin/GitPython/git/cmd.py", line 834, in wait
raise GitCommandError(remove_password_if_present(self.args), status, errstr)
git.exc.GitCommandError: Cmd('/cygdrive/c/Users/ek/scoop/shims/git') failed due to: exit code(128)
cmdline: /cygdrive/c/Users/ek/scoop/shims/git clone -v --bare -- /home/ek/repos-cygwin/GitPython/trivial/.git trivial-clone
stderr: 'fatal: repository '/home/ek/repos-cygwin/GitPython/trivial/.git' does not exist
'
What happens there is that a decygpath operation is either not being done or not being done correctly in at least one place where it would need to happen to support Git for Windows git from Cygwin. I am not sure if this has ever worked.
So that's admittedly a reason to prefer this PR: it's not clear under what circumstances, if any, is_cygwin_git has done any better than this, since #1455.
But I think this examination of the history also shows that the original #2026 (up to cffa264) is safe and strictly improves correctness. The sys.platform == "win32" condition on main descends from the is_win check. (sys.platform == "win32" always has the same value as os.name == "nt", at least in Python 3 and I think since well before that.) When I introduced the TODO comment in 42e10c0 (#1859), I was worried that doing the check even when the platform doesn't seem to be Cygwin might've been intentional, and that checking if git seems to be a Cygwin executable only when sys.platform == "cygwin" might somehow break something. I think looking at the history confirms that this is not the case.
Somewhat confusingly, Cygwin is not the only platform in which sys.platform is "cygwin".
We don't test MSYS2 on CI, though maybe we should. I don't know how often, if at all, people use GitPython in a Python interpreter that targets MSYS2. (This should not be confused with other environments that MSYS2 supplies, such as MINGW64, which is actually a native Windows target rather than a Cygwin-like target. I am talking about the MSYS environment of MSYS2, which is a non-Cygwin but Cygwin-like target.)
In MSYS2, sys.platform is "cygwin":
ek@Glub MSYS ~
$ python -c 'import sys; print(sys.platform)'
cygwin
But uname does not report CYGWIN:
ek@Glub MSYS ~
$ uname
MSYS_NT-10.0-19045
The facilities within GitPython that do Cygwin-related things, such as cygpath and decygpath, and their helpers, in git/util.py--which are used in more places when git is detected to be a Cygwin build--don't look like they will always work on MSYS2. While a MSYS2 does have /proc/cygdrive, it does not have /cygdrive; a path like /cygdrive/c in Cygwin is just /c is MSYS2. There may be other relevant differences.
As things stand now, where MSYS2 git run from MSYS2 is not considered to be a Cygwin git, MSYS2 does seem to work pretty well, though maybe not perfectly. I say that based on this test run; see #1988 (comment) for context. It may be good to look into that further before doing anything that would cause MSYS2 to be treated more like Cygwin.
This also applies to the strings approach pushed to #2026 after cffa264--strings will turn up cygwin in MSYS2 git as well:
ek@Glub MSYS ~
$ strings /usr/bin/git | grep -F cygwin
cygwin_conv_path
cygwin_internal
__imp_cygwin_internal
__imp_cygwin_conv_path
So this is part of why I'd be interested to integrate cffa264 first.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Since this was intended to be merged only if #2026 was not, and #2026 is merged, I've closed this. It's plausible--though I think not most likely--that we'll eventually end up going this route and no longer attempting to determine whether the |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.