OSCR

Git with GitHub

Clone, fetch, pull and push go straight to github.com, with GitHub's own credentials: OSCR runs no git server and no git proxy, and no git byte passes through it.

In the commands below, OWNER is the GitHub account and NAME the repository.

Clone, fetch, pull and push

Every repository's address is on github.com, as GitHub's Code button shows it. The daily round:

git clone https://github.com/OWNER/NAME.git
cd NAME
git fetch origin
git pull
git add analysis/
git commit -m "Describe the change"
git push origin main

Sources: Cloning a repository, Pushing commits to a remote repository, git clone, git push.

HTTPS, with a GitHub token as the password

Over HTTPS, git asks for a user name and a password. The user name is your GitHub account; the password is a personal access token you make on GitHub, never your GitHub password, which GitHub refuses for git. Make a token that reaches one repository and expires: tokens for git.

The credential cache

So that git does not ask each time, let a credential helper keep the token: cache keeps it in memory for a while, osxkeychain in the macOS keychain; Git Credential Manager does the same on every system.

git config --global credential.helper cache
git config --global credential.helper osxkeychain

Sources: Caching your GitHub credentials in Git,git credential-cache.

SSH, and the 2026 algorithm changes

Over SSH, git uses a key you add to your GitHub account instead of a token. The SSH address is on GitHub's Code button, under SSH. Since 2026-09-22 GitHub no longer accepts ssh-rsa signatures made with SHA-1 nor an old Diffie-Hellman key exchange, asks at least 3072 bits of a new RSA key, and offers a post-quantum key exchange (ML-KEM). An Ed25519 key avoids all of it:

ssh-keygen -t ed25519 -C "laptop"
ssh -T github.com

Sources: Connecting to GitHub with SSH, GitHub's changelog.

SHA-1 removed from HTTPS

GitHub stopped accepting SHA-1 signatures in HTTPS connections: a brownout on 2026-07-14, then for good on 2026-09-15. A clone or push that now fails with a TLS or handshake error comes from an old git, operating system or TLS library: update it. Sources: the announcement,the change.

Partial and shallow clones

A large repository can be cloned without all of it. A partial clone fetches every commit but a file's content only when a command needs it (blob:none), or even the directories (tree:0). A shallow clone fetches the last commit only; git log then sees little, and the history comes back with--unshallow.

git clone --filter=blob:none https://github.com/OWNER/NAME.git
git clone --filter=tree:0 https://github.com/OWNER/NAME.git
git clone --depth 1 https://github.com/OWNER/NAME.git
git fetch --unshallow

Sources: partial clone, git clone.

Clone error messages

Repository not found
The address is wrong, the repository was renamed or deleted, or it is private and the token cannot reach it. GitHub answers the same for a private repository as for an absent one.
Authentication failed, or HTTP status 401 or 403
The token is wrong, expired or revoked, or lacks the Contents permission on this repository: make a new one (tokens for git) and clear the old one from the credential helper.
Remote HEAD refers to nonexistent ref
The repository's default branch does not exist (an empty repository, or a branch renamed at the source): check out a branch that exists, with git switch.
A TLS or handshake error
An outdated git or TLS library: see SHA-1 removed from HTTPS.

Source: Troubleshooting cloning errors.

Push rejection messages

Rejected: fetch first, or non-fast-forward
The branch on GitHub has commits you do not have. Run git pull, then push again; never force a push over someone else's commits.
Repository rule violations, or a protected branch
A ruleset or a branch protection refused the push; git's output names the rule and what to change. Fix the commits locally (rewriting history), or push to another branch and open a pull request. Source: Troubleshooting rules.
Large files detected
A file is over 100 MiB: remove it from the commits (removing large files) and put it where large files go (large files).
Too many branch or tag updates
The repository's push policy limits the branches and tags one push may update (push policy): push them in several pushes.
Push declined due to email privacy restrictions
See Block pushes that expose my email, below.

Push protection warnings in the git push output

When push protection is on, GitHub refuses a push whose commits contain a secret it recognises (a token, a key), and git's output shows the kind of secret, the commit and the file, a few at a time. Revoke the secret first, since it is exposed on your computer and perhaps elsewhere; then remove it from the commits and push again. When it is a test value, the output gives a link where you may allow it. Sources:Push protection on the command line,what is scanned.

A push can also print warnings that do not refuse it: GitHub lists the known vulnerabilities in the repository's dependencies, with a link to the Dependabot alerts. Source:Dependabot notifications.

Block pushes that expose my email

Each commit records the author's email address as git is configured, and anyone who clones the repository can read it. GitHub gives your account a private "noreply" address instead. With "Keep my email addresses private" and "Block command line pushes that expose my email" on in your GitHub email settings, GitHub refuses a push whose commit carries your private address. Set git to the noreply address those settings show you, then amend the commit: git config --global user.email followed by that address, thengit commit --amend --reset-author. OSCR never shows an email address, and masks those it finds in commits. Source: Blocking command line pushes that expose your personal email address.

Creating and pushing tags

Tag the commit a paper describes, with an annotated tag, and push the tag: it is the version readers will cite, and a GitHub release can be made from it.

git tag -a v1.0.0 -m "Code as described in the paper"
git push origin v1.0.0
git push origin --tags

Signed by default

A signed tag proves who made it. Tell git to sign every annotated tag, with your SSH key (or a GPG key), and add the same key to your GitHub account as a signing key:

git config --global tag.gpgsign true
git config --global gpg.format ssh
git tag -v v1.0.0

Sources: Signing tags, Viewing releases and tags, git tag.

Command-line file operations

Moving, renaming and deleting files are commits like any other: make them with git, then push.git reset --soft undoes the last commit before a push and keeps its changes.

git mv old-name.py new-name.py
git rm unused.py
git add .
git commit -m "Rename and tidy"
git push
git reset --soft HEAD~1

Sources: Moving a file, Renaming a file,git mv.

Default branch name

GitHub names the first branch of your new repositories main unless you change it in your repository settings on GitHub; git's own setting does the same for the repositories you start on your computer.

git config --global init.defaultBranch main

Sources: Managing the default branch name for your repositories,git config.

Configuring the upstream remote

A fork follows the repository it came from through a second remote, by custom called upstream:

git remote add upstream https://github.com/UPSTREAM-OWNER/NAME.git
git remote -v
git fetch upstream

Sources: Configuring a remote repository for a fork,git remote.

Changing the remote URL

git remote set-url origin https://github.com/OWNER/NEW-NAME.git
git remote -v

Source: Managing remote repositories.

Updating local clones after a rename

After a repository is renamed or transferred, GitHub redirects its old address, but a new repository of the old name would end the redirect: change the remote URL of each clone (above). After a branch is renamed, each clone renames its own branch and follows the new one:

git branch -m master main
git fetch origin
git branch -u origin/main main
git remote set-head origin -a

Source: Renaming a repository.

The hosting guides