diff --git a/CHANGELOG.md b/CHANGELOG.md index 18eaf0b..482aee7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog +## [1.1.10] - 15/05/2022 +### Added +- Support for mirrored repositories - dont-checkout flag + ## [1.1.9] - 12/07/2021 ### Added diff --git a/README.rst b/README.rst index 7681929..20f215f 100644 --- a/README.rst +++ b/README.rst @@ -85,7 +85,7 @@ Usage .. code-block:: bash - usage: gitlabber [-h] [-t token] [-u url] [--verbose] [-p] + usage: gitlabber [-h] [-t token] [-u url] [--verbose] [-p] [-d] [--print-format {json,yaml,tree}] [-m {ssh,https}] [-i csv] [-x csv] [--version] [dest] @@ -115,6 +115,7 @@ Usage -x csv, --exclude csv comma delimited list of glob patterns of paths to projects or groups to exclude from clone/pull -r, --recursive clone/pull git submodules recursively + -d, --dont-checkout clone/fetch git repository without checkout --version print the version examples: diff --git a/gitlabber/__init__.py b/gitlabber/__init__.py index 86ee767..1bdaf47 100644 --- a/gitlabber/__init__.py +++ b/gitlabber/__init__.py @@ -1 +1 @@ -__version__ = '1.1.9' +__version__ = '1.1.10' diff --git a/gitlabber/cli.py b/gitlabber/cli.py index 968bcc8..f8c8358 100644 --- a/gitlabber/cli.py +++ b/gitlabber/cli.py @@ -38,7 +38,7 @@ def main(): excludes=split(args.exclude) tree = GitlabTree(args.url, args.token, args.method, args.naming, args.archived.api_value, includes, - excludes, args.file, args.concurrency, args.recursive, args.verbose) + excludes, args.file, args.concurrency, args.recursive, args.verbose, args.dont_checkout) log.debug("Reading projects tree from gitlab at [%s]", args.url) tree.load_tree() @@ -177,6 +177,12 @@ def parse_args(argv=None): action='store_true', default=False, help='clone/pull git submodules recursively') + parser.add_argument( + '-d', + '--dont-checkout', + action='store_true', + default=False, + help="don't checkout pulled git repository") parser.add_argument( '--version', action='store_true', diff --git a/gitlabber/git.py b/gitlabber/git.py index 405a2e4..c19d218 100644 --- a/gitlabber/git.py +++ b/gitlabber/git.py @@ -12,31 +12,32 @@ class GitAction: - def __init__(self, node, path, recursive=False): + def __init__(self, node, path, recursive=False, dont_checkout=False): self.node = node self.path = path self.recursive = recursive + self.dont_checkout = dont_checkout -def sync_tree(root, dest, concurrency=1, disable_progress=False, recursive=False): +def sync_tree(root, dest, concurrency=1, disable_progress=False, recursive=False, dont_checkout=False): if not disable_progress: progress.init_progress(len(root.leaves)) - actions = get_git_actions(root, dest, recursive) + actions = get_git_actions(root, dest, recursive, dont_checkout) with concurrent.futures.ThreadPoolExecutor(max_workers=concurrency) as executor: executor.map(clone_or_pull_project, actions) elapsed = progress.finish_progress() log.debug("Syncing projects took [%s]", elapsed) -def get_git_actions(root, dest, recursive): +def get_git_actions(root, dest, recursive, dont_checkout): actions = [] for child in root.children: path = "%s%s" % (dest, child.root_path) if not os.path.exists(path): os.makedirs(path) if child.is_leaf: - actions.append(GitAction(child, path, recursive)) + actions.append(GitAction(child, path, recursive, dont_checkout)) if not child.is_leaf: - actions.extend(get_git_actions(child, dest, recursive)) + actions.extend(get_git_actions(child, dest, recursive, dont_checkout)) return actions @@ -57,7 +58,10 @@ def clone_or_pull_project(action): progress.show_progress(action.node.name, 'pull') try: repo = git.Repo(action.path) - repo.remotes.origin.pull() + if(not action.dont_checkout): + repo.remotes.origin.pull() + else: + repo.remotes.origin.fetch() if(action.recursive): repo.submodule_update(recursive=True) except KeyboardInterrupt: @@ -71,11 +75,13 @@ def clone_or_pull_project(action): ''' log.debug("cloning new project %s", action.path) progress.show_progress(action.node.name, 'clone') + multi_options = [] + if(action.recursive): + multi_options.append('--recursive') + if(action.dont_checkout): + multi_options.append('--mirror') try: - if(action.recursive): - git.Repo.clone_from(action.node.url, action.path, multi_options=['--recursive']) - else: - git.Repo.clone_from(action.node.url, action.path) + git.Repo.clone_from(action.node.url, action.path, multi_options=multi_options) except KeyboardInterrupt: log.fatal("User interrupted") sys.exit(0) diff --git a/gitlabber/gitlab_tree.py b/gitlabber/gitlab_tree.py index f4fc448..40008cc 100644 --- a/gitlabber/gitlab_tree.py +++ b/gitlabber/gitlab_tree.py @@ -16,7 +16,7 @@ class GitlabTree: - def __init__(self, url, token, method, naming, archived=None, includes=[], excludes=[], in_file=None, concurrency=1, recursive=False, disable_progress=False): + def __init__(self, url, token, method, naming, archived=None, includes=[], excludes=[], in_file=None, concurrency=1, recursive=False, disable_progress=False, dont_checkout=False): self.includes = includes self.excludes = excludes self.url = url @@ -31,6 +31,7 @@ def __init__(self, url, token, method, naming, archived=None, includes=[], exclu self.recursive = recursive self.disable_progress = disable_progress self.progress = ProgressBar('* loading tree', disable_progress) + self.dont_checkout = dont_checkout @staticmethod def get_ca_path(): @@ -178,7 +179,7 @@ def sync_tree(self, dest): log.debug("Going to clone/pull [%s] groups and [%s] projects" % (len(self.root.descendants) - len(self.root.leaves), len(self.root.leaves))) sync_tree(self.root, dest, concurrency=self.concurrency, - disable_progress=self.disable_progress, recursive=self.recursive) + disable_progress=self.disable_progress, recursive=self.recursive, dont_checkout=self.dont_checkout) def is_empty(self): return self.root.height < 1