Overview
The Git error “error: src refspec main does not match any” means Git can’t find a local ref named main to push. Common causes:
- You have no commits yet.
- Your local branch isn’t named
main(e.g., stillmaster). - You’re not on the
mainbranch (detached HEAD or a different branch). - Typo or case mismatch in the branch name.
This guide shows quick checks, a minimal working example, and fixes for developer machines and CI/CD.
Quickstart fix
- Verify you have at least one commit:
- If empty: add a file and commit, then push.
- Ensure you’re on a branch named
main:- Rename current branch to
mainor createmainand switch.
- Rename current branch to
- Push with upstream:
- Use
git push -u origin main(orgit push -u origin HEADif you’re on the right branch but named differently remotely).
- Use
Minimal working example
This creates a repo with main, makes an initial commit, sets a remote, and pushes without errors.
# Git 2.28+ supports -b main during init
mkdir demo && cd demo
git init -b main
echo "# Demo" > README.md
git add README.md
git commit -m "chore: initial commit"
git remote add origin [email protected]:you/demo.git
# First push sets upstream
git push -u origin main
If you have Git < 2.28 (no -b flag):
git init
# Create commit before renaming
echo "# Demo" > README.md
git add README.md
git commit -m "chore: initial commit"
# Rename default branch to main
git branch -M main
git remote add origin [email protected]:you/demo.git
git push -u origin main
Step-by-step troubleshooting
- Confirm you’re in a Git repo
git rev-parse --show-toplevel
If this errors, cd into the correct repository directory.
- Check your current branch and commits
git status
git branch --show-current
git log --oneline -n 1
- If there’s “no commits yet”, create one:
git add .
git commit -m "chore: initial commit"
- Verify the
mainbranch exists locally
git rev-parse --verify main
- If this fails, either create/switch to
main:
git switch -c main # or: git checkout -b main
- Or push the branch you actually have (e.g.,
master):
git push -u origin master
- Rename your current branch to
main(if desired)
git branch -M main
- Set the remote and push
git remote -v
# Add if missing
# git remote add origin <ssh-or-https-url>
git push -u origin main
- If you’re on the right branch but ref name differs
# Push current branch to a main branch on remote
git push -u origin HEAD:main
- Fix detached HEAD If
git statussays “HEAD detached”, attach it to a branch:
git switch -c main # creates main from current commit
Then push.
- Check spelling and case Branch names are case-sensitive. Ensure
mainis lower-case.
Common scenarios and fixes
| Scenario | Symptom | Fix |
|---|---|---|
| No commits yet | git log empty; initial push fails | Add and commit at least one file, then push |
Branch is master | git branch shows master, not main | git branch -M main then git push -u origin main or push master |
| On another branch | git branch --show-current is not main | git switch main (or create it) and push |
| Detached HEAD | Status shows “HEAD detached” | git switch -c main and push |
| Typo in refspec | main misspelled | Correct the branch name |
| CI working dir wrong | CI step not in repo path | cd into repo path before pushing |
CI/CD specifics (DevOps)
- Ensure checkout happens before push (e.g., actions/checkout or equivalent).
- Confirm the job has write permissions and valid credentials (SSH key or token with push scope).
- Use explicit refs to avoid ambiguity:
git push origin HEAD:main # push the checked-out commit to main
- In ephemeral runners, always create the initial commit if pushing a brand-new repo.
Pitfalls
- Renaming before first commit on Git < 2.28:
git branch -M mainfails with no commits. Make a commit first. - Mixing HTTPS and SSH remotes inconsistently can cause auth or URL confusion. Verify with
git remote -v. - Pushing from a submodule directory instead of the root repo can fail with confusing errors.
- Assuming remote default branch controls local branch name; it does not. You must create/rename locally.
- Case-sensitive filesystems and branch names:
Main≠main.
Performance notes
- Create the minimal initial commit early to avoid repeated large staging operations in CI.
- Avoid pushing large binaries; use .gitignore or Git LFS to keep pushes fast and histories small.
- Shallow clones in CI (
--depth 1) are fine for build steps, but when pushing, ensure your branch history is present. - Keep repositories healthy with occasional maintenance in long-lived repos:
git gc --aggressive --prune=now
- Network compression is enabled by default; unreliable networks can still fail pushes—use retries in CI.
FAQ
Why does this happen on brand-new repos? Because there’s no commit yet. Git only pushes commits; make one first.
Do I need a remote
mainto push? No.git push -u origin maincreatesmainon the remote if your localmainexists.I want to keep
master. Is that okay? Yes. Pushmasterwithgit push -u origin master, or map it tomainviaHEAD:main.How do I check my Git version?
git --version
If < 2.28, you can’t git init -b main; rename after the first commit.
- How do I set upstream after the first push?
git push -u origin main # sets upstream
# Later pushes can be: git push