From c081f51b6d4ea6020a411e4ec5c2f90a48e10cad Mon Sep 17 00:00:00 2001 From: Dominic Date: Sat, 31 Jul 2021 13:27:55 +0100 Subject: [PATCH 1/5] update types commit.py --- git/objects/commit.py | 1 + 1 file changed, 1 insertion(+) diff --git a/git/objects/commit.py b/git/objects/commit.py index 884f65228..9d7096563 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -128,6 +128,7 @@ def __init__(self, repo: 'Repo', binsha: bytes, tree: Union[Tree, None] = None, as what time.altzone returns. The sign is inverted compared to git's UTC timezone.""" super(Commit, self).__init__(repo, binsha) + self.binsha = binsha if tree is not None: assert isinstance(tree, Tree), "Tree needs to be a Tree instance, was %s" % type(tree) if tree is not None: From 0affa33e449db5ba3e00e4c606e6d0c78ce228cf Mon Sep 17 00:00:00 2001 From: Dominic Date: Sat, 31 Jul 2021 13:28:39 +0100 Subject: [PATCH 2/5] update types submodule/base.py --- git/objects/submodule/base.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 29212167c..143511909 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -563,6 +563,7 @@ def update(self, recursive: bool = False, init: bool = True, to_latest_revision: progress.update(op, i, len_rmts, prefix + "Done fetching remote of submodule %r" % self.name) # END fetch new data except InvalidGitRepositoryError: + mrepo = None if not init: return self # END early abort if init is not allowed @@ -603,7 +604,7 @@ def update(self, recursive: bool = False, init: bool = True, to_latest_revision: # make sure HEAD is not detached mrepo.head.set_reference(local_branch, logmsg="submodule: attaching head to %s" % local_branch) - mrepo.head.ref.set_tracking_branch(remote_branch) + mrepo.head.reference.set_tracking_branch(remote_branch) except (IndexError, InvalidGitRepositoryError): log.warning("Failed to checkout tracking branch %s", self.branch_path) # END handle tracking branch @@ -629,13 +630,14 @@ def update(self, recursive: bool = False, init: bool = True, to_latest_revision: if mrepo is not None and to_latest_revision: msg_base = "Cannot update to latest revision in repository at %r as " % mrepo.working_dir if not is_detached: - rref = mrepo.head.ref.tracking_branch() + rref = mrepo.head.reference.tracking_branch() if rref is not None: rcommit = rref.commit binsha = rcommit.binsha hexsha = rcommit.hexsha else: - log.error("%s a tracking branch was not set for local branch '%s'", msg_base, mrepo.head.ref) + log.error("%s a tracking branch was not set for local branch '%s'", + msg_base, mrepo.head.reference) # END handle remote ref else: log.error("%s there was no local tracking branch", msg_base) From a3cd08a402f9517583b263152dddfa0005934015 Mon Sep 17 00:00:00 2001 From: Dominic Date: Sat, 31 Jul 2021 13:29:15 +0100 Subject: [PATCH 3/5] update types submodule/root.py --- git/objects/submodule/root.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/git/objects/submodule/root.py b/git/objects/submodule/root.py index bcac5419a..5e84d1616 100644 --- a/git/objects/submodule/root.py +++ b/git/objects/submodule/root.py @@ -2,9 +2,7 @@ Submodule, UpdateProgress ) -from .util import ( - find_first_remote_branch -) +from .util import find_first_remote_branch from git.exc import InvalidGitRepositoryError import git From 03190098bdf0f4c0cbb90e39f464c3dd67b0ee1d Mon Sep 17 00:00:00 2001 From: Dominic Date: Sat, 31 Jul 2021 13:34:22 +0100 Subject: [PATCH 4/5] update types sybmbolic.py --- git/refs/symbolic.py | 172 ++++++++++++++++++++++++------------------- 1 file changed, 98 insertions(+), 74 deletions(-) diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 0e9dad5cc..4171fe234 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -1,4 +1,3 @@ -from git.types import PathLike import os from git.compat import defenc @@ -17,17 +16,18 @@ BadName ) -import os.path as osp - -from .log import RefLog +from .log import RefLog, RefLogEntry # typing ------------------------------------------------------------------ -from typing import Any, Iterator, List, Match, Optional, Tuple, Type, TypeVar, Union, TYPE_CHECKING # NOQA +from typing import Any, Iterator, List, Match, Optional, Tuple, Type, TypeVar, Union, TYPE_CHECKING, cast # NOQA from git.types import Commit_ish, PathLike, TBD, Literal # NOQA if TYPE_CHECKING: from git.repo import Repo + from git.refs import Reference, Head, TagReference, RemoteReference + from git.config import GitConfigParser + from git.objects.commit import Actor T_References = TypeVar('T_References', bound='SymbolicReference') @@ -37,9 +37,9 @@ __all__ = ["SymbolicReference"] -def _git_dir(repo, path): +def _git_dir(repo: 'Repo', path: PathLike) -> PathLike: """ Find the git dir that's appropriate for the path""" - name = "%s" % (path,) + name = f"{path}" if name in ['HEAD', 'ORIG_HEAD', 'FETCH_HEAD', 'index', 'logs']: return repo.git_dir return repo.common_dir @@ -59,46 +59,47 @@ class SymbolicReference(object): _remote_common_path_default = "refs/remotes" _id_attribute_ = "name" - def __init__(self, repo: 'Repo', path: PathLike, check_path: bool = False): + def __init__(self, repo: 'Repo', path: PathLike, check_path: bool = False) -> None: self.repo = repo self.path = str(path) + self.ref = self._get_reference() def __str__(self) -> str: return self.path - def __repr__(self): + def __repr__(self) -> str: return '' % (self.__class__.__name__, self.path) - def __eq__(self, other): + def __eq__(self, other) -> bool: if hasattr(other, 'path'): return self.path == other.path return False - def __ne__(self, other): + def __ne__(self, other) -> bool: return not (self == other) def __hash__(self): return hash(self.path) @property - def name(self): + def name(self) -> str: """ :return: In case of symbolic references, the shortest assumable name is the path itself.""" - return self.path + return str(self.path) @property - def abspath(self): + def abspath(self) -> PathLike: return join_path_native(_git_dir(self.repo, self.path), self.path) @classmethod - def _get_packed_refs_path(cls, repo): - return osp.join(repo.common_dir, 'packed-refs') + def _get_packed_refs_path(cls, repo: 'Repo') -> str: + return os.path.join(repo.common_dir, 'packed-refs') @classmethod - def _iter_packed_refs(cls, repo): - """Returns an iterator yielding pairs of sha1/path pairs (as bytes) for the corresponding refs. + def _iter_packed_refs(cls, repo: 'Repo') -> Iterator[Tuple[str, str]]: + """Returns an iterator yielding pairs of sha1/path pairs for the corresponding refs. :note: The packed refs file will be kept open as long as we iterate""" try: with open(cls._get_packed_refs_path(repo), 'rt', encoding='UTF-8') as fp: @@ -126,7 +127,7 @@ def _iter_packed_refs(cls, repo): if line[0] == '^': continue - yield tuple(line.split(' ', 1)) + yield cast(Tuple[str, str], tuple(line.split(' ', 1))) # END for each line except OSError: return None @@ -137,26 +138,26 @@ def _iter_packed_refs(cls, repo): # alright. @classmethod - def dereference_recursive(cls, repo, ref_path): + def dereference_recursive(cls, repo: 'Repo', ref_path: PathLike) -> str: """ :return: hexsha stored in the reference at the given ref_path, recursively dereferencing all intermediate references as required :param repo: the repository containing the reference at ref_path""" while True: - hexsha, ref_path = cls._get_ref_info(repo, ref_path) + hexsha, _ref_path_out = cls._get_ref_info(repo, ref_path) if hexsha is not None: return hexsha # END recursive dereferencing @classmethod - def _get_ref_info_helper(cls, repo, ref_path): + def _get_ref_info_helper(cls, repo: 'Repo', ref_path: PathLike) -> Union[Tuple[str, None], Tuple[None, PathLike]]: """Return: (str(sha), str(target_ref_path)) if available, the sha the file at rela_path points to, or None. target_ref_path is the reference we point to, or None""" - tokens = None + tokens: Union[List[str], Tuple[str, str], None] = None repodir = _git_dir(repo, ref_path) try: - with open(osp.join(repodir, ref_path), 'rt', encoding='UTF-8') as fp: + with open(os.path.join(repodir, 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 @@ -188,13 +189,14 @@ def _get_ref_info_helper(cls, repo, ref_path): raise ValueError("Failed to parse reference information from %r" % ref_path) @classmethod - def _get_ref_info(cls, repo, ref_path): + def _get_ref_info(cls, repo: 'Repo', ref_path: PathLike + ) -> Union[Tuple[str, None], Tuple[None, PathLike]]: """Return: (str(sha), str(target_ref_path)) if available, the sha the file at rela_path points to, or None. target_ref_path is the reference we point to, or None""" return cls._get_ref_info_helper(repo, ref_path) - def _get_object(self): + def _get_object(self) -> Commit_ish: """ :return: The object our ref currently refers to. Refs can be cached, they will @@ -203,7 +205,7 @@ def _get_object(self): # Our path will be resolved to the hexsha which will be used accordingly return Object.new_from_sha(self.repo, hex_to_bin(self.dereference_recursive(self.repo, self.path))) - def _get_commit(self): + def _get_commit(self) -> 'Commit': """ :return: Commit object we point to, works for detached and non-detached @@ -218,7 +220,8 @@ def _get_commit(self): # END handle type return obj - def set_commit(self, commit: Union[Commit, 'SymbolicReference', str], logmsg=None): + def set_commit(self, commit: Union[Commit, 'SymbolicReference', str], + logmsg: Union[str, None] = None) -> None: """As set_object, but restricts the type of object to be a Commit :raise ValueError: If commit is not a Commit object or doesn't point to @@ -228,11 +231,13 @@ def set_commit(self, commit: Union[Commit, 'SymbolicReference', str], logmsg=Non invalid_type = False if isinstance(commit, Object): invalid_type = commit.type != Commit.type + commit = cast('Commit', commit) elif isinstance(commit, SymbolicReference): invalid_type = commit.object.type != Commit.type else: try: - invalid_type = self.repo.rev_parse(commit).type != Commit.type + commit = self.repo.rev_parse(commit) + invalid_type = commit.type != Commit.type except (BadObject, BadName) as e: raise ValueError("Invalid object: %s" % commit) from e # END handle exception @@ -245,9 +250,12 @@ def set_commit(self, commit: Union[Commit, 'SymbolicReference', str], logmsg=Non # we leave strings to the rev-parse method below self.set_object(commit, logmsg) - return self + # return self + return None - def set_object(self, object, logmsg=None): # @ReservedAssignment + def set_object(self, object: Union[Commit_ish, 'SymbolicReference'], + logmsg: Union[str, None] = None + ) -> 'SymbolicReference': # @ReservedAssignment """Set the object we point to, possibly dereference our symbolic reference first. If the reference does not exist, it will be created @@ -274,10 +282,11 @@ def set_object(self, object, logmsg=None): # @ReservedAssignment # set the commit on our reference return self._get_reference().set_object(object, logmsg) - commit = property(_get_commit, set_commit, doc="Query or set commits directly") - object = property(_get_object, set_object, doc="Return the object our ref currently refers to") + commit = cast('Commit', property(_get_commit, set_commit, doc="Query or set commits directly")) + object = property(_get_object, set_object, doc="Return the object our ref currently refers to") # type: ignore - def _get_reference(self): + def _get_reference(self + ) -> Union['Head', 'RemoteReference', 'TagReference', 'Reference']: """:return: Reference Object we point to :raise TypeError: If this symbolic reference is detached, hence it doesn't point to a reference, but to a commit""" @@ -286,7 +295,8 @@ def _get_reference(self): raise TypeError("%s is a detached symbolic reference as it points to %r" % (self, sha)) return self.from_path(self.repo, target_ref_path) - def set_reference(self, ref, logmsg=None): + def set_reference(self, ref: Union[str, Commit_ish, 'SymbolicReference'], logmsg: Union[str, None] = None + ) -> 'SymbolicReference': """Set ourselves to the given ref. It will stay a symbol if the ref is a Reference. Otherwise an Object, given as Object instance or refspec, is assumed and if valid, will be set which effectively detaches the refererence if it was a purely @@ -327,7 +337,7 @@ def set_reference(self, ref, logmsg=None): raise TypeError("Require commit, got %r" % obj) # END verify type - oldbinsha = None + oldbinsha: bytes = b'' if logmsg is not None: try: oldbinsha = self.commit.binsha @@ -355,11 +365,16 @@ def set_reference(self, ref, logmsg=None): return self - # aliased reference - reference = property(_get_reference, set_reference, doc="Returns the Reference we point to") - ref: Union[Commit_ish] = reference # type: ignore # Union[str, Commit_ish, SymbolicReference] + @ property + def reference(self) -> Union['Head', 'RemoteReference', 'TagReference', 'Reference']: + return self._get_reference() - def is_valid(self): + @ reference.setter + def reference(self, ref: Union[str, Commit_ish, 'SymbolicReference'], logmsg: Union[str, None] = None + ) -> 'SymbolicReference': + return self.set_reference(ref=ref, logmsg=logmsg) + + def is_valid(self) -> bool: """ :return: True if the reference is valid, hence it can be read and points to @@ -371,7 +386,7 @@ def is_valid(self): else: return True - @property + @ property def is_detached(self): """ :return: @@ -383,7 +398,7 @@ def is_detached(self): except TypeError: return True - def log(self): + def log(self) -> 'RefLog': """ :return: RefLog for this reference. Its last entry reflects the latest change applied to this reference @@ -392,7 +407,8 @@ def log(self): instead of calling this method repeatedly. It should be considered read-only.""" return RefLog.from_file(RefLog.path(self)) - def log_append(self, oldbinsha, message, newbinsha=None): + def log_append(self, oldbinsha: bytes, message: Union[str, None], + newbinsha: Union[bytes, None] = None) -> 'RefLogEntry': """Append a logentry to the logfile of this ref :param oldbinsha: binary sha this ref used to point to @@ -404,15 +420,19 @@ def log_append(self, oldbinsha, message, newbinsha=None): # correct to allow overriding the committer on a per-commit level. # See https://github.com/gitpython-developers/GitPython/pull/146 try: - committer_or_reader = self.commit.committer + committer_or_reader: Union['Actor', 'GitConfigParser'] = self.commit.committer except ValueError: committer_or_reader = self.repo.config_reader() # end handle newly cloned repositories - return RefLog.append_entry(committer_or_reader, RefLog.path(self), oldbinsha, - (newbinsha is None and self.commit.binsha) or newbinsha, - message) + if newbinsha is None: + newbinsha = self.commit.binsha + + if message is None: + message = '' - def log_entry(self, index): + return RefLog.append_entry(committer_or_reader, RefLog.path(self), oldbinsha, newbinsha, message) + + def log_entry(self, index: int) -> RefLogEntry: """:return: RefLogEntry at the given index :param index: python list compatible positive or negative index @@ -421,22 +441,23 @@ def log_entry(self, index): In that case, it will be faster than the ``log()`` method""" return RefLog.entry_at(RefLog.path(self), index) - @classmethod - def to_full_path(cls, path) -> PathLike: + @ classmethod + def to_full_path(cls, path: Union[PathLike, 'SymbolicReference']) -> str: """ :return: string with a full repository-relative path which can be used to initialize a Reference instance, for instance by using ``Reference.from_path``""" if isinstance(path, SymbolicReference): path = path.path - full_ref_path = path + full_ref_path = str(path) if not cls._common_path_default: return full_ref_path - if not path.startswith(cls._common_path_default + "/"): + + if not str(path).startswith(cls._common_path_default + "/"): full_ref_path = '%s/%s' % (cls._common_path_default, path) return full_ref_path - @classmethod - def delete(cls, repo, path): + @ classmethod + def delete(cls, repo: 'Repo', path: PathLike) -> None: """Delete the reference at the given path :param repo: @@ -447,8 +468,8 @@ def delete(cls, repo, path): or just "myreference", hence 'refs/' is implied. Alternatively the symbolic reference to be deleted""" full_ref_path = cls.to_full_path(path) - abs_path = osp.join(repo.common_dir, full_ref_path) - if osp.exists(abs_path): + abs_path = os.path.join(repo.common_dir, full_ref_path) + if os.path.exists(abs_path): os.remove(abs_path) else: # check packed refs @@ -458,8 +479,8 @@ def delete(cls, repo, path): new_lines = [] made_change = False dropped_last_line = False - for line in reader: - line = line.decode(defenc) + for line_bytes in reader: + line = line_bytes.decode(defenc) _, _, line_ref = line.partition(' ') line_ref = line_ref.strip() # keep line if it is a comment or if the ref to delete is not @@ -489,12 +510,14 @@ def delete(cls, repo, path): # delete the reflog reflog_path = RefLog.path(cls(repo, full_ref_path)) - if osp.isfile(reflog_path): + if os.path.isfile(reflog_path): os.remove(reflog_path) # END remove reflog - @classmethod - def _create(cls, repo, path, resolve, reference, force, logmsg=None): + @ classmethod + def _create(cls: Type[T_References], repo: 'Repo', path: PathLike, resolve: bool, + reference: Union[str, 'SymbolicReference'], + force: bool, logmsg: Union[str, None] = None) -> T_References: """internal method used to create a new symbolic reference. If resolve is False, the reference will be taken as is, creating a proper symbolic reference. Otherwise it will be resolved to the @@ -502,14 +525,14 @@ def _create(cls, repo, path, resolve, reference, force, logmsg=None): instead""" git_dir = _git_dir(repo, path) full_ref_path = cls.to_full_path(path) - abs_ref_path = osp.join(git_dir, full_ref_path) + abs_ref_path = os.path.join(git_dir, full_ref_path) # figure out target data target = reference if resolve: target = repo.rev_parse(str(reference)) - if not force and osp.isfile(abs_ref_path): + if not force and os.path.isfile(abs_ref_path): target_data = str(target) if isinstance(target, SymbolicReference): target_data = target.path @@ -527,8 +550,9 @@ def _create(cls, repo, path, resolve, reference, force, logmsg=None): return ref @classmethod - def create(cls, repo: 'Repo', path: PathLike, reference: Union[Commit_ish, str] = 'HEAD', - logmsg: Union[str, None] = None, force: bool = False, **kwargs: Any): + def create(cls: Type[T_References], repo: 'Repo', path: PathLike, + reference: Union[str, 'SymbolicReference'] = 'SymbolicReference', + logmsg: Union[str, None] = None, force: bool = False, **kwargs: Any) -> T_References: """Create a new symbolic reference, hence a reference pointing , to another reference. :param repo: @@ -540,7 +564,7 @@ def create(cls, repo: 'Repo', path: PathLike, reference: Union[Commit_ish, str] :param reference: The reference to which the new symbolic reference should point to. - If it is a commit'ish, the symbolic ref will be detached. + If it is a ref to a commit'ish, the symbolic ref will be detached. :param force: if True, force creation even if a symbolic reference with that name already exists. @@ -559,7 +583,7 @@ def create(cls, repo: 'Repo', path: PathLike, reference: Union[Commit_ish, str] :note: This does not alter the current HEAD, index or Working Tree""" return cls._create(repo, path, cls._resolve_ref_on_create, reference, force, logmsg) - def rename(self, new_path, force=False): + def rename(self, new_path: str, force: bool = False) -> 'SymbolicReference': """Rename self to a new path :param new_path: @@ -577,9 +601,9 @@ def rename(self, new_path, force=False): if self.path == new_path: return self - new_abs_path = osp.join(_git_dir(self.repo, new_path), new_path) - cur_abs_path = osp.join(_git_dir(self.repo, self.path), self.path) - if osp.isfile(new_abs_path): + new_abs_path = os.path.join(_git_dir(self.repo, new_path), new_path) + cur_abs_path = os.path.join(_git_dir(self.repo, self.path), self.path) + if os.path.isfile(new_abs_path): if not force: # if they point to the same file, its not an error with open(new_abs_path, 'rb') as fd1: @@ -594,8 +618,8 @@ def rename(self, new_path, force=False): os.remove(new_abs_path) # END handle existing target file - dname = osp.dirname(new_abs_path) - if not osp.isdir(dname): + dname = os.path.dirname(new_abs_path) + if not os.path.isdir(dname): os.makedirs(dname) # END create directory @@ -630,7 +654,7 @@ def _iter_items(cls: Type[T_References], repo: 'Repo', common_path: Union[PathLi # read packed refs for _sha, rela_path in cls._iter_packed_refs(repo): - if rela_path.startswith(common_path): + if rela_path.startswith(str(common_path)): rela_paths.add(rela_path) # END relative path matches common path # END packed refs reading @@ -665,7 +689,7 @@ def iter_items(cls, repo: 'Repo', common_path: Union[PathLike, None] = None, *ar return (r for r in cls._iter_items(repo, common_path) if r.__class__ == SymbolicReference or not r.is_detached) @classmethod - def from_path(cls, repo, path): + def from_path(cls, repo: 'Repo', path: PathLike) -> Union['Head', 'RemoteReference', 'TagReference', 'Reference']: """ :param path: full .git-directory-relative path name to the Reference to instantiate :note: use to_full_path() if you only have a partial path of a known Reference Type From a5a05d153ecdbd9b9bdb285a77f5b14d9c0344b0 Mon Sep 17 00:00:00 2001 From: Dominic Date: Sat, 31 Jul 2021 13:50:39 +0100 Subject: [PATCH 5/5] rvrt symbolic.py types --- git/refs/symbolic.py | 172 +++++++++++++++++++------------------------ 1 file changed, 74 insertions(+), 98 deletions(-) diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 4171fe234..0e9dad5cc 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -1,3 +1,4 @@ +from git.types import PathLike import os from git.compat import defenc @@ -16,18 +17,17 @@ BadName ) -from .log import RefLog, RefLogEntry +import os.path as osp + +from .log import RefLog # typing ------------------------------------------------------------------ -from typing import Any, Iterator, List, Match, Optional, Tuple, Type, TypeVar, Union, TYPE_CHECKING, cast # NOQA +from typing import Any, Iterator, List, Match, Optional, Tuple, Type, TypeVar, Union, TYPE_CHECKING # NOQA from git.types import Commit_ish, PathLike, TBD, Literal # NOQA if TYPE_CHECKING: from git.repo import Repo - from git.refs import Reference, Head, TagReference, RemoteReference - from git.config import GitConfigParser - from git.objects.commit import Actor T_References = TypeVar('T_References', bound='SymbolicReference') @@ -37,9 +37,9 @@ __all__ = ["SymbolicReference"] -def _git_dir(repo: 'Repo', path: PathLike) -> PathLike: +def _git_dir(repo, path): """ Find the git dir that's appropriate for the path""" - name = f"{path}" + name = "%s" % (path,) if name in ['HEAD', 'ORIG_HEAD', 'FETCH_HEAD', 'index', 'logs']: return repo.git_dir return repo.common_dir @@ -59,47 +59,46 @@ class SymbolicReference(object): _remote_common_path_default = "refs/remotes" _id_attribute_ = "name" - def __init__(self, repo: 'Repo', path: PathLike, check_path: bool = False) -> None: + def __init__(self, repo: 'Repo', path: PathLike, check_path: bool = False): self.repo = repo self.path = str(path) - self.ref = self._get_reference() def __str__(self) -> str: return self.path - def __repr__(self) -> str: + def __repr__(self): return '' % (self.__class__.__name__, self.path) - def __eq__(self, other) -> bool: + def __eq__(self, other): if hasattr(other, 'path'): return self.path == other.path return False - def __ne__(self, other) -> bool: + def __ne__(self, other): return not (self == other) def __hash__(self): return hash(self.path) @property - def name(self) -> str: + def name(self): """ :return: In case of symbolic references, the shortest assumable name is the path itself.""" - return str(self.path) + return self.path @property - def abspath(self) -> PathLike: + def abspath(self): return join_path_native(_git_dir(self.repo, self.path), self.path) @classmethod - def _get_packed_refs_path(cls, repo: 'Repo') -> str: - return os.path.join(repo.common_dir, 'packed-refs') + def _get_packed_refs_path(cls, repo): + return osp.join(repo.common_dir, 'packed-refs') @classmethod - def _iter_packed_refs(cls, repo: 'Repo') -> Iterator[Tuple[str, str]]: - """Returns an iterator yielding pairs of sha1/path pairs for the corresponding refs. + def _iter_packed_refs(cls, repo): + """Returns an iterator yielding pairs of sha1/path pairs (as bytes) for the corresponding refs. :note: The packed refs file will be kept open as long as we iterate""" try: with open(cls._get_packed_refs_path(repo), 'rt', encoding='UTF-8') as fp: @@ -127,7 +126,7 @@ def _iter_packed_refs(cls, repo: 'Repo') -> Iterator[Tuple[str, str]]: if line[0] == '^': continue - yield cast(Tuple[str, str], tuple(line.split(' ', 1))) + yield tuple(line.split(' ', 1)) # END for each line except OSError: return None @@ -138,26 +137,26 @@ def _iter_packed_refs(cls, repo: 'Repo') -> Iterator[Tuple[str, str]]: # alright. @classmethod - def dereference_recursive(cls, repo: 'Repo', ref_path: PathLike) -> str: + def dereference_recursive(cls, repo, ref_path): """ :return: hexsha stored in the reference at the given ref_path, recursively dereferencing all intermediate references as required :param repo: the repository containing the reference at ref_path""" while True: - hexsha, _ref_path_out = cls._get_ref_info(repo, ref_path) + hexsha, ref_path = cls._get_ref_info(repo, ref_path) if hexsha is not None: return hexsha # END recursive dereferencing @classmethod - def _get_ref_info_helper(cls, repo: 'Repo', ref_path: PathLike) -> Union[Tuple[str, None], Tuple[None, PathLike]]: + def _get_ref_info_helper(cls, repo, ref_path): """Return: (str(sha), str(target_ref_path)) if available, the sha the file at rela_path points to, or None. target_ref_path is the reference we point to, or None""" - tokens: Union[List[str], Tuple[str, str], None] = None + tokens = None repodir = _git_dir(repo, ref_path) try: - with open(os.path.join(repodir, ref_path), 'rt', encoding='UTF-8') as fp: + with open(osp.join(repodir, 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 @@ -189,14 +188,13 @@ def _get_ref_info_helper(cls, repo: 'Repo', ref_path: PathLike) -> Union[Tuple[s raise ValueError("Failed to parse reference information from %r" % ref_path) @classmethod - def _get_ref_info(cls, repo: 'Repo', ref_path: PathLike - ) -> Union[Tuple[str, None], Tuple[None, PathLike]]: + def _get_ref_info(cls, repo, ref_path): """Return: (str(sha), str(target_ref_path)) if available, the sha the file at rela_path points to, or None. target_ref_path is the reference we point to, or None""" return cls._get_ref_info_helper(repo, ref_path) - def _get_object(self) -> Commit_ish: + def _get_object(self): """ :return: The object our ref currently refers to. Refs can be cached, they will @@ -205,7 +203,7 @@ def _get_object(self) -> Commit_ish: # Our path will be resolved to the hexsha which will be used accordingly return Object.new_from_sha(self.repo, hex_to_bin(self.dereference_recursive(self.repo, self.path))) - def _get_commit(self) -> 'Commit': + def _get_commit(self): """ :return: Commit object we point to, works for detached and non-detached @@ -220,8 +218,7 @@ def _get_commit(self) -> 'Commit': # END handle type return obj - def set_commit(self, commit: Union[Commit, 'SymbolicReference', str], - logmsg: Union[str, None] = None) -> None: + def set_commit(self, commit: Union[Commit, 'SymbolicReference', str], logmsg=None): """As set_object, but restricts the type of object to be a Commit :raise ValueError: If commit is not a Commit object or doesn't point to @@ -231,13 +228,11 @@ def set_commit(self, commit: Union[Commit, 'SymbolicReference', str], invalid_type = False if isinstance(commit, Object): invalid_type = commit.type != Commit.type - commit = cast('Commit', commit) elif isinstance(commit, SymbolicReference): invalid_type = commit.object.type != Commit.type else: try: - commit = self.repo.rev_parse(commit) - invalid_type = commit.type != Commit.type + invalid_type = self.repo.rev_parse(commit).type != Commit.type except (BadObject, BadName) as e: raise ValueError("Invalid object: %s" % commit) from e # END handle exception @@ -250,12 +245,9 @@ def set_commit(self, commit: Union[Commit, 'SymbolicReference', str], # we leave strings to the rev-parse method below self.set_object(commit, logmsg) - # return self - return None + return self - def set_object(self, object: Union[Commit_ish, 'SymbolicReference'], - logmsg: Union[str, None] = None - ) -> 'SymbolicReference': # @ReservedAssignment + def set_object(self, object, logmsg=None): # @ReservedAssignment """Set the object we point to, possibly dereference our symbolic reference first. If the reference does not exist, it will be created @@ -282,11 +274,10 @@ def set_object(self, object: Union[Commit_ish, 'SymbolicReference'], # set the commit on our reference return self._get_reference().set_object(object, logmsg) - commit = cast('Commit', property(_get_commit, set_commit, doc="Query or set commits directly")) - object = property(_get_object, set_object, doc="Return the object our ref currently refers to") # type: ignore + commit = property(_get_commit, set_commit, doc="Query or set commits directly") + object = property(_get_object, set_object, doc="Return the object our ref currently refers to") - def _get_reference(self - ) -> Union['Head', 'RemoteReference', 'TagReference', 'Reference']: + def _get_reference(self): """:return: Reference Object we point to :raise TypeError: If this symbolic reference is detached, hence it doesn't point to a reference, but to a commit""" @@ -295,8 +286,7 @@ def _get_reference(self raise TypeError("%s is a detached symbolic reference as it points to %r" % (self, sha)) return self.from_path(self.repo, target_ref_path) - def set_reference(self, ref: Union[str, Commit_ish, 'SymbolicReference'], logmsg: Union[str, None] = None - ) -> 'SymbolicReference': + def set_reference(self, ref, logmsg=None): """Set ourselves to the given ref. It will stay a symbol if the ref is a Reference. Otherwise an Object, given as Object instance or refspec, is assumed and if valid, will be set which effectively detaches the refererence if it was a purely @@ -337,7 +327,7 @@ def set_reference(self, ref: Union[str, Commit_ish, 'SymbolicReference'], logmsg raise TypeError("Require commit, got %r" % obj) # END verify type - oldbinsha: bytes = b'' + oldbinsha = None if logmsg is not None: try: oldbinsha = self.commit.binsha @@ -365,16 +355,11 @@ def set_reference(self, ref: Union[str, Commit_ish, 'SymbolicReference'], logmsg return self - @ property - def reference(self) -> Union['Head', 'RemoteReference', 'TagReference', 'Reference']: - return self._get_reference() + # aliased reference + reference = property(_get_reference, set_reference, doc="Returns the Reference we point to") + ref: Union[Commit_ish] = reference # type: ignore # Union[str, Commit_ish, SymbolicReference] - @ reference.setter - def reference(self, ref: Union[str, Commit_ish, 'SymbolicReference'], logmsg: Union[str, None] = None - ) -> 'SymbolicReference': - return self.set_reference(ref=ref, logmsg=logmsg) - - def is_valid(self) -> bool: + def is_valid(self): """ :return: True if the reference is valid, hence it can be read and points to @@ -386,7 +371,7 @@ def is_valid(self) -> bool: else: return True - @ property + @property def is_detached(self): """ :return: @@ -398,7 +383,7 @@ def is_detached(self): except TypeError: return True - def log(self) -> 'RefLog': + def log(self): """ :return: RefLog for this reference. Its last entry reflects the latest change applied to this reference @@ -407,8 +392,7 @@ def log(self) -> 'RefLog': instead of calling this method repeatedly. It should be considered read-only.""" return RefLog.from_file(RefLog.path(self)) - def log_append(self, oldbinsha: bytes, message: Union[str, None], - newbinsha: Union[bytes, None] = None) -> 'RefLogEntry': + def log_append(self, oldbinsha, message, newbinsha=None): """Append a logentry to the logfile of this ref :param oldbinsha: binary sha this ref used to point to @@ -420,19 +404,15 @@ def log_append(self, oldbinsha: bytes, message: Union[str, None], # correct to allow overriding the committer on a per-commit level. # See https://github.com/gitpython-developers/GitPython/pull/146 try: - committer_or_reader: Union['Actor', 'GitConfigParser'] = self.commit.committer + committer_or_reader = self.commit.committer except ValueError: committer_or_reader = self.repo.config_reader() # end handle newly cloned repositories - if newbinsha is None: - newbinsha = self.commit.binsha - - if message is None: - message = '' + return RefLog.append_entry(committer_or_reader, RefLog.path(self), oldbinsha, + (newbinsha is None and self.commit.binsha) or newbinsha, + message) - return RefLog.append_entry(committer_or_reader, RefLog.path(self), oldbinsha, newbinsha, message) - - def log_entry(self, index: int) -> RefLogEntry: + def log_entry(self, index): """:return: RefLogEntry at the given index :param index: python list compatible positive or negative index @@ -441,23 +421,22 @@ def log_entry(self, index: int) -> RefLogEntry: In that case, it will be faster than the ``log()`` method""" return RefLog.entry_at(RefLog.path(self), index) - @ classmethod - def to_full_path(cls, path: Union[PathLike, 'SymbolicReference']) -> str: + @classmethod + def to_full_path(cls, path) -> PathLike: """ :return: string with a full repository-relative path which can be used to initialize a Reference instance, for instance by using ``Reference.from_path``""" if isinstance(path, SymbolicReference): path = path.path - full_ref_path = str(path) + full_ref_path = path if not cls._common_path_default: return full_ref_path - - if not str(path).startswith(cls._common_path_default + "/"): + if not path.startswith(cls._common_path_default + "/"): full_ref_path = '%s/%s' % (cls._common_path_default, path) return full_ref_path - @ classmethod - def delete(cls, repo: 'Repo', path: PathLike) -> None: + @classmethod + def delete(cls, repo, path): """Delete the reference at the given path :param repo: @@ -468,8 +447,8 @@ def delete(cls, repo: 'Repo', path: PathLike) -> None: or just "myreference", hence 'refs/' is implied. Alternatively the symbolic reference to be deleted""" full_ref_path = cls.to_full_path(path) - abs_path = os.path.join(repo.common_dir, full_ref_path) - if os.path.exists(abs_path): + abs_path = osp.join(repo.common_dir, full_ref_path) + if osp.exists(abs_path): os.remove(abs_path) else: # check packed refs @@ -479,8 +458,8 @@ def delete(cls, repo: 'Repo', path: PathLike) -> None: new_lines = [] made_change = False dropped_last_line = False - for line_bytes in reader: - line = line_bytes.decode(defenc) + for line in reader: + line = line.decode(defenc) _, _, line_ref = line.partition(' ') line_ref = line_ref.strip() # keep line if it is a comment or if the ref to delete is not @@ -510,14 +489,12 @@ def delete(cls, repo: 'Repo', path: PathLike) -> None: # delete the reflog reflog_path = RefLog.path(cls(repo, full_ref_path)) - if os.path.isfile(reflog_path): + if osp.isfile(reflog_path): os.remove(reflog_path) # END remove reflog - @ classmethod - def _create(cls: Type[T_References], repo: 'Repo', path: PathLike, resolve: bool, - reference: Union[str, 'SymbolicReference'], - force: bool, logmsg: Union[str, None] = None) -> T_References: + @classmethod + def _create(cls, repo, path, resolve, reference, force, logmsg=None): """internal method used to create a new symbolic reference. If resolve is False, the reference will be taken as is, creating a proper symbolic reference. Otherwise it will be resolved to the @@ -525,14 +502,14 @@ def _create(cls: Type[T_References], repo: 'Repo', path: PathLike, resolve: bool instead""" git_dir = _git_dir(repo, path) full_ref_path = cls.to_full_path(path) - abs_ref_path = os.path.join(git_dir, full_ref_path) + abs_ref_path = osp.join(git_dir, full_ref_path) # figure out target data target = reference if resolve: target = repo.rev_parse(str(reference)) - if not force and os.path.isfile(abs_ref_path): + if not force and osp.isfile(abs_ref_path): target_data = str(target) if isinstance(target, SymbolicReference): target_data = target.path @@ -550,9 +527,8 @@ def _create(cls: Type[T_References], repo: 'Repo', path: PathLike, resolve: bool return ref @classmethod - def create(cls: Type[T_References], repo: 'Repo', path: PathLike, - reference: Union[str, 'SymbolicReference'] = 'SymbolicReference', - logmsg: Union[str, None] = None, force: bool = False, **kwargs: Any) -> T_References: + def create(cls, repo: 'Repo', path: PathLike, reference: Union[Commit_ish, str] = 'HEAD', + logmsg: Union[str, None] = None, force: bool = False, **kwargs: Any): """Create a new symbolic reference, hence a reference pointing , to another reference. :param repo: @@ -564,7 +540,7 @@ def create(cls: Type[T_References], repo: 'Repo', path: PathLike, :param reference: The reference to which the new symbolic reference should point to. - If it is a ref to a commit'ish, the symbolic ref will be detached. + If it is a commit'ish, the symbolic ref will be detached. :param force: if True, force creation even if a symbolic reference with that name already exists. @@ -583,7 +559,7 @@ def create(cls: Type[T_References], repo: 'Repo', path: PathLike, :note: This does not alter the current HEAD, index or Working Tree""" return cls._create(repo, path, cls._resolve_ref_on_create, reference, force, logmsg) - def rename(self, new_path: str, force: bool = False) -> 'SymbolicReference': + def rename(self, new_path, force=False): """Rename self to a new path :param new_path: @@ -601,9 +577,9 @@ def rename(self, new_path: str, force: bool = False) -> 'SymbolicReference': if self.path == new_path: return self - new_abs_path = os.path.join(_git_dir(self.repo, new_path), new_path) - cur_abs_path = os.path.join(_git_dir(self.repo, self.path), self.path) - if os.path.isfile(new_abs_path): + new_abs_path = osp.join(_git_dir(self.repo, new_path), new_path) + cur_abs_path = osp.join(_git_dir(self.repo, self.path), self.path) + if osp.isfile(new_abs_path): if not force: # if they point to the same file, its not an error with open(new_abs_path, 'rb') as fd1: @@ -618,8 +594,8 @@ def rename(self, new_path: str, force: bool = False) -> 'SymbolicReference': os.remove(new_abs_path) # END handle existing target file - dname = os.path.dirname(new_abs_path) - if not os.path.isdir(dname): + dname = osp.dirname(new_abs_path) + if not osp.isdir(dname): os.makedirs(dname) # END create directory @@ -654,7 +630,7 @@ def _iter_items(cls: Type[T_References], repo: 'Repo', common_path: Union[PathLi # read packed refs for _sha, rela_path in cls._iter_packed_refs(repo): - if rela_path.startswith(str(common_path)): + if rela_path.startswith(common_path): rela_paths.add(rela_path) # END relative path matches common path # END packed refs reading @@ -689,7 +665,7 @@ def iter_items(cls, repo: 'Repo', common_path: Union[PathLike, None] = None, *ar return (r for r in cls._iter_items(repo, common_path) if r.__class__ == SymbolicReference or not r.is_detached) @classmethod - def from_path(cls, repo: 'Repo', path: PathLike) -> Union['Head', 'RemoteReference', 'TagReference', 'Reference']: + def from_path(cls, repo, path): """ :param path: full .git-directory-relative path name to the Reference to instantiate :note: use to_full_path() if you only have a partial path of a known Reference Type pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy