Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog

<!--next-version-placeholder-->
## [1.1.10] - 15/05/2022
### Added
- Support for mirrored repositories - dont-checkout flag

## [1.1.9] - 12/07/2021

### Added
Expand Down
3 changes: 2 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion gitlabber/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.1.9'
__version__ = '1.1.10'
8 changes: 7 additions & 1 deletion gitlabber/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down Expand Up @@ -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',
Expand Down
28 changes: 17 additions & 11 deletions gitlabber/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand All @@ -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:
Expand All @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions gitlabber/gitlab_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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():
Expand Down Expand Up @@ -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