A bash script to clone all repositories from a GitLab group and its subgroups recursively. Perfect for backing up your organization's repositories or setting up a local development environment.
- 🔍 Recursive Group Cloning: Automatically discovers and clones repositories from all subgroups
- 📁 Organized Structure: Creates directories matching your GitLab group hierarchy
- ⚡ Smart Skipping: Skips repositories that already exist locally
- 🔐 Secure: Supports both command-line arguments and environment variables for tokens
- 🌐 GitLab Compatible: Works with GitLab.com and self-hosted GitLab instances
bash(version 4.0 or higher)curl- for making API requestsjq- for parsing JSON responsesgit- for cloning repositories- A GitLab Personal Access Token with
read_apiandread_repositoryscopes
macOS:
brew install curl jqLinux (Ubuntu/Debian):
sudo apt-get update
sudo apt-get install curl jqLinux (Fedora/RHEL):
sudo dnf install curl jq- Clone this repository:
git clone https://github.com/yourusername/gitlab-bulk-cloner.git
cd gitlab-bulk-cloner- Make the script executable:
chmod +x clone.sh./clone.sh <GITLAB_URL> <ROOT_GROUP> <TOKEN>Example:
./clone.sh https://gitlab.com myorganization glpat-xxxxxxxxxxxxxexport GITLAB_URL="https://gitlab.com"
export ROOT_GROUP="myorganization"
export GITLAB_TOKEN="glpat-xxxxxxxxxxxxx"
./clone.shGITLAB_URL=https://gitlab.com ROOT_GROUP=myorganization GITLAB_TOKEN=glpat-xxxxx ./clone.sh./clone.sh https://gitlab.com mygroup glpat-xxxxxxxxxxxxx./clone.sh https://gitlab.example.com mygroup glpat-xxxxxxxxxxxxxexport GITLAB_URL="https://gitlab.com"
export ROOT_GROUP="mygroup"
export GITLAB_TOKEN="glpat-xxxxxxxxxxxxx"
./clone.sh- Fetches Group ID: Queries the GitLab API to find the root group ID
- Discovers Subgroups: Recursively finds all subgroups under the root group
- Creates Directory Structure: Creates local directories matching the GitLab group hierarchy
- Clones Repositories: Clones all repositories from each group and subgroup
- Skips Existing: Automatically skips repositories that already exist locally
The script creates a directory structure that mirrors your GitLab groups:
.
├── mygroup/
│ ├── project1/
│ ├── project2/
│ └── subgroup1/
│ ├── project3/
│ └── project4/
- Go to your GitLab profile settings
- Navigate to Access Tokens (or Personal Access Tokens)
- Create a new token with the following scopes:
read_api- Required to read group and project informationread_repository- Required to clone repositories
- Copy the token (it starts with
glpat-)
Note: Keep your token secure and never commit it to version control!
- Verify the
ROOT_GROUPname is correct (case-sensitive) - Ensure your token has access to the group
- Check that the GitLab URL is correct
- Install curl using your package manager (see Prerequisites)
- Install jq using your package manager (see Prerequisites)
- Make sure the script is executable:
chmod +x clone.sh - Verify your token has the correct permissions
- Check your token has
read_repositoryscope - Verify you have access to the repositories
- Check your network connection
- ✅ Use environment variables instead of command-line arguments when possible
- ✅ Never commit your GitLab token to version control
- ✅ Use tokens with minimal required scopes
- ✅ Rotate your tokens regularly
- ✅ Consider using
.envfiles (not included in this script, but you can add it)
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is open source and available under the MIT License.
- Built for the GitLab community
- Uses the GitLab API v4
If you encounter any issues or have questions, please open an issue on GitHub.
Made with ❤️ for the GitLab community