| |
| |
|
|
| __all__ = [ |
| "sm_section", |
| "sm_name", |
| "mkhead", |
| "find_first_remote_branch", |
| "SubmoduleConfigParser", |
| ] |
|
|
| from io import BytesIO |
| import weakref |
|
|
| import git |
| from git.config import GitConfigParser |
| from git.exc import InvalidGitRepositoryError |
|
|
| |
|
|
| from typing import Any, Sequence, TYPE_CHECKING, Union |
|
|
| from git.types import PathLike |
|
|
| if TYPE_CHECKING: |
| from weakref import ReferenceType |
|
|
| from git.refs import Head, RemoteReference |
| from git.remote import Remote |
| from git.repo import Repo |
|
|
| from .base import Submodule |
|
|
| |
|
|
|
|
| def sm_section(name: str) -> str: |
| """:return: Section title used in ``.gitmodules`` configuration file""" |
| return f'submodule "{name}"' |
|
|
|
|
| def sm_name(section: str) -> str: |
| """:return: Name of the submodule as parsed from the section name""" |
| section = section.strip() |
| return section[11:-1] |
|
|
|
|
| def mkhead(repo: "Repo", path: PathLike) -> "Head": |
| """:return: New branch/head instance""" |
| return git.Head(repo, git.Head.to_full_path(path)) |
|
|
|
|
| def find_first_remote_branch(remotes: Sequence["Remote"], branch_name: str) -> "RemoteReference": |
| """Find the remote branch matching the name of the given branch or raise |
| :exc:`~git.exc.InvalidGitRepositoryError`.""" |
| for remote in remotes: |
| try: |
| return remote.refs[branch_name] |
| except IndexError: |
| continue |
| |
| |
| raise InvalidGitRepositoryError("Didn't find remote branch '%r' in any of the given remotes" % branch_name) |
|
|
|
|
| |
|
|
| |
|
|
|
|
| class SubmoduleConfigParser(GitConfigParser): |
| """Catches calls to :meth:`~git.config.GitConfigParser.write`, and updates the |
| ``.gitmodules`` blob in the index with the new data, if we have written into a |
| stream. |
| |
| Otherwise it would add the local file to the index to make it correspond with the |
| working tree. Additionally, the cache must be cleared. |
| |
| Please note that no mutating method will work in bare mode. |
| """ |
|
|
| def __init__(self, *args: Any, **kwargs: Any) -> None: |
| self._smref: Union["ReferenceType[Submodule]", None] = None |
| self._index = None |
| self._auto_write = True |
| super().__init__(*args, **kwargs) |
|
|
| |
| def set_submodule(self, submodule: "Submodule") -> None: |
| """Set this instance's submodule. It must be called before the first write |
| operation begins.""" |
| self._smref = weakref.ref(submodule) |
|
|
| def flush_to_index(self) -> None: |
| """Flush changes in our configuration file to the index.""" |
| assert self._smref is not None |
| |
| assert not isinstance(self._file_or_files, BytesIO) |
|
|
| sm = self._smref() |
| if sm is not None: |
| index = self._index |
| if index is None: |
| index = sm.repo.index |
| |
| index.add([sm.k_modules_file], write=self._auto_write) |
| sm._clear_cache() |
| |
|
|
| |
|
|
| |
| def write(self) -> None: |
| rval: None = super().write() |
| self.flush_to_index() |
| return rval |
|
|
| |
|
|
|
|
| |
|
|