set up your access and tools
You’ll need
- python/pip/virtualenv
 - git 1.7.3 or newer (for the hub tool)
 - a GitHub ssh key configured on your GitHub account
 - a GitLab ssh key configured on your GitLab account
 - a GitLab API token
 - the hub tool
 
clone the projects
usage
 | 
 | 
main.py
 | 
 | 
some notes
Apparently GitLab projects are organized by namespace, which is a dict with a field kind, which is user for user projects and group for group projects.
The gl.groups call returns all projects linked to that group. With this list, it’s possible to get the git clone url. I suppose this is technically correct, but it ignores all projects in the default user space.
I’m pretty sure gl.projects.list(all=True) tries to retrieve all of GitLab’s publicly visible projects, not just yours. Don’t do that.
gl.projects.list(owned=True, all=True, visibility='public') seems to return just publicly visible projects owned by me, without needing to worry about group vs. user namespaces.
push the projects to GitHub
This is probably better served as a bash script to allow more control for conflicts and other problems, but this works as a quick solution.
One downside to this approach is that it’s not always clear which directory is currently being acted on for repo creation and pushing.
change all remote URLs from GitLab to GitHub
This is a bit messy, but basically, it’s using basename to get the name of the directory (which is the name of the GitLab project), storing it in THE_NAME, then updating the remote with GitHub’s url string, substituting THE_NAME for the project.
 | 
 | 
create the necessary repos in GitHub using the hub tool
It’s not possible to create a repo in GitHub with a git push, so tools like hub are needed to automate this step.
Hub will ask for your username and password, though there may be an API token setting. It will also warn you if the target repo already exists: Existing repository detected.
The usage docs for hub state that hub create will also set the remote URL for the directory, but it (rightly so) does not do this when a remote is already defined, hence the update remote URL command above.
 | 
 | 
push repo to GitHub
 | 
 |