
Photo by Ray Hennessy on Unsplash
Migrate your Git repositories to Gitea
Exodus
Anyone who uses Git will quickly see the true value of version management. I have set up my own Git server with all kinds of features on a Raspberry Pi with the Gogs self-hosted Git service software, but as of now, the Gogs repository has had very little activity, with releases only appearing every six months and offering very little in terms of new features. This situation led me to believe that the software will probably not survive much longer.
Unfortunately, I didn't realize the unhealthy state of Gogs until I was already dealing with versions that have no easy migration path to Gitea, a fork of Gogs and the new home I chose for my code. The two projects have drifted apart since the fork. In this article, I show how to migrate your repositories to Gitea.
Git Origin
Unlike veterans such as CVS or Subversion, Git is not a client-server application, but a distributed system, which means that no node is favored or disadvantaged compared with others. Git allows each repository to act as a server, making migration easier. You just have to make sure that the working copies contain all the branches and tags of the origin.
In the Git world, the origin is a local alias of a specific remote repository. It removes the need for you to enter the full URL for every fetch, pull, or push operation. In fact, you could even rename the origin
alias to, say, source
by typing:
git remote rename origin source
What is far more serious than these names in the context of a server migration is that all data from the previous origin is only available locally. If the previous server is deleted, development branches could be lost.
Checking for Completeness
If you want to migrate your repositories, first make sure all of them are fully available locally. I had no choice but to make all my remote repositories available locally with the git clone
command. Once that was done, I was able to check each repository's branches and tags. For each individual repository, all the branches and tags had to be up to date in the local version. A few Git commands and a little shell scripting made this task easier.
The following script shows how to check out all the branches of a repository:
for mybranch in $(git branch -a | grep -o -E '(remote.*)' | grep -v ' -> ' | cut -f3 -d'/') do git checkout "${mybranch}" git pull done
The git branch -a command
in the first line returns the names of all branches in the repository. For the purpose of migration, I was mainly interested in the branches that were not yet available locally, so I used grep
to filter out the remote branches. I then removed the line that denoted my HEAD
reference – that is, the currently active branch, which is marked with an arrow (->
).
The for
loop iterates over the branches it finds and executes the git checkout
command, making the branch in question available locally. You just need to repeat this procedure for all tags (git fetch --tags
).
Everything Is a File
True to my motto of "a lazy admin is a good admin" or "if you can do so, let the computer work for you," I thought about the easiest way to handle the migration. Looking at the operating system first, for me, one of the greatest strengths of free software is that practically everything that makes up the system is available as a file. This arrangement might sound trivial at first, but it will probably become clearer when you consider what you need to do in the scope of a server move.
The migration all starts with the Git software, which I want to change; the reverse proxy – NGINX in my case, the Exim4 mail server, and various shell scripts, cron tables, and so on. With no exceptions, I store global cron tables in the /etc/cron.d/
directory, global shell scripts in /usr/local/bin
, and non-distribution software in /opt/
. This structure makes it easy to create a backup of all the relevant files on this system with a one-liner:
$ sudo tar -vzcf /home/thomas/githorst.tar.gz /etc/ /opt/ /usr/local/bin/
The archive created in this way contains the files required to ensure the features on my old hardware exist in the same way on my future hardware.
My Raspberry Pi needs an operating system release change because a Raspbian version based on Debian 12 became available. The next step, then, is to copy the new Raspbian image to an SD card; Raspberry Pi Imager gives you a very convenient way of doing this. After booting the new system, it's time to install some software. A simple
sudo apt install postgres exim4 nginx
makes light work of this task. I then copied the required configuration files (Nginx, Exim4, and Gogs) to /etc/
.
Installing Gitea, including setting up a systemd service, was quick and painless thanks to the good documentation [1]. The service can be accessed on port 3000. Because I wanted to transfer the configuration of my existing Gogs instance to the new Gitea instance to the extent possible, I had to edit app.ini
, the central configuration file. Once again, Vim proves to be a great all-rounder, because vimdiff
– assuming you have some experience with Vim – makes it easy to find the differences between the former and the current configuration files and merge them as required.
Once you have set up the configuration to suit your needs, I would recommend sending a test email to check the mail server settings. You will find the most important server settings under Configuration | Site Administration (Figures 1 and 2) and can send a test email by entering an email address (Figure 3).
In general, I can warmly recommend the Gitea configuration cheat sheet [2], which contains every setting and every flag that can occur in the app.ini
file. However, I would definitely recommend adjusting the logging settings here. By default, Gitea only logs on the console, which makes very little sense in server operation. I would recommend configuring the settings for logging to files in the log section:
[log] #MODE = console MODE = file LEVEL = Warn ROOT_PATH = /opt/gitea/log LOG_ROTATE = true DAILY_ROTATE = true MAX_DAYS = 7 COMPRESS = true COMPRESSION_LEVEL = -2
Merging the settings and setting up NGINX as a reverse proxy – again, with the old configuration – gives you a running, clean, empty Gitea instance. This process was even easier than I originally thought it would be.
Now is the time for migration (i.e., physically moving the existing repositories to the new server). My Gitea server has the same fully qualified domain name (FQDN) as the former Gogs; moreover, Gitea has the same Let's Encrypt certificates, which was exactly the plan I had in mind when I backed up the original system. Later, I will look into tried and tested procedures for moving a repository to a new server. In my case, all the server settings remained the same, minus repositories.
My first attempt was a naive git push
; after all, what could go wrong? To be honest, I was not so far off the mark and received a very informative error message, as well. Figure 4 shows the message in the first line of output, which sent me running to read the Gitea documentation, which clearly states:
In the app.ini file, set ENABLE_PUSH_CREATE_USER to true and ENABLE_PUSH_CREATE_ORG to true if you want to allow users to create repositories in their own user account and in organizations they are a member of respectively. Restart Gitea for the changes to take effect. You can read more about these two options in the Configuration Cheat Sheet.
(Gitea push
docs [3])
Voilà – exactly the information I needed.
I enabled two flags,
ENABLE_PUSH_CREATE_USER = true ENABLE_PUSH_CREATE_ORG = true
in the [repository]
section of the app.ini
file. After restarting the Gitea service, I tried my luck again, and with success this time. As you can see in Figure 5, Gitea accepts push-and-create for both user and organization-owned repos. Given my fears that the move could turn into a major project, this outcome was really satisfying.
Buy this article as PDF
(incl. VAT)
Buy ADMIN Magazine
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Most Popular
Support Our Work
ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.
