| | |
| | |
| |
|
| | __all__ = ["Reference"] |
| |
|
| | from git.util import IterableObj, LazyMixin |
| |
|
| | from .symbolic import SymbolicReference, T_References |
| |
|
| | |
| |
|
| | from typing import Any, Callable, Iterator, TYPE_CHECKING, Type, Union |
| |
|
| | from git.types import AnyGitObject, PathLike, _T |
| |
|
| | if TYPE_CHECKING: |
| | from git.repo import Repo |
| |
|
| | |
| |
|
| | |
| |
|
| |
|
| | def require_remote_ref_path(func: Callable[..., _T]) -> Callable[..., _T]: |
| | """A decorator raising :exc:`ValueError` if we are not a valid remote, based on the |
| | path.""" |
| |
|
| | def wrapper(self: T_References, *args: Any) -> _T: |
| | if not self.is_remote(): |
| | raise ValueError("ref path does not point to a remote reference: %s" % self.path) |
| | return func(self, *args) |
| |
|
| | |
| | wrapper.__name__ = func.__name__ |
| | return wrapper |
| |
|
| |
|
| | |
| |
|
| |
|
| | class Reference(SymbolicReference, LazyMixin, IterableObj): |
| | """A named reference to any object. |
| | |
| | Subclasses may apply restrictions though, e.g., a :class:`~git.refs.head.Head` can |
| | only point to commits. |
| | """ |
| |
|
| | __slots__ = () |
| |
|
| | _points_to_commits_only = False |
| | _resolve_ref_on_create = True |
| | _common_path_default = "refs" |
| |
|
| | def __init__(self, repo: "Repo", path: PathLike, check_path: bool = True) -> None: |
| | """Initialize this instance. |
| | |
| | :param repo: |
| | Our parent repository. |
| | |
| | :param path: |
| | Path relative to the ``.git/`` directory pointing to the ref in question, |
| | e.g. ``refs/heads/master``. |
| | |
| | :param check_path: |
| | 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 |
| | super().__init__(repo, path) |
| |
|
| | def __str__(self) -> str: |
| | return self.name |
| |
|
| | |
| |
|
| | |
| | def set_object( |
| | self, |
| | object: Union[AnyGitObject, "SymbolicReference", str], |
| | logmsg: Union[str, None] = None, |
| | ) -> "Reference": |
| | """Special version which checks if the head-log needs an update as well. |
| | |
| | :return: |
| | self |
| | """ |
| | oldbinsha = None |
| | if logmsg is not None: |
| | head = self.repo.head |
| | if not head.is_detached and head.ref == self: |
| | oldbinsha = self.commit.binsha |
| | |
| | |
| |
|
| | super().set_object(object, logmsg) |
| |
|
| | if oldbinsha is not None: |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | self.repo.head.log_append(oldbinsha, logmsg) |
| | |
| |
|
| | return self |
| |
|
| | |
| |
|
| | @property |
| | def name(self) -> str: |
| | """ |
| | :return: |
| | (shortest) Name of this reference - it may contain path components |
| | """ |
| | |
| | |
| | tokens = self.path.split("/") |
| | if len(tokens) < 3: |
| | return self.path |
| | return "/".join(tokens[2:]) |
| |
|
| | @classmethod |
| | def iter_items( |
| | cls: Type[T_References], |
| | repo: "Repo", |
| | common_path: Union[PathLike, None] = None, |
| | *args: Any, |
| | **kwargs: Any, |
| | ) -> Iterator[T_References]: |
| | """Equivalent to |
| | :meth:`SymbolicReference.iter_items <git.refs.symbolic.SymbolicReference.iter_items>`, |
| | but will return non-detached references as well.""" |
| | return cls._iter_items(repo, common_path) |
| |
|
| | |
| |
|
| | |
| |
|
| | @property |
| | @require_remote_ref_path |
| | def remote_name(self) -> str: |
| | """ |
| | :return: |
| | Name of the remote we are a reference of, such as ``origin`` for a reference |
| | named ``origin/master``. |
| | """ |
| | tokens = self.path.split("/") |
| | |
| | return tokens[2] |
| |
|
| | @property |
| | @require_remote_ref_path |
| | def remote_head(self) -> str: |
| | """ |
| | :return: |
| | Name of the remote head itself, e.g. ``master``. |
| | |
| | :note: |
| | The returned name is usually not qualified enough to uniquely identify a |
| | branch. |
| | """ |
| | tokens = self.path.split("/") |
| | return "/".join(tokens[3:]) |
| |
|
| | |
| |
|