Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit adfbeaa

Browse filesBrowse files
committed
Add fetch_url and push_url to GitRemoteCmd
1 parent 5b47018 commit adfbeaa
Copy full SHA for adfbeaa

File tree

Expand file treeCollapse file tree

1 file changed

+88
-11
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+88
-11
lines changed

‎src/libvcs/cmd/git.py

Copy file name to clipboardExpand all lines: src/libvcs/cmd/git.py
+88-11Lines changed: 88 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import datetime
66
import pathlib
7+
import re
78
import shlex
89
import typing as t
910
from collections.abc import Sequence
@@ -2361,12 +2362,16 @@ class GitRemoteCmd:
23612362
"""Run commands directly for a git remote on a git repository."""
23622363

23632364
remote_name: str
2365+
fetch_url: str | None
2366+
push_url: str | None
23642367

23652368
def __init__(
23662369
self,
23672370
*,
23682371
path: StrPath,
23692372
remote_name: str,
2373+
fetch_url: str | None = None,
2374+
push_url: str | None = None,
23702375
cmd: Git | None = None,
23712376
) -> None:
23722377
r"""Lite, typed, pythonic wrapper for git-remote(1).
@@ -2408,6 +2413,8 @@ def __init__(
24082413
self.cmd = cmd if isinstance(cmd, Git) else Git(path=self.path)
24092414

24102415
self.remote_name = remote_name
2416+
self.fetch_url = fetch_url
2417+
self.push_url = push_url
24112418

24122419
def __repr__(self) -> str:
24132420
"""Representation of a git remote for a git repository."""
@@ -2731,6 +2738,24 @@ def set_url(
27312738
)
27322739

27332740

2741+
GitRemoteManagerLiteral = Literal[
2742+
"--verbose",
2743+
"add",
2744+
"rename",
2745+
"remove",
2746+
"set-branches",
2747+
"set-head",
2748+
"set-branch",
2749+
"get-url",
2750+
"set-url",
2751+
"set-url --add",
2752+
"set-url --delete",
2753+
"prune",
2754+
"show",
2755+
"update",
2756+
]
2757+
2758+
27342759
class GitRemoteManager:
27352760
"""Run commands directly related to git remotes of a git repo."""
27362761

@@ -2777,7 +2802,7 @@ def __repr__(self) -> str:
27772802

27782803
def run(
27792804
self,
2780-
command: GitRemoteCommandLiteral | None = None,
2805+
command: GitRemoteManagerLiteral | None = None,
27812806
local_flags: list[str] | None = None,
27822807
*,
27832808
# Pass-through to run()
@@ -2860,6 +2885,16 @@ def show(
28602885
--------
28612886
>>> GitRemoteManager(path=example_git_repo.path).show()
28622887
'origin'
2888+
2889+
For the example below, add a remote:
2890+
>>> GitRemoteManager(path=example_git_repo.path).add(
2891+
... name='my_remote', url=f'file:///dev/null'
2892+
... )
2893+
''
2894+
2895+
Retrieve a list of remote names:
2896+
>>> GitRemoteManager(path=example_git_repo.path).show().splitlines()
2897+
['my_remote', 'origin']
28632898
"""
28642899
local_flags: list[str] = []
28652900
required_flags: list[str] = []
@@ -2880,17 +2915,17 @@ def show(
28802915
log_in_real_time=log_in_real_time,
28812916
)
28822917

2883-
def _ls(self) -> list[str]:
2884-
"""List remotes.
2918+
def _ls(self) -> str:
2919+
r"""List remotes (raw output).
28852920
28862921
Examples
28872922
--------
28882923
>>> GitRemoteManager(path=example_git_repo.path)._ls()
2889-
['origin']
2924+
'origin\tfile:///... (fetch)\norigin\tfile:///... (push)'
28902925
"""
28912926
return self.run(
2892-
"show",
2893-
).splitlines()
2927+
"--verbose",
2928+
)
28942929

28952930
def ls(self) -> QueryList[GitRemoteCmd]:
28962931
"""List remotes.
@@ -2899,14 +2934,56 @@ def ls(self) -> QueryList[GitRemoteCmd]:
28992934
--------
29002935
>>> GitRemoteManager(path=example_git_repo.path).ls()
29012936
[<GitRemoteCmd path=... remote_name=origin>]
2937+
2938+
For the example below, add a remote:
2939+
>>> GitRemoteManager(path=example_git_repo.path).add(
2940+
... name='my_remote', url=f'file:///dev/null'
2941+
... )
2942+
''
2943+
2944+
>>> GitRemoteManager(path=example_git_repo.path).ls()
2945+
[<GitRemoteCmd path=... remote_name=my_remote>,
2946+
<GitRemoteCmd path=... remote_name=origin>]
29022947
"""
2903-
return QueryList(
2904-
[
2905-
GitRemoteCmd(path=self.path, remote_name=remote_name.lstrip("* "))
2906-
for remote_name in self._ls()
2907-
],
2948+
remote_str = self._ls()
2949+
remote_pattern = re.compile(
2950+
r"""
2951+
(?P<name>\S+) # Remote name: one or more non-whitespace characters
2952+
\s+ # One or more whitespace characters
2953+
(?P<url>\S+) # URL: one or more non-whitespace characters
2954+
\s+ # One or more whitespace characters
2955+
\((?P<cmd_type>fetch|push)\) # 'fetch' or 'push' in parentheses
2956+
""",
2957+
re.VERBOSE | re.MULTILINE,
29082958
)
29092959

2960+
remotes: dict[str, dict[str, str | None]] = {}
2961+
2962+
for match_obj in remote_pattern.finditer(remote_str):
2963+
name = match_obj.group("name")
2964+
url = match_obj.group("url")
2965+
cmd_type = match_obj.group("cmd_type")
2966+
2967+
if name not in remotes:
2968+
remotes[name] = {}
2969+
2970+
remotes[name][cmd_type] = url
2971+
2972+
remote_cmds: list[GitRemoteCmd] = []
2973+
for name, urls in remotes.items():
2974+
fetch_url = urls.get("fetch")
2975+
push_url = urls.get("push")
2976+
remote_cmds.append(
2977+
GitRemoteCmd(
2978+
path=self.path,
2979+
remote_name=name,
2980+
fetch_url=fetch_url,
2981+
push_url=push_url,
2982+
)
2983+
)
2984+
2985+
return QueryList(remote_cmds)
2986+
29102987
def get(self, *args: t.Any, **kwargs: t.Any) -> GitRemoteCmd | None:
29112988
"""Get remote via filter lookup.
29122989

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.