Migration of GitLab projects
Instances
URL to the GitLab Community Edition Instance: https://git-ce.rwth-aachen.de
URL to the GitLab Ultimate Edition Instance: https://git.rwth-aachen.de
Feature Comparison
Feature comparison of individual GitLab licenses: https://about.gitlab.com/pricing/self-managed/feature-comparison/
Project export
When exporting projects, the following elements are exported:
- project and wiki repositories
- project uploads
- Project configuration, including services
- Issues with comments, merge requests with diffs and comments, labels, milestones, snippets and other project entities
- LFS objects
- issue boards
The following elements are not exported:
- Job artifacts
- Container and Registry Images
- CI Variables
- webhooks
- all encrypted tokens
- Merge Request Approver
- Push Rules
- awards
Export via GUI
- view project page
- in the left navigation bar click on "Settings"
- Scroll down to "Advanced"
- Search and press the "Export project" button
As soon as the export is completed, a "Download export" button appears next to the "Export project" button. Please click on this button.
After the export has been downloaded, it can be imported into GitLab again.
While creating a new project, click on "Import Project" and then on "GitLab Export".
In the following step you have to set "Project name", "Project URL" and "Project slug".
The GitLab Export is now selected with "Choose File". After that the import is finished.
During the migration, permissions are not transferred and existing, local copies of the project must be updated.
To update the git URLs, the following must be done in the local repo:
- List the Git Remotes: git remote -v
- Transfer of remotes with adjustment to git-ce
Example:
git remote -v origin git@git.rwth-aachen.de:itc-lba/gitmig_scripts.git (fetch) origin git@git.rwth-aachen.de:itc-lba/gitmig_scripts.git (push) get remote set-url origin git@git-ce.rwth-aachen.de:itc-lba/gitmig_scripts.git git remote -v origin git@git-ce.rwth-aachen.de:itc-lba/gitmig_scripts.git (fetch) origin git@git-ce.rwth-aachen.de:itc-lba/gitmig_scripts.git (push) |
If the group name or the project name has changed, these must also be adapted. Generally applies:
- SSH: origin git@git-ce.rwth-aachen.de:<User/Group>/<Project name>.git
- HTTPS: origin https://git-ce.rwth-aachen.de/<User/Group>/<Project name>.git
Manual reworking
- GitLab Runner must be moved to git-ce.rwth-aachen.de
- The Git Remotes must be adjusted:
git remote -v # origin git@git.rwth-aachen.de:<Nutzer/Gruppe>/<Projektname>.git # diese Ausgabe kopieren und git.rwth-aachen.de durch git-ce.rwth-aachen.de austauschen git remote set-url origin git@git-ce.rwth-aachen.de:<Nutzer/Gruppe>/<Projektname>.git git remote set-url <Ausgabe> |
- Any Deploy Keys must be copied.
- SSH keys must be transferred
- User authorizations must be transferred manually.
For advanced users
To facilitate the migration of several projects, individual sample scripts for mass export/import were created at: https://git.rwth-aachen.de/itc-lba/gitmig_scripts .
Alternatively there is a Powershell script:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Write-Host "Dieses Skript hilft Ihnen bei der Migration der Projekte von https://git.rwth-aachen.de nach https://git-ce.rwth-aachen.de." Write-Host "Für die Migration brauchen Sie jeweils ein Private Token. Diese können Sie hier generieren:" Write-Host "https://git.rwth-aachen.de/profile/personal_access_tokens" Write-Host "https://git-ce.rwth-aachen.de/profile/personal_access_tokens" Write-Host "Die Token benötigen folgende Zugriffsrechte:" Write-Host " * api" Write-Host " * read_user" Write-Host " * read_repository" Write-Host " * write_repository" Write-Host " * read_registry" Write-Host "Neben dem Token brauchen Sie die Nutzer-ID bzw. Gruppen-ID von beiden Instanzen." Write-Host "Die Benutzer ID finden Sie unter https://git.rwth-aachen.de/profile im Feld User ID" Write-Host "und unter https://git-ce.rwth-aachen.de/profile unter User ID." Write-Host "Die Gruppen ID finden Sie unter https://git.rwth-aachen.de/<Gruppen Name> und" Write-Host "https://git-ce.rwth-aachen.de/<Gruppen Name>." Write-Host "Die Gruppe muss auf beiden Instanzen verfügbar sein." Write-Host "Bei der Migration werden folgende Elemente übertragen:" Write-Host " * Projekt und Wiki Repositories" Write-Host " * Projekt Uploads" Write-Host " * Projekt Konfigurationen, inklusive Diensten" Write-Host " * Issues mit Kommentaren, Merge Requests mit Diffs und Kommentaren, Labels, Milestones und andere Projekt Entitäten" Write-Host " * LFS Objekte" Write-Host " * Issue Boards" Write-Host "Bitte geben Sie nun nachfolgende die Informationen ein" $token_git = Read-Host -Prompt "Geben Sie Ihr Private Toke für https://git.rwth-aachen.de ein" $token_gitce = Read-Host -Prompt "Geben Sie Ihren Private Token für https://git-ce.rwth-aachen.de ein" $export_dir = Read-Host -Prompt "Geben Sie das Export Verzeichnis an" $group_title = "Gruppe oder Nutzer?" $group_pompt = "Handelt es sich um die Migration einer Gruppe oder eines Nutzer?" $group = New-Object System.Management.Automation.Host.ChoiceDescription "&Gruppe","Gruppe" $user = New-Object System.Management.Automation.Host.ChoiceDescription "&Nutzer","Nutzer" $options = [System.Management.Automation.Host.ChoiceDescription[]]($group, $user) [string]$selectedType = $host.ui.PromptForChoice($group_title, $group_pompt, $options, 1) if ($selectedType -eq 1) { $urlid = 'users' $userid_git = Read-Host -Prompt "Geben Sie die Nutzer ID von https://git.rwth-aachen.de ein" $userid_gitce = Read-Host -Prompt "Geben Sie die Nutzer ID von https://git-ce.rwth-aachen.de ein" } elseif ($selectedType -eq 0){ $urlid = 'groups' $userid_git = Read-Host -Prompt "Geben Sie die Gruppen ID von https://git.rwth-aachen.de ein" $userid_gitce = Read-Host -Prompt "Geben Sie die Gruppen ID von https://git-ce.rwth-aachen.de ein" } $r = Invoke-RestMethod -Headers @{ 'PRIVATE-TOKEN' = $token_git } -Uri https://git.rwth-aachen.de/api/v4/$urlid/$userid_git/projects # Prints a table of projects to be imported $r | Select-Object id, name | Sort-Object -Property id | Export-Csv -Path "myprojects.csv" -NoTypeInformation # Send export request for each project Import-Csv -Path "myprojects.csv" | ForEach-Object { $url = ("https://git.rwth-aachen.de/api/v4/projects/" + $_.id + "/export"); Invoke-RestMethod -Method Post -Headers @{ 'PRIVATE-TOKEN'=$token_git } -Uri $url } Write-Host "Alle Ihre Projekte wurden nun exportiert. Bitte Warten Sie, bis Sie zu jedem Projekt eine E-Mail erhalten haben, dass es erfolgreich exportiert wurde." Write-Host "Drücken sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown'); # Download Import-Csv -Path "myprojects.csv" | ForEach-Object { $url = ("https://git.rwth-aachen.de/api/v4/projects/" + $_.id + "/export/download"); $filename= $_.id; Invoke-RestMethod -Headers @{ 'PRIVATE-TOKEN'=$token_git } -Uri $url -OutFile "$export_dir\$filename.tar.gz" } # Import all Projects if ($PSVersionTable.PSVersion.Major -ge 6) { Import-Csv -Path "myprojects.csv" | ForEach-Object { $file = ($export_dir + "\" + $_.id + ".tar.gz"); Invoke-RestMethod -Method Post -Headers @{ 'PRIVATE-TOKEN' = $token_gitce } -Form @{ namespace = $userid_gitce; path = $_.name; file = Get-Item $file } -Uri https://git-ce.rwth-aachen.de/api/v4/projects/import } } else { Import-Csv -Path "myprojects.csv" | ForEach-Object { $file = ($export_dir + "\" + $_.id + ".tar.gz"); Invoke-RestMethod -Method Post -ContentType 'multipart/form-data' -Headers @{ 'PRIVATE-TOKEN' = $token_gitce } -Body @{'namespace' = $userid_gitce; 'path' = $_.name; 'file' = [IO.File]::ReadAllBytes($file)} -Uri https://git-ce.rwth-aachen.de/api/v4/projects/import } } |