Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
78 changes: 78 additions & 0 deletions content/blog/2025-10-17-github-and-away/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
title: Code hosting options beyond GitHub
author:
- Mark Padgham
editor:
date: '2025-10-17'
slug: beyond-github
description: How to manage and mirror code repositories across different platforms.
output: hugodown::md_document
tags:
- tech notes
params:
doi: ""
---

rOpenSci peer-review has to date been exclusively conducted [on GitHub](https://github.com/ropensci/software-review/issues?q=sort%3Aupdated-desc%20is%3Aissue%20state%3Aclosed).
We are not planning on moving away from this system any time soon, but are nonetheless aware that many people prefer alternative platforms.
rOpenSci also has an organization presence on [gitlab.com/ropensci](https://gitlab.com/ropensci) and [codeberg.org/ropensci](https://codeberg.org/ropensci).
This post describes how rOpenSci community members can use these alternative platforms.

## Code (still) needs a single home

All platforms described here are based on [git](https://git-scm.com/), which is a _centralized_ version control system (in contrast to decentralized version control systems such as [darcs](https://darcs.net/) or [pijul](https://pijul.org/)).
This means that managing code with git generally requires identifying a single, main version to which changes can be _pushed_, or from which changes can be _pulled_.
There is thus a single connection between code on your local machine and this single main version.

Code can of course be hosted anywhere, and we aim here to show how easy it is to mirror a repository on an arbitrary number of platforms.
Hosting code in multiple locations creates multiple connections between local and remote versions.
This can easily create conflicts in git.
To keeps things simple, this post will therefore presume that every repository maintains a single home, with all other platforms mirroring changes from that site via `git push` only.

## Mirroring to other platforms

### Mirroring on codeberg

The easiest platform on which to mirror your code is currently [Codeberg](https://codeberg.org), which has inbuilt options to mirror repositories directly from a large number of other platforms, including GitHub.
[Codeberg](https://codeberg.org) can also mirror all issues and pull requests, although the contributors will no longer be hyperlinked (see an [example here](https://codeberg.org/ropensci/osmdata/issues/388)).
To mirror a repo on Codeberg, click the large "+" button on the top right of the main menu bar, and select "New migration", like this:

![](codeberg-new-migration.png)

That will then open up the following grid of options from where you want to mirror your repository:

{{< figure src = "codeberg-migration-options.png" alt = "Codeberg new migration button." class = "pull-left" caption = "Codeberg new repository migration button.">}}

![](codeberg-migration-options.png)

To migrate from GitHub, click the symbol to open a migration to fill in some details, where you can also paste a GitHub token into "access token", and mirror almost all other aspects, including issues, pull requests, and releases.
Note that the migration process may take 10 minutes or more.
You'll also need to update your local `git` configuration to add the new remote destination, as described in the following sub-section.

### Mirroring elsewhere

No other platforms currently offer the one-click mirror functionality of Codeberg.
To mirror in all other cases, you'll need to:
1. Create a new repository on the desired platform.
2. Set a `git remote` URL to the new destination.
3. `git push` to new remote.

The [git remote web page](https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes) provides more detail on working with remotes.

## Managing one repository across multiple platforms

With due apologies for repeittion, git is a centralised version control system, and is thus not the best system for managing multiple remote sources.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest using American English for consistency, "centralised" here, but on line 23 it is "centralized"

The best way to manage one git repository across multiple platforms is to use one main source to which you `push`, and from where you may `pull`.
All other remote origins should be considered `push` mirrors only, and never `pull`.
In the rare case that conflicts from other sources arise, you may need to `git push --force` to _other_ remotes (or the [safer version of `git push --force-with-lease`](https://git-scm.com/docs/git-push#Documentation/git-push.txt---force-with-leaserefnameexpect)).
You should never `git push --force` to your main source.

For each additional remote source, you'll need to add a remote URL with [`git remote add`](https://git-scm.com/docs/git-remote).
In a standard set up, this will still require you to explicitly `git push` to each individual remote.
The pure git way of managing multiple remote sources is to take advantage of `git remote set-url --add` to add additional URLs to a single remote identifier.
Consistent with advice throughout this post, it is not recommended to update your _main_ remote URL with `set-url --add`.
A better option would be to initially create a remote like `git remote add other https://codeberg.org/ropensci/my-package`.
You can then extend that with each additional remote URL with `set-url --add`.
Running `git push other <branch>` will then push that branch to all remote URLs specified in `other`.

More arcane alternatives include my own [arcane git push bash script](https://github.com/mpadge/dotfiles/blob/main/system/gitpush.bash) which recreates the now obsolete push-by-password functionality of GitHub, while also pushing to all other listed remote sources.