OSCR

Import a repository

Code from GitLab, Bitbucket, Codeberg or any git host, a Zenodo, figshare or OSF record, or your paper's code links: the commands that import it on your own computer into your GitHub account, every commit id kept.OSCR runs no import and sees none of your credentials.

The commands, by hand

In these commands OWNER is your GitHub account, NAME the new repository, and the first address the source's. Create the repository first, empty (create a repository, with no README), then:

git clone --mirror 'https://gitlab.com/LAB/NAME.git' 'NAME.git'
cd 'NAME.git'
# Branches and tags only: the source's hidden refs (pull and merge requests) stay behind.
git config --replace-all remote.origin.fetch '+refs/heads/*:refs/heads/*'
git config --add remote.origin.fetch '+refs/tags/*:refs/tags/*'
git for-each-ref --format='delete %(refname)' refs/pull refs/pull-requests refs/merge-requests refs/pipelines refs/keep-around refs/environments | git update-ref --stdin
git push --mirror 'https://github.com/OWNER/NAME.git'

git clone --mirror and git push --mirror keep every branch, tag and commit id. The two refspecs fetch branches and tags only, and the line with git for-each-ref deletes the source's hidden refs (pull and merge requests), which GitHub refuses on a push. When the source uses Git LFS, its large files move with two more lines:

git clone --mirror 'https://gitlab.com/LAB/NAME.git' 'NAME.git'
cd 'NAME.git'
# Branches and tags only: the source's hidden refs (pull and merge requests) stay behind.
git config --replace-all remote.origin.fetch '+refs/heads/*:refs/heads/*'
git config --add remote.origin.fetch '+refs/tags/*:refs/tags/*'
git for-each-ref --format='delete %(refname)' refs/pull refs/pull-requests refs/merge-requests refs/pipelines refs/keep-around refs/environments | git update-ref --stdin
git lfs fetch --all origin
git push --mirror 'https://github.com/OWNER/NAME.git'
git lfs push --all 'https://github.com/OWNER/NAME.git'

An SSH source works the same: use the address its Clone button shows under SSH.

A Zenodo, figshare or OSF record

An archive has no history: its files become the first commit of the repository, and the commit's message cites the record's DOI.

mkdir 'NAME'
cd 'NAME'
git init -b main
curl -L --fail -o ../record.zip 'https://zenodo.org/records/1234567/files-archive'
unzip ../record.zip
git add -A
git commit -m 'Import the files of the Zenodo record doi:10.5281/zenodo.1234567' -m 'Source: https://doi.org/10.5281/zenodo.1234567. An archive has no history: this commit holds the files as published in the record.'
git remote add origin 'https://github.com/OWNER/NAME.git'
git push -u origin main

Submodules

A mirror copies a repository, not the repositories it names as submodules: those still point to their own addresses. List them; import each one the same way if it should move too; then point the submodule to its new address.

git submodule status
git config --file .gitmodules --get-regexp url
git submodule set-url PATH/TO/SUBMODULE https://github.com/OWNER/SUBMODULE.git
git commit -am "Point the submodule to its new home"
git push

More