◐ Shell
reader mode source ↗
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
File filter
Conversations
Jump to
Diff view
Apply and reload
Show whitespace
Diff view
Apply and reload
2 changes: 1 addition & 1 deletion git/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ def _included_paths(self) -> List[Tuple[str, str]]:
value,
)
if self._repo.git_dir:
if fnmatch.fnmatchcase(str(self._repo.git_dir), value):
paths += self.items(section)

elif keyword == "onbranch":
Expand Down
12 changes: 6 additions & 6 deletions git/index/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ def raise_exc(e: Exception) -> NoReturn:
r = str(self.repo.working_tree_dir)
rs = r + os.sep
for path in paths:
abs_path = str(path)
if not osp.isabs(abs_path):
abs_path = osp.join(r, path)
# END make absolute path
Expand Down Expand Up @@ -656,10 +656,10 @@ def _to_relative_path(self, path: PathLike) -> PathLike:
return path
if self.repo.bare:
raise InvalidGitRepositoryError("require non-bare repository")
if not osp.normpath(str(path)).startswith(str(self.repo.working_tree_dir)):
raise ValueError("Absolute path %r is not in git repository at %r" % (path, self.repo.working_tree_dir))
result = os.path.relpath(path, self.repo.working_tree_dir)
if str(path).endswith(os.sep) and not result.endswith(os.sep):
result += os.sep
return result

Expand Down Expand Up @@ -1036,7 +1036,7 @@ def remove(
args.append("--")

# Preprocess paths.
paths = self._items_to_rela_paths(items)
removed_paths = self.repo.git.rm(args, paths, **kwargs).splitlines()

# Process output to gain proper paths.
Expand Down Expand Up @@ -1359,11 +1359,11 @@ def make_exc() -> GitCommandError:
try:
self.entries[(co_path, 0)]
except KeyError:
folder = str(co_path)
if not folder.endswith("/"):
folder += "/"
for entry in self.entries.values():
if str(entry.path).startswith(folder):
p = entry.path
self._write_path_to_stdin(proc, p, p, make_exc, fprogress, read_from_stdout=False)
checked_out_files.append(p)
Expand Down
2 changes: 1 addition & 1 deletion git/index/fun.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None:
return

env = os.environ.copy()
env["GIT_INDEX_FILE"] = safe_decode(str(index.path))
env["GIT_EDITOR"] = ":"
cmd = [hp]
try:
4 changes: 2 additions & 2 deletions git/index/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

# typing ----------------------------------------------------------------------

from typing import Any, Callable, TYPE_CHECKING, Optional, Type

from git.types import Literal, PathLike, _T

Expand Down @@ -106,7 +106,7 @@ def git_working_dir(func: Callable[..., _T]) -> Callable[..., _T]:
@wraps(func)
def set_git_working_dir(self: "IndexFile", *args: Any, **kwargs: Any) -> _T:
cur_wd = os.getcwd()
os.chdir(str(self.repo.working_tree_dir))
try:
return func(self, *args, **kwargs)
finally:
Expand Down
3 changes: 2 additions & 1 deletion git/objects/blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
__all__ = ["Blob"]

from mimetypes import guess_type
import sys

if sys.version_info >= (3, 8):
Expand Down @@ -44,5 +45,5 @@ def mime_type(self) -> str:
"""
guesses = None
if self.path:
guesses = guess_type(str(self.path))
return guesses and guesses[0] or self.DEFAULT_MIME_TYPE
4 changes: 2 additions & 2 deletions git/objects/submodule/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ def _clone_repo(
module_abspath_dir = osp.dirname(module_abspath)
if not osp.isdir(module_abspath_dir):
os.makedirs(module_abspath_dir)
module_checkout_path = osp.join(str(repo.working_tree_dir), path)

if url.startswith("../"):
remote_name = cast("RemoteReference", repo.active_branch.tracking_branch()).remote_name
Expand Up @@ -541,7 +541,7 @@ def add(
if sm.exists():
# Reretrieve submodule from tree.
try:
sm = repo.head.commit.tree[str(path)]
sm._name = name
return sm
except KeyError:
Expand Down
3 changes: 2 additions & 1 deletion git/refs/reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

__all__ = ["Reference"]

from git.util import IterableObj, LazyMixin

from .symbolic import SymbolicReference, T_References
Expand Up @@ -65,7 +66,7 @@ def __init__(self, repo: "Repo", path: PathLike, check_path: bool = True) -> Non
If ``False``, you can provide any path.
Otherwise the path must start with the default path prefix of this type.
"""
if check_path and not str(path).startswith(self._common_path_default + "/"):
raise ValueError(f"Cannot instantiate {self.__class__.__name__!r} from path {path}")
self.path: str # SymbolicReference converts to string at the moment.
super().__init__(repo, path)
Expand Down
21 changes: 11 additions & 10 deletions git/refs/symbolic.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
__all__ = ["SymbolicReference"]

import os

from gitdb.exc import BadName, BadObject

Expand Down Expand Up @@ -76,10 +77,10 @@ class SymbolicReference:

def __init__(self, repo: "Repo", path: PathLike, check_path: bool = False) -> None:
self.repo = repo
self.path = path

def __str__(self) -> str:
return str(self.path)

def __repr__(self) -> str:
return '<git.%s "%s">' % (self.__class__.__name__, self.path)
Expand All @@ -103,7 +104,7 @@ def name(self) -> str:
In case of symbolic references, the shortest assumable name is the path
itself.
"""
return str(self.path)

@property
def abspath(self) -> PathLike:
Expand Down Expand Up @@ -178,7 +179,7 @@ def _check_ref_name_valid(ref_path: PathLike) -> None:
"""
previous: Union[str, None] = None
one_before_previous: Union[str, None] = None
for c in str(ref_path):
if c in " ~^:?*[\\":
raise ValueError(
f"Invalid reference '{ref_path}': references cannot contain spaces, tildes (~), carets (^),"
Expand Down Expand Up @@ -212,7 +213,7 @@ def _check_ref_name_valid(ref_path: PathLike) -> None:
raise ValueError(f"Invalid reference '{ref_path}': references cannot end with a forward slash (/)")
elif previous == "@" and one_before_previous is None:
raise ValueError(f"Invalid reference '{ref_path}': references cannot be '@'")
elif any(component.endswith(".lock") for component in str(ref_path).split("/")):
raise ValueError(
f"Invalid reference '{ref_path}': references cannot have slash-separated components that end with"
" '.lock'"
Expand All @@ -235,7 +236,7 @@ def _get_ref_info_helper(
tokens: Union[None, List[str], Tuple[str, str]] = None
repodir = _git_dir(repo, ref_path)
try:
with open(os.path.join(repodir, str(ref_path)), "rt", encoding="UTF-8") as fp:
value = fp.read().rstrip()
# Don't only split on spaces, but on whitespace, which allows to parse lines like:
# 60b64ef992065e2600bfef6187a97f92398a9144 branch 'master' of git-server:/path/to/repo
Expand Down Expand Up @@ -614,7 +615,7 @@ def to_full_path(cls, path: Union[PathLike, "SymbolicReference"]) -> PathLike:
full_ref_path = path
if not cls._common_path_default:
return full_ref_path
if not str(path).startswith(cls._common_path_default + "/"):
full_ref_path = "%s/%s" % (cls._common_path_default, path)
return full_ref_path

Expand Up @@ -706,7 +707,7 @@ def _create(
if not force and os.path.isfile(abs_ref_path):
target_data = str(target)
if isinstance(target, SymbolicReference):
target_data = str(target.path)
if not resolve:
target_data = "ref: " + target_data
with open(abs_ref_path, "rb") as fd:
Expand Down Expand Up @@ -842,7 +843,7 @@ def _iter_items(

# Read packed refs.
for _sha, rela_path in cls._iter_packed_refs(repo):
if rela_path.startswith(str(common_path)):
rela_paths.add(rela_path)
# END relative path matches common path
# END packed refs reading
Expand Down Expand Up @@ -930,4 +931,4 @@ def from_path(cls: Type[T_References], repo: "Repo", path: PathLike) -> T_Refere

def is_remote(self) -> bool:
""":return: True if this symbolic reference points to a remote branch"""
return str(self.path).startswith(self._remote_common_path_default + "/")
19 changes: 9 additions & 10 deletions git/repo/base.py
Original file line number Diff line number Diff line change
@@ -126,6 +126,7 @@ class Repo:
working_dir: PathLike
"""The working directory of the git command."""

_working_tree_dir: Optional[PathLike] = None

git_dir: PathLike
Expand Down Expand Up @@ -215,15 +216,13 @@ def __init__(
epath = path or os.getenv("GIT_DIR")
if not epath:
epath = os.getcwd()
if Git.is_cygwin():
# 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(str(epath))

epath = epath or path or os.getcwd()
if not isinstance(epath, str):
epath = str(epath)
if expand_vars and re.search(self.re_envvars, epath):
warnings.warn(
"The use of environment variables in paths is deprecated"
Expand Down Expand Up @@ -957,7 +956,7 @@ def is_dirty(
if not submodules:
default_args.append("--ignore-submodules")
if path:
default_args.extend(["--", str(path)])
if index:
# diff index against HEAD.
if osp.isfile(self.index.path) and len(self.git.diff("--cached", *default_args)):
Expand Down Expand Up @@ -1357,9 +1356,9 @@ def _clone(
) -> "Repo":
odbt = kwargs.pop("odbt", odb_default_type)

# When pathlib.Path or other class-based path is passed
if not isinstance(path, str):
path = str(path)

## A bug win cygwin's Git, when `--bare` or `--separate-git-dir`
# it prepends the cwd or(?) the `url` into the `path, so::
Expand All @@ -1376,7 +1375,7 @@ def _clone(
multi = shlex.split(" ".join(multi_options))

if not allow_unsafe_protocols:
Git.check_unsafe_protocols(str(url))
if not allow_unsafe_options:
Git.check_unsafe_options(options=list(kwargs.keys()), unsafe_options=cls.unsafe_git_clone_options)
if not allow_unsafe_options and multi_options:
Expand All @@ -1385,7 +1384,7 @@ def _clone(
proc = git.clone(
multi,
"--",
Git.polish_url(str(url)),
clone_path,
with_extended_output=True,
as_process=True,
Expand Down
24 changes: 12 additions & 12 deletions git/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import logging
import os
import os.path as osp
import pathlib
import platform
import re
import shutil
Expand Down Expand Up @@ -272,9 +272,9 @@ def stream_copy(source: BinaryIO, destination: BinaryIO, chunk_size: int = 512 *
def join_path(a: PathLike, *p: PathLike) -> PathLike:
R"""Join path tokens together similar to osp.join, but always use ``/`` instead of
possibly ``\`` on Windows."""
path = str(a)
for b in p:
b = str(b)
if not b:
continue
if b.startswith("/"):
Expand All @@ -290,18 +290,18 @@ def join_path(a: PathLike, *p: PathLike) -> PathLike:
if sys.platform == "win32":

def to_native_path_windows(path: PathLike) -> PathLike:
path = str(path)
return path.replace("/", "\\")

def to_native_path_linux(path: PathLike) -> str:
path = str(path)
return path.replace("\\", "/")

to_native_path = to_native_path_windows
else:
# No need for any work on Linux.
def to_native_path_linux(path: PathLike) -> str:
return str(path)

to_native_path = to_native_path_linux

Expand Down Expand Up @@ -372,7 +372,7 @@ def is_exec(fpath: str) -> bool:
progs = []
if not path:
path = os.environ["PATH"]
for folder in str(path).split(os.pathsep):
folder = folder.strip('"')
if folder:
exe_path = osp.join(folder, program)
Expand All @@ -397,7 +397,7 @@ def _cygexpath(drive: Optional[str], path: str) -> str:
p = cygpath(p)
elif drive:
p = "/proc/cygdrive/%s/%s" % (drive.lower(), p)
p_str = str(p) # ensure it is a str and not AnyPath
return p_str.replace("\\", "/")


Expand All @@ -418,7 +418,7 @@ def _cygexpath(drive: Optional[str], path: str) -> str:

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", "//", "/proc/cygdrive")):
for regex, parser, recurse in _cygpath_parsers:
Expand All @@ -438,7 +438,7 @@ def cygpath(path: str) -> str:


def decygpath(path: PathLike) -> str:
path = str(path)
m = _decygpath_regex.match(path)
if m:
drive, rest_path = m.groups()
Expand All @@ -465,7 +465,7 @@ def _is_cygwin_git(git_executable: str) -> bool:
# Just a name given, not a real path.
uname_cmd = osp.join(git_dir, "uname")

if not (pathlib.Path(uname_cmd).is_file() and os.access(uname_cmd, os.X_OK)):
_logger.debug(f"Failed checking if running in CYGWIN: {uname_cmd} is not an executable")
_is_cygwin_cache[git_executable] = is_cygwin
return is_cygwin
Expand Down Expand Up @@ -523,7 +523,7 @@ def expand_path(p: PathLike, expand_vars: bool = ...) -> str:


def expand_path(p: Union[None, PathLike], expand_vars: bool = True) -> Optional[PathLike]:
if isinstance(p, pathlib.Path):
return p.resolve()
try:
p = osp.expanduser(p) # type: ignore[arg-type]
Expand Down
Loading
Loading
Toggle all file notes Toggle all file annotations