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 ""
|
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:
|
def mirror_push(repo: Path, remote: str) -> None:
|
||||||
"""Push the full mirror to a remote.
|
"""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*.
|
"""Check whether a submodule is registered at *path*.
|
||||||
|
|
||||||
Reads ``.gitmodules`` to determine whether the submodule exists.
|
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.
|
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():
|
if not gitmodules.is_file():
|
||||||
return False
|
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:
|
try:
|
||||||
result = _run(
|
result = _run(
|
||||||
["config", "--file", ".gitmodules",
|
["config", "--file", str(gitmodules),
|
||||||
"--get-regexp", r"submodule\..*\.path"],
|
"--get-regexp", r"submodule\..*\.path"],
|
||||||
cwd=repo,
|
cwd=toplevel,
|
||||||
)
|
)
|
||||||
except GitError:
|
except GitError:
|
||||||
return False
|
return False
|
||||||
for line in result.stdout.splitlines():
|
for line in result.stdout.splitlines():
|
||||||
parts = line.split(None, 1)
|
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 True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
@ -306,3 +335,11 @@ def submodule_update(repo: Path, path: str) -> None:
|
||||||
default_branch = result.stdout.strip()
|
default_branch = result.stdout.strip()
|
||||||
_run(["checkout", default_branch], cwd=sub_path)
|
_run(["checkout", default_branch], cwd=sub_path)
|
||||||
logger.info("Updated submodule %s to %s", path, default_branch)
|
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