gitbolt 0.0.0.dev1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env python3
2
+ # coding=utf-8
3
+
4
+ """
5
+ Simple and direct implementations of git commands using subprocess calls.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from abc import ABC
11
+ from pathlib import Path
12
+ from typing import override
13
+
14
+ from vt.utils.commons.commons.op import RootDirOp
15
+
16
+ from gitbolt.add import AddArgsValidator
17
+ from gitbolt.git_subprocess import (
18
+ GitCommand,
19
+ VersionCommand,
20
+ LsTreeCommand,
21
+ GitSubcmdCommand,
22
+ AddCommand,
23
+ )
24
+ from gitbolt.git_subprocess.add import AddCLIArgsBuilder
25
+ from gitbolt.git_subprocess.constants import VERSION_CMD
26
+ from gitbolt.git_subprocess.ls_tree import LsTreeCLIArgsBuilder
27
+ from gitbolt.git_subprocess.runner import GitCommandRunner
28
+ from gitbolt.git_subprocess.runner.simple_impl import SimpleGitCR
29
+ from gitbolt.ls_tree import LsTreeArgsValidator
30
+
31
+
32
+ class GitSubcmdCommandImpl(GitSubcmdCommand, ABC):
33
+ def __init__(self, git: GitCommand):
34
+ self._underlying_git = git
35
+
36
+ @property
37
+ def underlying_git(self) -> GitCommand:
38
+ return self._underlying_git
39
+
40
+ def _set_underlying_git(self, git: "GitCommand") -> None:
41
+ self._underlying_git = git
42
+
43
+
44
+ class VersionCommandImpl(VersionCommand, GitSubcmdCommandImpl):
45
+ @override
46
+ def version(self, build_options: bool = False) -> str:
47
+ self._require_valid_args(build_options)
48
+ main_cmd_args = self.underlying_git.build_main_cmd_args()
49
+ sub_cmd_args = [VERSION_CMD]
50
+ if build_options:
51
+ sub_cmd_args.append("--build-options")
52
+ return self.underlying_git.runner.run_git_command(
53
+ main_cmd_args, sub_cmd_args, check=True, text=True, capture_output=True
54
+ ).stdout.strip()
55
+
56
+ def clone(self) -> "VersionCommandImpl":
57
+ return VersionCommandImpl(self.underlying_git)
58
+
59
+
60
+ class LsTreeCommandImpl(LsTreeCommand, GitSubcmdCommandImpl):
61
+ def __init__(
62
+ self,
63
+ git_root_dir: Path,
64
+ git: GitCommand,
65
+ *,
66
+ args_validator: LsTreeArgsValidator | None = None,
67
+ cli_args_builder: LsTreeCLIArgsBuilder | None = None,
68
+ ):
69
+ """
70
+ ``ls-tree`` cli command implementation using subprocess.
71
+
72
+ :param git_root_dir: Path to the Git repository root.
73
+ :param git: Underlying Git command interface.
74
+ :param args_validator: Optional custom argument validator. If None, uses the default from superclass.
75
+ :param cli_args_builder: Optional CLI args builder. If None, uses the default from superclass.
76
+ """
77
+ super().__init__(git)
78
+ self._git_root_dir = git_root_dir
79
+ self._args_validator = args_validator or super().args_validator
80
+ self._cli_args_builder = cli_args_builder or super().cli_args_builder
81
+
82
+ @override
83
+ @property
84
+ def root_dir(self) -> Path:
85
+ return self._git_root_dir
86
+
87
+ @override
88
+ @property
89
+ def args_validator(self) -> LsTreeArgsValidator:
90
+ return self._args_validator
91
+
92
+ @override
93
+ @property
94
+ def cli_args_builder(self) -> LsTreeCLIArgsBuilder:
95
+ return self._cli_args_builder
96
+
97
+ def clone(self) -> "LsTreeCommandImpl":
98
+ return LsTreeCommandImpl(self.root_dir, self.underlying_git)
99
+
100
+
101
+ class AddCommandImpl(AddCommand, GitSubcmdCommandImpl):
102
+ def __init__(
103
+ self,
104
+ root_dir: Path,
105
+ git: GitCommand,
106
+ *,
107
+ args_validator: AddArgsValidator | None = None,
108
+ cli_args_builder: AddCLIArgsBuilder | None = None,
109
+ ):
110
+ super().__init__(git)
111
+ self._root_dir = root_dir
112
+ self._args_validator = args_validator or super().args_validator
113
+ self._cli_args_builder = cli_args_builder or super().cli_args_builder
114
+
115
+ @override
116
+ @property
117
+ def root_dir(self) -> Path:
118
+ return self._root_dir
119
+
120
+ @override
121
+ @property
122
+ def args_validator(self) -> AddArgsValidator:
123
+ return self._args_validator
124
+
125
+ @override
126
+ @property
127
+ def cli_args_builder(self) -> AddCLIArgsBuilder:
128
+ return self._cli_args_builder
129
+
130
+ def clone(self) -> "AddCommandImpl":
131
+ return AddCommandImpl(self.root_dir, self.underlying_git)
132
+
133
+
134
+ class SimpleGitCommand(GitCommand, RootDirOp):
135
+ def __init__(
136
+ self,
137
+ git_root_dir: Path = Path.cwd(),
138
+ runner: GitCommandRunner = SimpleGitCR(),
139
+ *,
140
+ version_subcmd: VersionCommand | None = None,
141
+ ls_tree_subcmd: LsTreeCommand | None = None,
142
+ add_subcmd: AddCommand | None = None,
143
+ ):
144
+ super().__init__(runner)
145
+ self.git_root_dir = git_root_dir
146
+ self._version_subcmd = version_subcmd or VersionCommandImpl(self)
147
+ self._ls_tree = ls_tree_subcmd or LsTreeCommandImpl(self.root_dir, self)
148
+ self._add_subcmd = add_subcmd or AddCommandImpl(self.root_dir, self)
149
+
150
+ @override
151
+ @property
152
+ def version_subcmd(self) -> VersionCommand:
153
+ return self._version_subcmd
154
+
155
+ @override
156
+ @property
157
+ def ls_tree_subcmd(self) -> LsTreeCommand:
158
+ return self._ls_tree
159
+
160
+ @override
161
+ @property
162
+ def add_subcmd(self) -> AddCommand:
163
+ return self._add_subcmd
164
+
165
+ @override
166
+ def clone(self) -> "SimpleGitCommand":
167
+ # region obtain class instance
168
+ cloned = SimpleGitCommand(
169
+ self.root_dir,
170
+ self.runner,
171
+ version_subcmd=self.version_subcmd,
172
+ ls_tree_subcmd=self.ls_tree_subcmd,
173
+ add_subcmd=self.add_subcmd,
174
+ )
175
+ # endregion
176
+ # region clone protected members
177
+ cloned._main_cmd_opts = self._main_cmd_opts
178
+ cloned._env_vars = self._env_vars
179
+ # endregion
180
+ return cloned
181
+
182
+ @override
183
+ @property
184
+ def root_dir(self) -> Path:
185
+ return self.git_root_dir
@@ -0,0 +1,384 @@
1
+ #!/usr/bin/env python3
2
+ # coding=utf-8
3
+
4
+ """
5
+ Helper interfaces for ``git ls-tree`` subcommand with default implementation for subprocess calls.
6
+ """
7
+
8
+ from abc import abstractmethod
9
+ from typing import Protocol, Unpack, override
10
+
11
+ from gitbolt.git_subprocess.constants import LS_TREE_CMD
12
+ from gitbolt.models import GitLsTreeOpts
13
+
14
+
15
+ class LsTreeCLIArgsBuilder(Protocol):
16
+ """
17
+ Interface to facilitate building of cli arguments for ``git ls-tree`` subcommand.
18
+ """
19
+
20
+ @abstractmethod
21
+ def build(self, tree_ish: str, **ls_tree_opts: Unpack[GitLsTreeOpts]) -> list[str]:
22
+ """
23
+ Build the complete list of subcommand arguments to be passed to ``git ls-tree``.
24
+
25
+ This method assembles the subcommand portion of the git command invocation, such as
26
+ in ``git --no-pager ls-tree -r HEAD``, where ``-r HEAD`` is the subcommand argument list.
27
+
28
+ It delegates the formation of each argument to protected helper methods to allow
29
+ easier overriding and testing of individual components.
30
+
31
+ Includes support for:
32
+
33
+ - Boolean flags (e.g., -r, -t, --name-only)
34
+ - Optional key-value arguments (e.g., --abbrev=N, --format=FMT)
35
+ - Required tree-ish identifier
36
+ - Optional file path list
37
+
38
+ :param tree_ish: A tree-ish identifier (commit SHA, branch name, etc.).
39
+ :param ls_tree_opts: Keyword arguments mapping to supported options for ``git ls-tree``.
40
+ :return: Complete list of subcommand arguments.
41
+ :raises GitExitingException: if undesired argument type or argument combination is supplied.
42
+ """
43
+ ...
44
+
45
+
46
+ class IndividuallyOverridableLTCAB(LsTreeCLIArgsBuilder):
47
+ """
48
+ Individually Overridable Ls Tree CLI Args Builder.
49
+
50
+ Build CLI args to run ``git ls-tree`` subcommand in a subprocess. This class is independent in its working and
51
+ provides interface to individually override each arg former for fine-grained control.
52
+ """
53
+
54
+ @override
55
+ def build(self, tree_ish: str, **ls_tree_opts: Unpack[GitLsTreeOpts]) -> list[str]:
56
+ """
57
+ Build the full list of arguments to be passed to ``git ls-tree``.
58
+
59
+ This includes flags, optional arguments, tree-ish identifier, and optional paths.
60
+
61
+ >>> builder = IndividuallyOverridableLTCAB()
62
+
63
+ * Basic case: only tree-ish::
64
+
65
+ >>> builder.build("HEAD")
66
+ ['ls-tree', 'HEAD']
67
+
68
+ * With single boolean option::
69
+
70
+ >>> builder.build("HEAD", r=True)
71
+ ['ls-tree', '-r', 'HEAD']
72
+
73
+ * With multiple boolean flags::
74
+
75
+ >>> builder.build("HEAD", r=True, t=True, d=True)
76
+ ['ls-tree', '-d', '-r', '-t', 'HEAD']
77
+
78
+ * Long listing format::
79
+
80
+ >>> builder.build("HEAD", long=True)
81
+ ['ls-tree', '-l', 'HEAD']
82
+
83
+ * All common flags::
84
+
85
+ >>> builder.build("HEAD", r=True, t=True, long=True, z=True,
86
+ ... name_only=True, full_name=True, full_tree=True)
87
+ ['ls-tree', '-r', '-t', '-l', '-z', '--name-only', '--full-name', '--full-tree', 'HEAD']
88
+
89
+ * With --name-status::
90
+
91
+ >>> builder.build("HEAD", name_status=True)
92
+ ['ls-tree', '--name-status', 'HEAD']
93
+
94
+ * With --object-only::
95
+
96
+ >>> builder.build("HEAD", object_only=True)
97
+ ['ls-tree', '--object-only', 'HEAD']
98
+
99
+ * With --abbrev (edge cases)::
100
+
101
+ >>> builder.build("HEAD", abbrev=0)
102
+ ['ls-tree', '--abbrev=0', 'HEAD']
103
+ >>> builder.build("HEAD", abbrev=40)
104
+ ['ls-tree', '--abbrev=40', 'HEAD']
105
+ >>> builder.build("HEAD", abbrev=7)
106
+ ['ls-tree', '--abbrev=7', 'HEAD']
107
+
108
+ * With --format::
109
+
110
+ >>> builder.build("HEAD", format_="%(objectname)")
111
+ ['ls-tree', '--format=%(objectname)', 'HEAD']
112
+ >>> builder.build("HEAD", format_="")
113
+ ['ls-tree', '--format=', 'HEAD']
114
+
115
+ * With paths::
116
+
117
+ >>> builder.build("HEAD", path=["src", "README.md"])
118
+ ['ls-tree', 'HEAD', 'src', 'README.md']
119
+
120
+ * With flags and paths::
121
+
122
+ >>> builder.build("HEAD", r=True, path=["src/module.py"])
123
+ ['ls-tree', '-r', 'HEAD', 'src/module.py']
124
+
125
+ * All supported options::
126
+
127
+ >>> builder.build(
128
+ ... "HEAD",
129
+ ... d=True,
130
+ ... r=True,
131
+ ... t=True,
132
+ ... long=True,
133
+ ... z=True,
134
+ ... name_only=True,
135
+ ... name_status=False,
136
+ ... object_only=True,
137
+ ... full_name=True,
138
+ ... full_tree=True,
139
+ ... abbrev=10,
140
+ ... format_="%(objectname) %(path)",
141
+ ... path=["dir1", "dir2/file.txt"]
142
+ ... )
143
+ ['ls-tree', '-d', '-r', '-t', '-l', '-z', '--name-only', '--object-only', '--full-name', '--full-tree', '--abbrev=10', '--format=%(objectname) %(path)', 'HEAD', 'dir1', 'dir2/file.txt']
144
+
145
+ * Empty or falsy values, mostly will fail at validation::
146
+
147
+ >>> builder.build("HEAD", d=False,
148
+ ... abbrev=None, # type: ignore[arg-type] # expected int provided None
149
+ ... path=[],
150
+ ... format_=None) # type: ignore[arg-type] # expected str provided None
151
+ ['ls-tree', 'HEAD']
152
+ """
153
+ sub_cmd_args = [LS_TREE_CMD]
154
+
155
+ sub_cmd_args.extend(self.d_arg(ls_tree_opts.get("d")))
156
+ sub_cmd_args.extend(self.r_arg(ls_tree_opts.get("r")))
157
+ sub_cmd_args.extend(self.t_arg(ls_tree_opts.get("t")))
158
+ sub_cmd_args.extend(self.long_arg(ls_tree_opts.get("long")))
159
+ sub_cmd_args.extend(self.z_arg(ls_tree_opts.get("z")))
160
+ sub_cmd_args.extend(self.name_only_arg(ls_tree_opts.get("name_only")))
161
+ sub_cmd_args.extend(self.name_status_arg(ls_tree_opts.get("name_status")))
162
+ sub_cmd_args.extend(self.object_only_arg(ls_tree_opts.get("object_only")))
163
+ sub_cmd_args.extend(self.full_name_arg(ls_tree_opts.get("full_name")))
164
+ sub_cmd_args.extend(self.full_tree_arg(ls_tree_opts.get("full_tree")))
165
+
166
+ sub_cmd_args.extend(self.abbrev_arg(ls_tree_opts.get("abbrev")))
167
+ sub_cmd_args.extend(self.format_arg(ls_tree_opts.get("format_")))
168
+
169
+ sub_cmd_args.extend(self.tree_ish_arg(tree_ish))
170
+ sub_cmd_args.extend(self.path_args(ls_tree_opts.get("path")))
171
+
172
+ return sub_cmd_args
173
+
174
+ def d_arg(self, d: bool | None) -> list[str]:
175
+ """
176
+ Return ``-d`` if `d` is True.
177
+
178
+ :param d: Whether to include the ``-d`` option.
179
+ :return: List containing ``-d`` if applicable.
180
+
181
+ >>> IndividuallyOverridableLTCAB().d_arg(True)
182
+ ['-d']
183
+ >>> IndividuallyOverridableLTCAB().d_arg(False)
184
+ []
185
+ >>> IndividuallyOverridableLTCAB().d_arg(None)
186
+ []
187
+ """
188
+ return ["-d"] if d else []
189
+
190
+ def r_arg(self, r: bool | None) -> list[str]:
191
+ """
192
+ Return ``-r`` if `r` is True.
193
+
194
+ :param r: Whether to include the ``-r`` option.
195
+ :return: List containing ``-r`` if applicable.
196
+
197
+ >>> IndividuallyOverridableLTCAB().r_arg(True)
198
+ ['-r']
199
+ >>> IndividuallyOverridableLTCAB().r_arg(False)
200
+ []
201
+ >>> IndividuallyOverridableLTCAB().r_arg(None)
202
+ []
203
+ """
204
+ return ["-r"] if r else []
205
+
206
+ def t_arg(self, t: bool | None) -> list[str]:
207
+ """
208
+ Return ``-t`` if `t` is True.
209
+
210
+ :param t: Whether to include the ``-t`` option.
211
+ :return: List containing ``-t`` if applicable.
212
+
213
+ >>> IndividuallyOverridableLTCAB().t_arg(True)
214
+ ['-t']
215
+ >>> IndividuallyOverridableLTCAB().t_arg(False)
216
+ []
217
+ >>> IndividuallyOverridableLTCAB().t_arg(None)
218
+ []
219
+ """
220
+ return ["-t"] if t else []
221
+
222
+ def long_arg(self, long: bool | None) -> list[str]:
223
+ """
224
+ Return ``-l`` if `long` is True.
225
+
226
+ :param long: Whether to include the ``-l`` option.
227
+ :return: List containing ``-l`` if applicable.
228
+
229
+ >>> IndividuallyOverridableLTCAB().long_arg(True)
230
+ ['-l']
231
+ >>> IndividuallyOverridableLTCAB().long_arg(False)
232
+ []
233
+ >>> IndividuallyOverridableLTCAB().long_arg(None)
234
+ []
235
+ """
236
+ return ["-l"] if long else []
237
+
238
+ def z_arg(self, z: bool | None) -> list[str]:
239
+ """
240
+ Return ``-z`` if `z` is True.
241
+
242
+ :param z: Whether to include the ``-z`` option.
243
+ :return: List containing ``-z`` if applicable.
244
+
245
+ >>> IndividuallyOverridableLTCAB().z_arg(True)
246
+ ['-z']
247
+ >>> IndividuallyOverridableLTCAB().z_arg(False)
248
+ []
249
+ >>> IndividuallyOverridableLTCAB().z_arg(None)
250
+ []
251
+ """
252
+ return ["-z"] if z else []
253
+
254
+ def name_only_arg(self, name_only: bool | None) -> list[str]:
255
+ """
256
+ Return ``--name-only`` if applicable.
257
+
258
+ >>> IndividuallyOverridableLTCAB().name_only_arg(True)
259
+ ['--name-only']
260
+ >>> IndividuallyOverridableLTCAB().name_only_arg(False)
261
+ []
262
+ >>> IndividuallyOverridableLTCAB().name_only_arg(None)
263
+ []
264
+ """
265
+ return ["--name-only"] if name_only else []
266
+
267
+ def name_status_arg(self, name_status: bool | None) -> list[str]:
268
+ """
269
+ Return ``--name-status`` if applicable.
270
+
271
+ >>> IndividuallyOverridableLTCAB().name_status_arg(True)
272
+ ['--name-status']
273
+ >>> IndividuallyOverridableLTCAB().name_status_arg(False)
274
+ []
275
+ >>> IndividuallyOverridableLTCAB().name_status_arg(None)
276
+ []
277
+ """
278
+ return ["--name-status"] if name_status else []
279
+
280
+ def object_only_arg(self, object_only: bool | None) -> list[str]:
281
+ """
282
+ Return ``--object-only`` if applicable.
283
+
284
+ >>> IndividuallyOverridableLTCAB().object_only_arg(True)
285
+ ['--object-only']
286
+ >>> IndividuallyOverridableLTCAB().object_only_arg(False)
287
+ []
288
+ >>> IndividuallyOverridableLTCAB().object_only_arg(None)
289
+ []
290
+ """
291
+ return ["--object-only"] if object_only else []
292
+
293
+ def full_name_arg(self, full_name: bool | None) -> list[str]:
294
+ """
295
+ Return ``--full-name`` if applicable.
296
+
297
+ >>> IndividuallyOverridableLTCAB().full_name_arg(True)
298
+ ['--full-name']
299
+ >>> IndividuallyOverridableLTCAB().full_name_arg(False)
300
+ []
301
+ >>> IndividuallyOverridableLTCAB().full_name_arg(None)
302
+ []
303
+ """
304
+ return ["--full-name"] if full_name else []
305
+
306
+ def full_tree_arg(self, full_tree: bool | None) -> list[str]:
307
+ """
308
+ Return ``--full-tree`` if applicable.
309
+
310
+ >>> IndividuallyOverridableLTCAB().full_tree_arg(True)
311
+ ['--full-tree']
312
+ >>> IndividuallyOverridableLTCAB().full_tree_arg(False)
313
+ []
314
+ >>> IndividuallyOverridableLTCAB().full_tree_arg(None)
315
+ []
316
+ """
317
+ return ["--full-tree"] if full_tree else []
318
+
319
+ def abbrev_arg(self, abbrev: int | None) -> list[str]:
320
+ """
321
+ Format ``--abbrev=N`` if `abbrev` is provided.
322
+
323
+ :param abbrev: Abbreviation length (0-40 inclusive).
324
+ :return: List containing formatted option or empty list.
325
+
326
+ >>> IndividuallyOverridableLTCAB().abbrev_arg(None)
327
+ []
328
+ >>> IndividuallyOverridableLTCAB().abbrev_arg(7)
329
+ ['--abbrev=7']
330
+ >>> IndividuallyOverridableLTCAB().abbrev_arg(0)
331
+ ['--abbrev=0']
332
+ >>> IndividuallyOverridableLTCAB().abbrev_arg(40)
333
+ ['--abbrev=40']
334
+ """
335
+ return [f"--abbrev={abbrev}"] if abbrev is not None else []
336
+
337
+ def format_arg(self, _format: str | None) -> list[str]:
338
+ """
339
+ Format ``--format=...`` if `_format` is provided.
340
+
341
+ :param _format: A valid format string.
342
+ :return: List containing formatted option or empty list.
343
+
344
+ >>> IndividuallyOverridableLTCAB().format_arg(None)
345
+ []
346
+ >>> IndividuallyOverridableLTCAB().format_arg('%(objectname)')
347
+ ['--format=%(objectname)']
348
+ >>> IndividuallyOverridableLTCAB().format_arg('')
349
+ ['--format=']
350
+ """
351
+ return [f"--format={_format}"] if _format is not None else []
352
+
353
+ def tree_ish_arg(self, tree_ish: str) -> list[str]:
354
+ """
355
+ Return the required tree-ish identifier as a single-element list.
356
+
357
+ This value is typically a commit SHA, branch name, tag, or other valid tree reference
358
+ and is appended at the end of the formed git subcommand options, just before path(s).
359
+
360
+ >>> IndividuallyOverridableLTCAB().tree_ish_arg("HEAD")
361
+ ['HEAD']
362
+ >>> IndividuallyOverridableLTCAB().tree_ish_arg("origin/main")
363
+ ['origin/main']
364
+ >>> IndividuallyOverridableLTCAB().tree_ish_arg("a1b2c3d")
365
+ ['a1b2c3d']
366
+ >>> IndividuallyOverridableLTCAB().tree_ish_arg("")
367
+ ['']
368
+ """
369
+ return [tree_ish]
370
+
371
+ def path_args(self, path: list[str] | None) -> list[str]:
372
+ """
373
+ Return the list of paths (if any) passed to ``git ls-tree``.
374
+
375
+ If `path` is None or an empty list, this returns an empty list.
376
+
377
+ >>> IndividuallyOverridableLTCAB().path_args(["src", "README.md"])
378
+ ['src', 'README.md']
379
+ >>> IndividuallyOverridableLTCAB().path_args([])
380
+ []
381
+ >>> IndividuallyOverridableLTCAB().path_args(None)
382
+ []
383
+ """
384
+ return path if path else []
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env python3
2
+ # coding=utf-8
3
+
4
+ """
5
+ Git command runners to run subprocess calls.
6
+ """
7
+
8
+ from gitbolt.git_subprocess.runner.base import GitCommandRunner as GitCommandRunner
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python3
2
+ # coding=utf-8
3
+
4
+ """
5
+ Git command runner interfaces to run subprocess calls.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from abc import abstractmethod
11
+ from subprocess import CompletedProcess
12
+ from typing import Protocol, overload, Any, Literal
13
+
14
+
15
+ class GitCommandRunner(Protocol):
16
+ """
17
+ Interface to facilitate running git commands in subprocess.
18
+ """
19
+
20
+ @overload
21
+ @abstractmethod
22
+ def run_git_command(
23
+ self,
24
+ main_cmd_args: list[str],
25
+ subcommand_args: list[str],
26
+ *subprocess_run_args: Any,
27
+ _input: str,
28
+ text: Literal[True],
29
+ **subprocess_run_kwargs: Any,
30
+ ) -> CompletedProcess[str]: ...
31
+
32
+ @overload
33
+ @abstractmethod
34
+ def run_git_command(
35
+ self,
36
+ main_cmd_args: list[str],
37
+ subcommand_args: list[str],
38
+ *subprocess_run_args: Any,
39
+ _input: bytes,
40
+ text: Literal[False],
41
+ **subprocess_run_kwargs: Any,
42
+ ) -> CompletedProcess[bytes]: ...
43
+
44
+ @overload
45
+ @abstractmethod
46
+ def run_git_command(
47
+ self,
48
+ main_cmd_args: list[str],
49
+ subcommand_args: list[str],
50
+ *subprocess_run_args: Any,
51
+ text: Literal[True],
52
+ **subprocess_run_kwargs: Any,
53
+ ) -> CompletedProcess[str]: ...
54
+
55
+ @overload
56
+ @abstractmethod
57
+ def run_git_command(
58
+ self,
59
+ main_cmd_args: list[str],
60
+ subcommand_args: list[str],
61
+ *subprocess_run_args: Any,
62
+ text: Literal[False] = ...,
63
+ **subprocess_run_kwargs: Any,
64
+ ) -> CompletedProcess[bytes]: ...