As someone who frequently works with both GitHub and GitLab repositories, I often find the need to get an overview of various projects that exist within an organization or group. At my workplace, we use GitLab’s group- and subgroup functionality to organize our team-specific and customer-specific structures.

Recently, I needed to clone all 27 repositories associated with one of our microservice-projects (where else would you find so many repositories?). Doing this the traditional way by hand would require me to copy the URL for each repository and run “git clone \$URL” on the command line. This is a time-consuming and tedious process I want to avoid.

Fortunately,my habit for automating things lead me to discovering a tool called ghorg that simplifies this process.

With just a single command, I was able to clone entire GitHub organizations or GitLab (sub-)groups. Below is the command I used to do this:

ghorg clone customergroup/services --base-url=https://git.example.com --scm=gitlab --token=$TOKEN --preserve-dir -p .

This command clones all repositories in the group customergroup/services, connecting to our private GitLab instance, using the specified token $TOKEN to authenticate. The --preserve-dir option clones the repos in a directory structure that matches GitLab groups, so repository foo will be cloned into customergroup/services/foo.

ghorg clone customergroup/services --base-url=https://git.example.com --scm=gitlab --token=$TOKEN --preserve-dir -p .

 +-+-+-+-+ +-+-+ +-+-+-+-+-+
 |T|I|M|E| |T|O| |G|H|O|R|G|
 +-+-+-+-+ +-+-+ +-+-+-+-+-+

*************************************
* SCM           : gitlab
* Type          : org
* Protocol      : https
* Location      : ./
* Concurrency   : 25
* Base URL      : https://git.example.com
* Preserve Dir  : true
* Config Used   : none
* Ghorg version : v1.9.3
*************************************
27 repos found in customergroup/services

Success cloning repo: https://git.example.com/customergroup/services/foo.git -> branch: main
Success cloning repo: https://git.example.com/customergroup/services/foo-audit-report.git -> branch: master
Success cloning repo: https://git.example.com/customergroup/services/foo-tools.git -> branch: main
Success cloning repo: https://git.example.com/customergroup/services/foo-base.git -> branch: main
Success cloning repo: https://git.example.com/customergroup/services/foo-pages.git -> branch: main
Success cloning repo: https://git.example.com/customergroup/services/foo-helm.git -> branch: master
Success cloning repo: https://git.example.com/customergroup/services/foo-application-base.git -> branch: master

Interestingly, ghorg is not limited to GitLab or GitHub; it also offers support for other repository providers such as Bitbucket.

But I’m also a great fan of the gitlab-cli and it has a similar feature, too! Albeit the Gitlab-cli supports only Gitlab, naturally.

The same batch cloning process can be performed through the gitlab-cli tool with this command:

GITLAB_HOST=git.example.com glab repo clone --group customergroup/services -p

The syntax deviates slightly from the one used in “ghorg”. With --group $GROUP you define the particular group you want to clone and with the -p option you preserve the group-structure.

> GITLAB_HOST=git.example.com glab repo clone --group customergroup/services -p
Cloning into 'customergroup/services/foo'...
remote: Enumerating objects: 59, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 59 (delta 0), reused 0 (delta 0), pack-reused 54
Receiving objects: 100% (59/59), 13.36 KiB | 1.03 MiB/s, done.

Subsequently, both tools, ghorg and gitlab-cli, produced the same directory structure for the cloned repositories when tested, thus proving equivalently efficient.

> tree -d -L 3
.
└── customergroup
    └── services
        ├── foo
        ├── foo-audit-report
        ├── foo-tools
        ├── foo-base
        ├── foo-pages
        ├── foo-helm
        └── foo-application-base

Many other tools offer similar batch cloning features, like myrepos, vcsh or gitlabber, but I haven’t explored these alternatives yet. If anyone has experience with one of these tools, tell me! I’d love to hear about it.



Related posts: