gitlabber 2.1.0__tar.gz → 2.1.1__tar.gz
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.
- {gitlabber-2.1.0/gitlabber.egg-info → gitlabber-2.1.1}/PKG-INFO +4 -2
- {gitlabber-2.1.0 → gitlabber-2.1.1}/README.rst +2 -1
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/__init__.py +1 -1
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/cli.py +11 -1
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/config.py +1 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/git.py +21 -7
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/gitlab_tree.py +5 -1
- {gitlabber-2.1.0 → gitlabber-2.1.1/gitlabber.egg-info}/PKG-INFO +4 -2
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber.egg-info/requires.txt +1 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/pyproject.toml +2 -1
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/conftest.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/gitlab_test_utils.cpython-313.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/io_test_util.cpython-313.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_cli.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_cli_token_storage.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_config.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_e2e.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_exceptions.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.1.1/tests/__pycache__/test_git.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_gitlab_tree.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_helpers.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_integration.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_performance.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_rate_limiter.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_token_storage.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.1.1/tests/test_git.py +499 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_helpers.py +9 -1
- gitlabber-2.1.0/tests/__pycache__/test_git.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.1.0/tests/test_git.py +0 -219
- {gitlabber-2.1.0 → gitlabber-2.1.1}/LICENSE.txt +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/MANIFEST.in +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/__main__.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/archive.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/auth.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/exceptions.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/format.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/method.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/naming.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/progress.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/rate_limiter.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/token_storage.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/tree_builder.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber/url_builder.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber.egg-info/SOURCES.txt +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber.egg-info/dependency_links.txt +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber.egg-info/entry_points.txt +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/gitlabber.egg-info/top_level.txt +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/setup.cfg +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/setup.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__init__.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/__init__.cpython-311.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/__init__.cpython-312.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/__init__.cpython-313.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/conftest.cpython-311-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/gitlab_test_utils.cpython-311.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/gitlab_test_utils.cpython-312.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/io_test_util.cpython-311.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/io_test_util.cpython-312.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_archive.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_archive.cpython-312-pytest-8.3.3.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_archive.cpython-312-pytest-8.3.4.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_archive.cpython-312-pytest-8.3.5.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_archive.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_auth.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_cli.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_cli.cpython-311-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_cli.cpython-312-pytest-8.3.3.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_cli.cpython-312-pytest-8.3.4.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_cli.cpython-312-pytest-8.3.5.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_e2e.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_e2e.cpython-312-pytest-8.3.3.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_e2e.cpython-312-pytest-8.3.4.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_e2e.cpython-312-pytest-8.3.5.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_e2e.cpython-313.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_format.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_format.cpython-312-pytest-8.3.3.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_format.cpython-312-pytest-8.3.4.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_format.cpython-312-pytest-8.3.5.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_format.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_git.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_git.cpython-312-pytest-8.3.3.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_git.cpython-312-pytest-8.3.4.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_git.cpython-312-pytest-8.3.5.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_gitlab_tree.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_gitlab_tree.cpython-312-pytest-8.3.3.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_gitlab_tree.cpython-312-pytest-8.3.4.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_gitlab_tree.cpython-312-pytest-8.3.5.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_helpers.cpython-311-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_integration.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_integration.cpython-311-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_integration.cpython-312-pytest-8.3.3.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_integration.cpython-312-pytest-8.3.4.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_integration.cpython-312-pytest-8.3.5.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_method.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_method.cpython-312-pytest-8.3.3.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_method.cpython-312-pytest-8.3.4.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_method.cpython-312-pytest-8.3.5.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_method.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_naming.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_naming.cpython-312-pytest-8.3.3.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_naming.cpython-312-pytest-8.3.4.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_naming.cpython-312-pytest-8.3.5.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_naming.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_performance.cpython-313.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_progress.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_url_builder.cpython-313-pytest-9.0.1.pyc +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/conftest.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/gitlab_test_utils.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/io_test_util.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test-input.yaml +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test-output.json +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test-output.tree +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test-output.yaml +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_archive.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_auth.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_cli.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_cli_token_storage.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_config.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_e2e.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_exceptions.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_format.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_gitlab_tree.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_integration.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_main.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_method.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_naming.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_performance.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_progress.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_rate_limiter.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_token_storage.py +0 -0
- {gitlabber-2.1.0 → gitlabber-2.1.1}/tests/test_url_builder.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitlabber
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.1
|
|
4
4
|
Summary: A Gitlab clone/pull utility for backing up or cloning Gitlab groups
|
|
5
5
|
Author-email: Erez Mazor <erezmazor@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -26,6 +26,7 @@ Requires-Dist: pyyaml
|
|
|
26
26
|
Requires-Dist: pydantic>=2.7
|
|
27
27
|
Requires-Dist: pydantic-settings>=2.7
|
|
28
28
|
Requires-Dist: typer>=0.12
|
|
29
|
+
Requires-Dist: urllib3==2.5.0
|
|
29
30
|
Requires-Dist: rich
|
|
30
31
|
Requires-Dist: GitPython
|
|
31
32
|
Requires-Dist: python-gitlab
|
|
@@ -229,7 +230,8 @@ Usage
|
|
|
229
230
|
number of concurrent git operations (default: 1)
|
|
230
231
|
--api-concurrency N number of concurrent API calls for tree building (default: 5)
|
|
231
232
|
-r, --recursive clone/pull git submodules recursively
|
|
232
|
-
-F, --use-fetch
|
|
233
|
+
-F, --use-fetch use git fetch instead of pull for updates (normal repositories with working tree)
|
|
234
|
+
--mirror create bare mirror repositories (for backups, automatically uses fetch)
|
|
233
235
|
-s, --include-shared include shared projects in the results
|
|
234
236
|
-g term, --group-search term
|
|
235
237
|
only include groups matching the search term, filtering done at the API level (useful for large projects, see: https://docs.gitlab.com/ee/api/groups.html#search-for-group works with partial names of path or name)
|
|
@@ -189,7 +189,8 @@ Usage
|
|
|
189
189
|
number of concurrent git operations (default: 1)
|
|
190
190
|
--api-concurrency N number of concurrent API calls for tree building (default: 5)
|
|
191
191
|
-r, --recursive clone/pull git submodules recursively
|
|
192
|
-
-F, --use-fetch
|
|
192
|
+
-F, --use-fetch use git fetch instead of pull for updates (normal repositories with working tree)
|
|
193
|
+
--mirror create bare mirror repositories (for backups, automatically uses fetch)
|
|
193
194
|
-s, --include-shared include shared projects in the results
|
|
194
195
|
-g term, --group-search term
|
|
195
196
|
only include groups matching the search term, filtering done at the API level (useful for large projects, see: https://docs.gitlab.com/ee/api/groups.html#search-for-group works with partial names of path or name)
|
|
@@ -211,6 +211,7 @@ def run_gitlabber(
|
|
|
211
211
|
exclude: Optional[str],
|
|
212
212
|
recursive: bool,
|
|
213
213
|
use_fetch: bool,
|
|
214
|
+
mirror: bool,
|
|
214
215
|
include_shared: bool,
|
|
215
216
|
group_search: Optional[str],
|
|
216
217
|
user_projects: bool,
|
|
@@ -244,6 +245,7 @@ def run_gitlabber(
|
|
|
244
245
|
exclude: Comma-separated glob patterns to exclude
|
|
245
246
|
recursive: Clone submodules recursively
|
|
246
247
|
use_fetch: Use git fetch instead of pull
|
|
248
|
+
mirror: Create bare mirror repositories (implies use_fetch)
|
|
247
249
|
include_shared: Include shared projects
|
|
248
250
|
group_search: Search term for filtering groups at API level
|
|
249
251
|
user_projects: Fetch only user personal projects
|
|
@@ -295,6 +297,7 @@ def run_gitlabber(
|
|
|
295
297
|
"recursive": recursive,
|
|
296
298
|
"include_shared": include_shared,
|
|
297
299
|
"use_fetch": use_fetch,
|
|
300
|
+
"mirror": mirror,
|
|
298
301
|
"hide_token": hide_token,
|
|
299
302
|
"user_projects": user_projects,
|
|
300
303
|
"group_search": group_search,
|
|
@@ -318,6 +321,7 @@ def run_gitlabber(
|
|
|
318
321
|
disable_progress=verbose,
|
|
319
322
|
include_shared=include_shared,
|
|
320
323
|
use_fetch=use_fetch,
|
|
324
|
+
mirror=mirror,
|
|
321
325
|
hide_token=hide_token,
|
|
322
326
|
user_projects=user_projects,
|
|
323
327
|
group_search=group_search,
|
|
@@ -458,7 +462,7 @@ def cli(
|
|
|
458
462
|
False,
|
|
459
463
|
"-F",
|
|
460
464
|
"--use-fetch",
|
|
461
|
-
help="Use git fetch instead of pull (
|
|
465
|
+
help="Use git fetch instead of pull for updates (normal repositories with working tree)",
|
|
462
466
|
),
|
|
463
467
|
exclude_shared: bool = typer.Option(
|
|
464
468
|
False,
|
|
@@ -495,6 +499,11 @@ def cli(
|
|
|
495
499
|
"--store-token",
|
|
496
500
|
help="Store token securely in OS keyring (requires keyring package)",
|
|
497
501
|
),
|
|
502
|
+
mirror: bool = typer.Option(
|
|
503
|
+
False,
|
|
504
|
+
"--mirror",
|
|
505
|
+
help="Create bare mirror repositories (for backups, automatically uses fetch)",
|
|
506
|
+
),
|
|
498
507
|
) -> None:
|
|
499
508
|
"""Main CLI command for gitlabber.
|
|
500
509
|
|
|
@@ -560,6 +569,7 @@ def cli(
|
|
|
560
569
|
exclude=exclude,
|
|
561
570
|
recursive=recursive,
|
|
562
571
|
use_fetch=use_fetch,
|
|
572
|
+
mirror=mirror,
|
|
563
573
|
include_shared=include_shared_value,
|
|
564
574
|
group_search=group_search,
|
|
565
575
|
user_projects=user_projects,
|
|
@@ -26,6 +26,7 @@ class GitAction:
|
|
|
26
26
|
use_fetch: bool = False
|
|
27
27
|
hide_token: bool = False
|
|
28
28
|
git_options: Optional[str] = None
|
|
29
|
+
mirror: bool = False # New parameter
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
class GitRepository:
|
|
@@ -68,7 +69,7 @@ class GitRepository:
|
|
|
68
69
|
multi_options: list[str] = []
|
|
69
70
|
if action.recursive:
|
|
70
71
|
multi_options.append('--recursive')
|
|
71
|
-
if action.
|
|
72
|
+
if action.mirror: # New parameter
|
|
72
73
|
multi_options.append('--mirror')
|
|
73
74
|
if action.git_options:
|
|
74
75
|
multi_options += action.git_options.split(',')
|
|
@@ -132,13 +133,15 @@ class GitRepository:
|
|
|
132
133
|
GitlabberGitError: If pull operation fails
|
|
133
134
|
"""
|
|
134
135
|
log.debug("updating existing project %s", action.path)
|
|
135
|
-
|
|
136
|
+
# Mirror implies use_fetch, so check both
|
|
137
|
+
should_fetch = action.use_fetch or action.mirror
|
|
138
|
+
operation = 'fetching' if should_fetch else 'pulling'
|
|
136
139
|
progress_bar.show_progress_detailed(action.node.name, 'project', operation)
|
|
137
140
|
|
|
138
141
|
try:
|
|
139
142
|
if repo is None:
|
|
140
143
|
repo = git.Repo(action.path)
|
|
141
|
-
if not
|
|
144
|
+
if not should_fetch:
|
|
142
145
|
repo.remotes.origin.pull()
|
|
143
146
|
else:
|
|
144
147
|
repo.remotes.origin.fetch()
|
|
@@ -226,6 +229,7 @@ class GitActionCollector:
|
|
|
226
229
|
dest: str,
|
|
227
230
|
recursive: bool = False,
|
|
228
231
|
use_fetch: bool = False,
|
|
232
|
+
mirror: bool = False,
|
|
229
233
|
hide_token: bool = False,
|
|
230
234
|
git_options: Optional[str] = None
|
|
231
235
|
):
|
|
@@ -235,12 +239,14 @@ class GitActionCollector:
|
|
|
235
239
|
dest: Destination directory for repositories
|
|
236
240
|
recursive: Whether to clone recursively
|
|
237
241
|
use_fetch: Whether to use git fetch instead of pull
|
|
242
|
+
mirror: Whether to create bare mirror repositories
|
|
238
243
|
hide_token: Whether to hide token in URLs
|
|
239
244
|
git_options: Additional git options as comma-separated string
|
|
240
245
|
"""
|
|
241
246
|
self.dest = Path(dest)
|
|
242
247
|
self.recursive = recursive
|
|
243
248
|
self.use_fetch = use_fetch
|
|
249
|
+
self.mirror = mirror
|
|
244
250
|
self.hide_token = hide_token
|
|
245
251
|
self.git_options = git_options
|
|
246
252
|
|
|
@@ -272,9 +278,11 @@ class GitActionCollector:
|
|
|
272
278
|
path_str = str(path)
|
|
273
279
|
|
|
274
280
|
if child.is_leaf:
|
|
281
|
+
# Mirror implies use_fetch (mirrors should always use fetch)
|
|
282
|
+
effective_use_fetch = self.use_fetch or self.mirror
|
|
275
283
|
actions.append(GitAction(
|
|
276
284
|
child, path_str, self.recursive,
|
|
277
|
-
self.
|
|
285
|
+
effective_use_fetch, self.hide_token, self.git_options, self.mirror
|
|
278
286
|
))
|
|
279
287
|
|
|
280
288
|
if not child.is_leaf:
|
|
@@ -307,6 +315,7 @@ class GitSyncManager:
|
|
|
307
315
|
dest: str,
|
|
308
316
|
recursive: bool = False,
|
|
309
317
|
use_fetch: bool = False,
|
|
318
|
+
mirror: bool = False,
|
|
310
319
|
hide_token: bool = False,
|
|
311
320
|
git_options: Optional[str] = None
|
|
312
321
|
) -> None:
|
|
@@ -317,6 +326,7 @@ class GitSyncManager:
|
|
|
317
326
|
dest: Destination directory
|
|
318
327
|
recursive: Whether to clone recursively
|
|
319
328
|
use_fetch: Whether to use git fetch instead of pull
|
|
329
|
+
mirror: Whether to create bare mirror repositories
|
|
320
330
|
hide_token: Whether to hide token in URLs
|
|
321
331
|
git_options: Additional git options as comma-separated string
|
|
322
332
|
"""
|
|
@@ -324,7 +334,7 @@ class GitSyncManager:
|
|
|
324
334
|
self.progress_bar.init_progress(len(root.leaves))
|
|
325
335
|
|
|
326
336
|
collector = GitActionCollector(
|
|
327
|
-
dest, recursive, use_fetch, hide_token, git_options
|
|
337
|
+
dest, recursive, use_fetch, mirror, hide_token, git_options
|
|
328
338
|
)
|
|
329
339
|
actions = collector.collect(root)
|
|
330
340
|
|
|
@@ -343,6 +353,7 @@ def sync_tree(
|
|
|
343
353
|
disable_progress: bool = False,
|
|
344
354
|
recursive: bool = False,
|
|
345
355
|
use_fetch: bool = False,
|
|
356
|
+
mirror: bool = False,
|
|
346
357
|
hide_token: bool = False,
|
|
347
358
|
git_options: Optional[str] = None
|
|
348
359
|
) -> None:
|
|
@@ -356,11 +367,12 @@ def sync_tree(
|
|
|
356
367
|
disable_progress: Whether to disable progress reporting
|
|
357
368
|
recursive: Whether to clone recursively
|
|
358
369
|
use_fetch: Whether to use git fetch instead of pull
|
|
370
|
+
mirror: Whether to create bare mirror repositories
|
|
359
371
|
hide_token: Whether to hide token in URLs
|
|
360
372
|
git_options: Additional git options as comma-separated string
|
|
361
373
|
"""
|
|
362
374
|
manager = GitSyncManager(concurrency, disable_progress)
|
|
363
|
-
manager.sync(root, dest, recursive, use_fetch, hide_token, git_options)
|
|
375
|
+
manager.sync(root, dest, recursive, use_fetch, mirror, hide_token, git_options)
|
|
364
376
|
|
|
365
377
|
|
|
366
378
|
def get_git_actions(
|
|
@@ -368,6 +380,7 @@ def get_git_actions(
|
|
|
368
380
|
dest: str,
|
|
369
381
|
recursive: bool,
|
|
370
382
|
use_fetch: bool,
|
|
383
|
+
mirror: bool,
|
|
371
384
|
hide_token: bool,
|
|
372
385
|
git_options: Optional[str] = None
|
|
373
386
|
) -> list[GitAction]:
|
|
@@ -378,13 +391,14 @@ def get_git_actions(
|
|
|
378
391
|
dest: Destination directory
|
|
379
392
|
recursive: Whether to clone recursively
|
|
380
393
|
use_fetch: Whether to use git fetch instead of pull
|
|
394
|
+
mirror: Whether to create bare mirror repositories
|
|
381
395
|
hide_token: Whether to hide token in URLs
|
|
382
396
|
git_options: Additional git options as comma-separated string
|
|
383
397
|
|
|
384
398
|
Returns:
|
|
385
399
|
List of GitAction objects to execute
|
|
386
400
|
"""
|
|
387
|
-
collector = GitActionCollector(dest, recursive, use_fetch, hide_token, git_options)
|
|
401
|
+
collector = GitActionCollector(dest, recursive, use_fetch, mirror, hide_token, git_options)
|
|
388
402
|
return collector.collect(root)
|
|
389
403
|
|
|
390
404
|
|
|
@@ -45,6 +45,7 @@ class GitlabTree:
|
|
|
45
45
|
disable_progress: bool = False,
|
|
46
46
|
include_shared: bool = True,
|
|
47
47
|
use_fetch: bool = False,
|
|
48
|
+
mirror: bool = False,
|
|
48
49
|
hide_token: bool = False,
|
|
49
50
|
user_projects: bool = False,
|
|
50
51
|
group_search: Optional[str] = None,
|
|
@@ -69,6 +70,7 @@ class GitlabTree:
|
|
|
69
70
|
disable_progress: Whether to disable progress bar (used if config not provided)
|
|
70
71
|
include_shared: Whether to include shared projects (used if config not provided)
|
|
71
72
|
use_fetch: Whether to use git fetch instead of pull (used if config not provided)
|
|
73
|
+
mirror: Whether to create bare mirror repositories (used if config not provided)
|
|
72
74
|
hide_token: Whether to hide token in URLs (used if config not provided)
|
|
73
75
|
user_projects: Whether to fetch only user projects (used if config not provided)
|
|
74
76
|
group_search: Search term for filtering groups (used if config not provided)
|
|
@@ -98,6 +100,7 @@ class GitlabTree:
|
|
|
98
100
|
disable_progress = config.disable_progress
|
|
99
101
|
include_shared = config.include_shared
|
|
100
102
|
use_fetch = config.use_fetch
|
|
103
|
+
mirror = config.mirror
|
|
101
104
|
hide_token = config.hide_token
|
|
102
105
|
user_projects = config.user_projects
|
|
103
106
|
group_search = config.group_search
|
|
@@ -175,6 +178,7 @@ class GitlabTree:
|
|
|
175
178
|
self.token = token
|
|
176
179
|
self.include_shared = include_shared
|
|
177
180
|
self.use_fetch = use_fetch
|
|
181
|
+
self.mirror = mirror
|
|
178
182
|
self.hide_token = hide_token
|
|
179
183
|
self.user_projects = user_projects
|
|
180
184
|
self.group_search = group_search
|
|
@@ -308,7 +312,7 @@ class GitlabTree:
|
|
|
308
312
|
len(self.root.descendants) - len(self.root.leaves), len(self.root.leaves))
|
|
309
313
|
sync_tree(self.root, dest, concurrency=self.concurrency,
|
|
310
314
|
disable_progress=self.disable_progress, recursive=self.recursive,
|
|
311
|
-
use_fetch=self.use_fetch, hide_token=self.hide_token,
|
|
315
|
+
use_fetch=self.use_fetch, mirror=self.mirror, hide_token=self.hide_token,
|
|
312
316
|
git_options=self.git_options)
|
|
313
317
|
except GitlabberGitError:
|
|
314
318
|
# Re-raise git errors as-is
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitlabber
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.1
|
|
4
4
|
Summary: A Gitlab clone/pull utility for backing up or cloning Gitlab groups
|
|
5
5
|
Author-email: Erez Mazor <erezmazor@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -26,6 +26,7 @@ Requires-Dist: pyyaml
|
|
|
26
26
|
Requires-Dist: pydantic>=2.7
|
|
27
27
|
Requires-Dist: pydantic-settings>=2.7
|
|
28
28
|
Requires-Dist: typer>=0.12
|
|
29
|
+
Requires-Dist: urllib3==2.5.0
|
|
29
30
|
Requires-Dist: rich
|
|
30
31
|
Requires-Dist: GitPython
|
|
31
32
|
Requires-Dist: python-gitlab
|
|
@@ -229,7 +230,8 @@ Usage
|
|
|
229
230
|
number of concurrent git operations (default: 1)
|
|
230
231
|
--api-concurrency N number of concurrent API calls for tree building (default: 5)
|
|
231
232
|
-r, --recursive clone/pull git submodules recursively
|
|
232
|
-
-F, --use-fetch
|
|
233
|
+
-F, --use-fetch use git fetch instead of pull for updates (normal repositories with working tree)
|
|
234
|
+
--mirror create bare mirror repositories (for backups, automatically uses fetch)
|
|
233
235
|
-s, --include-shared include shared projects in the results
|
|
234
236
|
-g term, --group-search term
|
|
235
237
|
only include groups matching the search term, filtering done at the API level (useful for large projects, see: https://docs.gitlab.com/ee/api/groups.html#search-for-group works with partial names of path or name)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "gitlabber"
|
|
7
|
-
version = "2.1.
|
|
7
|
+
version = "2.1.1"
|
|
8
8
|
description = "A Gitlab clone/pull utility for backing up or cloning Gitlab groups"
|
|
9
9
|
readme = "README.rst"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -32,6 +32,7 @@ dependencies = [
|
|
|
32
32
|
"pydantic>=2.7",
|
|
33
33
|
"pydantic-settings>=2.7",
|
|
34
34
|
"typer>=0.12",
|
|
35
|
+
"urllib3==2.5.0",
|
|
35
36
|
"rich",
|
|
36
37
|
"GitPython",
|
|
37
38
|
"python-gitlab",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
{gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_config.cpython-313-pytest-9.0.1.pyc
RENAMED
|
Binary file
|
|
Binary file
|
{gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_exceptions.cpython-313-pytest-9.0.1.pyc
RENAMED
|
Binary file
|
|
Binary file
|
{gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_gitlab_tree.cpython-313-pytest-9.0.1.pyc
RENAMED
|
Binary file
|
{gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_helpers.cpython-313-pytest-9.0.1.pyc
RENAMED
|
Binary file
|
{gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_integration.cpython-313-pytest-9.0.1.pyc
RENAMED
|
Binary file
|
{gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc
RENAMED
|
Binary file
|
{gitlabber-2.1.0 → gitlabber-2.1.1}/tests/__pycache__/test_performance.cpython-313-pytest-9.0.1.pyc
RENAMED
|
Binary file
|