History

I wanted to switch away from GitHub for a while. I considered a few options. Mainly SourceHut and Radicle.

In the end, I chose SourceHut because it's easier for non-tech users to look at.

Now what?

I created my account and then the actual migration had to happen. SourceHut has an option to import repos from other forges, but it would take too long and all my private repos would not be importable.

Luckily, the GitHub command has an option to create JSONs for all repos with all the necessary data to copy them to SourceHut.

Furthermore, SourceHut allows you to create, private by default, repos by simply pushing to a non-existing repo.

Note: SourceHut uses SSH to push to repos. HTTP/S is not an option.

Repo

read -p "Enter forge URL: " forge
read -p "Enter username: " user

json=$(gh repo list --json url,name,isPrivate)
readarray -t arr < <(echo "$json" | jq -r '.[] | "\(.url) \(.name) \(.isPrivate)"')

for repo in "${arr[@]}"; do
    IFS=' ' read -r url name isPrivate <<< "$repo"

    # Clone the repository to a temporary directory
    git clone "$url" "~/tmp/$name"

    cd "~/tmp/$name" || { echo "Failed to change directory"; continue; }

    # Remove the existing origin remote
    git remote remove origin

    # Add the new origin remote
    git remote add origin "git@$forge:$user/$name"

    # Push all branches to the new origin
    git push --all origin
    # SourceHut does not like high-speed automation and they say you should leave a minute between requests
    sleep 1m
    # Change back to the original directory
    cd - || exit
done