Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit77f74ce

Browse files
committed
initial patch to use git bash rather than WSL
1 parent32c02d1 commit77f74ce

File tree

3 files changed

+175
-4
lines changed

3 files changed

+175
-4
lines changed

‎git/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ def refresh(path: Optional[PathLike] = None) -> None:
126126

127127
ifnotGit.refresh(path=path):
128128
return
129+
Git.refresh_bash()
129130
ifnotFetchInfo.refresh():# noqa: F405
130131
return# type: ignore [unreachable]
131132

‎git/cmd.py

Lines changed: 172 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@
1111
importlogging
1212
importos
1313
importsignal
14-
fromsubprocessimportPopen,PIPE,DEVNULL
14+
fromsubprocessimportPopen,PIPE,DEVNULL,run,CalledProcessError
1515
importsubprocess
1616
importthreading
1717
fromtextwrapimportdedent
18+
frompathlibimportPath
1819

19-
fromgit.compatimportdefenc,force_bytes,safe_decode
20+
fromgit.compatimportdefenc,force_bytes,safe_decode,is_win
2021
fromgit.excimport (
2122
CommandError,
2223
GitCommandError,
@@ -305,6 +306,175 @@ def __setstate__(self, d: Dict[str, Any]) -> None:
305306
the top level ``__init__``.
306307
"""
307308

309+
_bash_exec_env_var="GIT_PYTHON_BASH_EXECUTABLE"
310+
311+
bash_exec_name="bash"
312+
"""Default bash command that should work on Linux, Windows, and other systems."""
313+
314+
GIT_PYTHON_BASH_EXECUTABLE=None
315+
"""Provide the full path to the bash executable. Otherwise it assumes bash is in the path.
316+
317+
Note that the bash executable is actually found during the refresh step in
318+
the top level ``__init__``.
319+
"""
320+
321+
@classmethod
322+
def_get_default_bash_path(cls):
323+
# Assumes that, if user is running in Windows, they probably are using
324+
# Git for Windows, which includes Git BASH and should be associated
325+
# with the configured Git command set in `refresh()`. Regardless of
326+
# if the Git command assumes it is installed in (root)/cmd/git.exe or
327+
# (root)/bin/git.exe, the root is always up two levels from the git
328+
# command. Try going up to levels from the currently configured
329+
# git command, then navigate to (root)/bin/bash.exe. If this exists,
330+
# prefer it over the WSL version in System32, direct access to which
331+
# is reportedly deprecated. Fail back to default "bash.exe" if
332+
# the Git for Windows lookup doesn't work.
333+
#
334+
# This addresses issues where git hooks are intended to run assuming
335+
# the "native" Windows environment as seen by git.exe rather than
336+
# inside the git sandbox of WSL, which is likely configured
337+
# independetly of the Windows Git. A noteworthy example are repos with
338+
# Git LFS, where Git LFS may be installed in Windows but not in WSL.
339+
ifnotis_win:
340+
return'bash'
341+
try:
342+
wheregit=run(['where',Git.GIT_PYTHON_GIT_EXECUTABLE],
343+
check=True,stdout=PIPE).stdout
344+
exceptCalledProcessError:
345+
return'bash.exe'
346+
gitpath=Path(wheregit.decode(defenc).splitlines()[0])
347+
gitroot=gitpath.parent.parent
348+
gitbash=gitroot/'bin'/'bash.exe'
349+
returnstr(gitbash)ifgitbash.existselse'bash.exe'
350+
351+
@classmethod
352+
defrefresh_bash(cls,path:Union[None,PathLike]=None)->bool:
353+
"""This gets called by the refresh function (see the top level __init__)."""
354+
# Discern which path to refresh with.
355+
ifpathisnotNone:
356+
new_bash=os.path.expanduser(path)
357+
new_bash=os.path.abspath(new_bash)
358+
else:
359+
new_bash=os.environ.get(cls._bash_exec_env_var)
360+
ifnew_bashisNone:
361+
new_bash=cls._get_default_bash_path()
362+
363+
# Keep track of the old and new bash executable path.
364+
old_bash=cls.GIT_PYTHON_BASH_EXECUTABLE
365+
cls.GIT_PYTHON_BASH_EXECUTABLE=new_bash
366+
367+
# Test if the new git executable path is valid. A GitCommandNotFound error is
368+
# spawned by us. A PermissionError is spawned if the git executable cannot be
369+
# executed for whatever reason.
370+
has_bash=False
371+
try:
372+
run([cls.GIT_PYTHON_BASH_EXECUTABLE,'--version'])
373+
has_bash=True
374+
exceptCalledProcessError:
375+
pass
376+
377+
# Warn or raise exception if test failed.
378+
ifnothas_bash:
379+
err= (
380+
dedent(
381+
f"""\
382+
Bad bash executable.
383+
The bash executable must be specified in one of the following ways:
384+
- be included in your $PATH
385+
- be set via ${cls._bash_exec_env_var}
386+
- explicitly set via git.refresh_bash()
387+
"""
388+
)
389+
)
390+
391+
# Revert to whatever the old_bash was.
392+
cls.GIT_PYTHON_BASH_EXECUTABLE=old_bash
393+
394+
ifold_bashisNone:
395+
# On the first refresh (when GIT_PYTHON_GIT_EXECUTABLE is None) we only
396+
# are quiet, warn, or error depending on the GIT_PYTHON_REFRESH value.
397+
398+
# Determine what the user wants to happen during the initial refresh we
399+
# expect GIT_PYTHON_REFRESH to either be unset or be one of the
400+
# following values:
401+
#
402+
# 0|q|quiet|s|silence|n|none
403+
# 1|w|warn|warning
404+
# 2|r|raise|e|error
405+
406+
mode=os.environ.get(cls._refresh_env_var,"raise").lower()
407+
408+
quiet= ["quiet","q","silence","s","none","n","0"]
409+
warn= ["warn","w","warning","1"]
410+
error= ["error","e","raise","r","2"]
411+
412+
ifmodeinquiet:
413+
pass
414+
elifmodeinwarnormodeinerror:
415+
err= (
416+
dedent(
417+
"""\
418+
%s
419+
All commit hook commands will error until this is rectified.
420+
421+
This initial warning can be silenced or aggravated in the future by setting the
422+
$%s environment variable. Use one of the following values:
423+
- %s: for no warning or exception
424+
- %s: for a printed warning
425+
- %s: for a raised exception
426+
427+
Example:
428+
export %s=%s
429+
"""
430+
)
431+
% (
432+
err,
433+
cls._refresh_env_var,
434+
"|".join(quiet),
435+
"|".join(warn),
436+
"|".join(error),
437+
cls._refresh_env_var,
438+
quiet[0],
439+
)
440+
)
441+
442+
ifmodeinwarn:
443+
print("WARNING: %s"%err)
444+
else:
445+
raiseImportError(err)
446+
else:
447+
err= (
448+
dedent(
449+
"""\
450+
%s environment variable has been set but it has been set with an invalid value.
451+
452+
Use only the following values:
453+
- %s: for no warning or exception
454+
- %s: for a printed warning
455+
- %s: for a raised exception
456+
"""
457+
)
458+
% (
459+
cls._refresh_env_var,
460+
"|".join(quiet),
461+
"|".join(warn),
462+
"|".join(error),
463+
)
464+
)
465+
raiseImportError(err)
466+
467+
# We get here if this was the init refresh and the refresh mode was not
468+
# error. Go ahead and set the GIT_PYTHON_BASH_EXECUTABLE such that we
469+
# discern the difference between a first import and a second import.
470+
cls.GIT_PYTHON_BASH_EXECUTABLE=cls.bash_exec_name
471+
else:
472+
# After the first refresh (when GIT_PYTHON_BASH_EXECUTABLE is no longer
473+
# None) we raise an exception.
474+
raiseGitCommandNotFound("bash",err)
475+
476+
returnhas_bash
477+
308478
@classmethod
309479
defrefresh(cls,path:Union[None,PathLike]=None)->bool:
310480
"""This gets called by the refresh function (see the top level __init__)."""

‎git/index/fun.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
)
1919
importsubprocess
2020

21-
fromgit.cmdimportPROC_CREATIONFLAGS,handle_process_output
21+
fromgit.cmdimportPROC_CREATIONFLAGS,handle_process_output,Git
2222
fromgit.compatimportdefenc,force_bytes,force_text,safe_decode
2323
fromgit.excimportHookExecutionError,UnmergedEntriesError
2424
fromgit.objects.funimport (
@@ -96,7 +96,7 @@ def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None:
9696
# Windows only uses extensions to determine how to open files
9797
# (doesn't understand shebangs). Try using bash to run the hook.
9898
relative_hp=Path(hp).relative_to(index.repo.working_dir).as_posix()
99-
cmd= ["bash.exe",relative_hp]
99+
cmd= [Git.GIT_PYTHON_BASH_EXECUTABLE,relative_hp]
100100

101101
process=subprocess.Popen(
102102
cmd+list(args),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp