feat(git): submodule and remote handling
This commit is contained in:
parent
5bf4a7eee4
commit
c4fb29f694
1 changed files with 41 additions and 4 deletions
|
|
@ -146,6 +146,18 @@ def show_ref(repo: Path) -> str:
|
|||
return ""
|
||||
|
||||
|
||||
def ls_remote(repo: Path, remote: str) -> str:
|
||||
"""Return the raw output of ``git ls-remote <remote>``.
|
||||
|
||||
Returns an empty string if the remote has no refs or on error.
|
||||
"""
|
||||
try:
|
||||
result = _run(["ls-remote", remote], cwd=repo)
|
||||
return result.stdout
|
||||
except GitError:
|
||||
return ""
|
||||
|
||||
|
||||
def mirror_push(repo: Path, remote: str) -> None:
|
||||
"""Push the full mirror to a remote.
|
||||
|
||||
|
|
@ -260,22 +272,39 @@ def has_submodule(repo: Path, path: str) -> bool:
|
|||
"""Check whether a submodule is registered at *path*.
|
||||
|
||||
Reads ``.gitmodules`` to determine whether the submodule exists.
|
||||
*path* is resolved relative to *repo*, then compared against
|
||||
the repository root so the check works when *repo* is a
|
||||
subdirectory of the actual git working tree.
|
||||
Returns False if ``.gitmodules`` does not exist.
|
||||
"""
|
||||
gitmodules = repo / ".gitmodules"
|
||||
try:
|
||||
toplevel = Path(
|
||||
_run(
|
||||
["rev-parse", "--show-toplevel"], cwd=repo,
|
||||
).stdout.strip()
|
||||
)
|
||||
except GitError:
|
||||
return False
|
||||
gitmodules = toplevel / ".gitmodules"
|
||||
if not gitmodules.is_file():
|
||||
return False
|
||||
# Resolve the full path relative to the repo root
|
||||
full_path = (repo / path).resolve()
|
||||
try:
|
||||
rel_path = str(full_path.relative_to(toplevel.resolve()))
|
||||
except ValueError:
|
||||
return False
|
||||
try:
|
||||
result = _run(
|
||||
["config", "--file", ".gitmodules",
|
||||
["config", "--file", str(gitmodules),
|
||||
"--get-regexp", r"submodule\..*\.path"],
|
||||
cwd=repo,
|
||||
cwd=toplevel,
|
||||
)
|
||||
except GitError:
|
||||
return False
|
||||
for line in result.stdout.splitlines():
|
||||
parts = line.split(None, 1)
|
||||
if len(parts) == 2 and parts[1] == path:
|
||||
if len(parts) == 2 and parts[1] == rel_path:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
|
@ -306,3 +335,11 @@ def submodule_update(repo: Path, path: str) -> None:
|
|||
default_branch = result.stdout.strip()
|
||||
_run(["checkout", default_branch], cwd=sub_path)
|
||||
logger.info("Updated submodule %s to %s", path, default_branch)
|
||||
|
||||
|
||||
def submodule_checkout(repo: Path, path: str, ref: str) -> None:
|
||||
"""Fetch and checkout a specific ref in a submodule."""
|
||||
sub_path = repo / path
|
||||
_run(["fetch", "origin"], cwd=sub_path)
|
||||
_run(["checkout", ref], cwd=sub_path)
|
||||
logger.info("Checked out submodule %s at %s", path, ref)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue