Migrating a Hugo + Netlify blog from GitHub to GitLab

I walk you through the process of migrating my blog from GitHub to GitLab. No code, just a lot of screenshots.

(If you only want to read how to migrate, click here)

First TIL of this blog post: the GitLab logo - - is AcTuAlLy not a fox but a tanuki - a Japanese racoon dog:

Image from https://pixabay.com/photos/raccoon-dog-tanuki-enok-fruit-fuchs-871609/

Cute, right? 😍 Well, anyway, to the content:

Last week, I participated in a hackathon organized by CorrelAid. It was a great event on so many levels - organization, data, people, location - but one of them was definitely that we used GitLab for the project. I have to admit that I am one of those people who created a GitLab account in the “oh no, GitHub was acquired by evil Microsoft - open source will die!” crisis last year but never even created a single project on it. So, I was a bit apprehensive at first when I heard that the organization we were collaborating with for the hackathon was using GitLab because it was a little bit out of my comfort zone (hey, different UI!). But at the same time, I was excited because I knew that GitLab offers many, many exciting features.

So after some time working on the backend code, I started checking out GitLab CI/CD and the docker registry in order to enable automatic testing etc. And it was just sooo easy to do! I did not get the full CI/CD pipeline to our server working to deploy the docker container to our server - but just by copy-pasting a gitlab-ci.yml off the internet and slightly adjusting it, I had a pipeline that build the docker image, ran the tests inside the docker image and if successful, pushed the image to the free docker registry that came with the GitLab repository. Sure, you can do that with travis in GitHub as well. But not as nicely and as integrated and as free - usually setting up a private docker registry requires you to pay some 💸. After the hackathon, I travelled home, very much impressed by GitLab but probably still not 100% committed to really changing anything.

And then, GitHub had a ca. 45 minute outage on Monday and one of my favorite #rstats AND security twitter people - what a combo! -, Bob Rudis (@hrbrmstr), tweeted this:

Perhaps use this yet-another-within-weeks GH IS DOWN moment to think about your choices when it comes to social coding sites and start planning diversification now.

Microsoft should ask Twitter if they can borrow their fail whale. Looks like they're going to need it.

— boB 🇷udis (@hrbrmstr) July 22, 2019

“Ok, that’s it!”, I thought, “Let’s migrate at least something!”. After all, I could not migrate the whole CorrelAid GitHub organization…well I could’ve (super admin powers!! :sunglasses:) but I probably should discuss this first with the others. 😉

So I decided on my blog repo because a) it’s small and b) it was a good test on whether GitLab could hold up with GitHub with regards to how well it’s supported by the tools I use for blogging: Hugo as a static site generator and Netlify for the deployment / CI/CD. Spoiler: It’s just the same experience as for GitHub.

Migrating the repo and the blog was surprisingly easy and smooth. It just took three steps and I did not even have to write a single line of code.

1. Import your GitHub Repo to GitLab

First, I migrated my repository from GitHub to GitLab. I initially thought I’d have do it like this:

  1. create empty repo in GitLab called “blog”.
  2. change the remote URL on my local machine to point to the new repo.
  3. push everything

I guess that would’ve worked as well but I was not sure on how easy step 3 would be, especially with regards to pushing all branches and all my commits. Git is still a bit like this for me:

Figure from https://imgs.xkcd.com/comics/git.png

In addition, with that approach, it would probably not be easy to migrate issues and pull requests. Which is not a big thing for my blog repository as I just work on it alone (look at the commit messages: “update”, “draft”, … 😂). However, for migrating other projects, pull requests and issues might become relevant.

Well.. turns out GitLab has you totally covered. When you click on “create new project”, there is a tab “import project” where you can import repositories from a range of providers:

When you click on “GitHub”, you’ll need to authorize GitLab to access your repositories - you only need to do this once. And voilà: you are presented with a list of all your own repositories and the repositories of organizations you belong to (and probably have admin rights of).

(image only showing imported repos…there are a lot more!)

Migrating the whole blog repo - code, commit history, branches, issues, pull requests - was then just a matter of CTRL+F “blog” to find it in the looong list, clicking “import” and waiting 1-2 minutes. Done. :tada:

(I also migrated another repository that has issues and pull requests and I can confirm that they were successfully converted into GitLab issues and merge requests. :tada:)

2. Change Netlify settings

Next up, Netlify.

  1. Log in to your netlify account.

  2. go to your site and find the “site settings”. Right now, it is located here:

  3. Under site settings, click on “Build & Deploy” in the sidebar and then click on “Edit settings”:

  4. Click “Link to a different repository”. That will open a three-step dialogue where you can connect Netlify to your GitLab and choose the blog repository.

The whole process worked flawlessly for me and I could successfully trigger a build (and I could apparently publish this blog post 😉).

3. Change git remote locally

Finally, I had to configure my local clone(s) of the blog repository so that I could push to GitLab instead of GitHub in the future.

How you need to do this depends a bit on your git client of choice. I use Gitkraken, so all I had to do was edit the remote in the GUI:

This opened up another window where I could insert the git URL of my repository: https://gitlab.com/friep/blog.git. If I previously had used a link starting with git@ (implying SSH authentication), I would’ve entered the corresponding GitLab version. In my case, that would’ve been: git@gitlab.com:friep/blog.git.

RStudio (or command line)

If you use the RStudio Git integration, you can’t change this setting with just a GUI click (at least I couldn’t find that option in the project settings or the Git tab).

(Note: Unfortunately, I was not able to test the following on Windows. If someone could test it and share their experiences, I’d be super happy to add some Windows specific instructions if necessary.)

Instead, switch from the R console to the terminal:

Then, you should be able to enter:

git remote -v

The output will look something like this:

origin  git@github.com:CorrelAid/newsanchor.git (fetch)
origin  git@github.com:CorrelAid/newsanchor.git (push)

You can then remove the remote using:

git remote rm origin

or similarly git remote rm {remote name} if your remote is not called origin. This will remove the “link” from your local copy to GitHub. Now, your git is just local.

So, let’s add your new GitLab remote: to give your repository a new “online home”

git add origin {gitlab remote url}

or git add {remote name} {gitlab remote url} if your previous remote was not called origin.

All your commits and pushes should now go to GitLab and you can safely delete or archive your GitHub repository.

Final thoughts

GitHub is the version control platform if you want your work to be seen. Especially in the R community, GitHub is the place to be. Which is not a bad thing per se: There are various excellent resources for R users related to GitHub 1, you can follow so many people and things are just sooo…convenient?

However, following Bob here, some diversification of how we share and distribute open source code cannot hurt: Getting cozy in one tool tends to make us unaware of other great tools that would allow us to do more in less time (see the excellent CI/CD support in GitLab, I can’t wait to work more with this!). Second, as a community, having an almost complete focus on one social coding platform puts us in a dependent position: If you wanted to download the development version of package on GitHub during the outage on Monday, you had no choice but to wait until it was over. In most cases, there would be no other place to get the dev version. Finally, well.. *insert argument on why to support open source 2 core software instead of huge companies*.

And even if you don’t want to commit to completely moving to GitLab or another social coding platform: Why not have it on both platforms? That could give you a peace of mind - just in case GitHub is unavailable again - while at the same time, you could retain your GitHub presence. 😉 You can even set up your Git to push to two repositories at once (haven’t tested that yet though). If you have done something like this, hit me up and let’s collaborate on another blog post where we explore the options for such a setup. 😊

Until then: keep coding. ❤️

  1. .e.g. https://happygitwithr.com/↩︎

  2. https://about.gitlab.com/2016/07/20/gitlab-is-open-core-github-is-closed-source/↩︎


If you see mistakes or want to suggest changes, please create an issue on the source repository.


Text and figures are licensed under Creative Commons Attribution CC BY 4.0. Source code is available at https://gitlab.com/friep/blog, unless otherwise noted. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".