The Right Way to Set Up Your Salesforce SFDX Project with Git — No Conflicts, No Ref Errors
- Rao
- May 15
- 3 min read

"Do I create the Git repo first or the project first?"" Why does Git throw push ref errors even though it's a brand-new project?"
These are classic setup confusions that trip up even experienced Salesforce engineers when working with SFDX source format and Github for the first time.
And almost always, people follow imprecise, conflicting steps.
They create the project locally, or they create the repo remotely first.
They try to push, and they hit ref errors.
They scramble around Git commands.
And they lose trust in the whole process.
The problem is not your tools. It's the way you start. In this article, I’ll show you the exact step-by-step process that works — clean, conflict-free, and safe for enterprise GitHub workflows.
The two wrong patterns most engineers unknowingly follow (and why they fail)
Pattern 1: Local-first, then pushing to non-empty remote — ends in ref errors
Engineer creates SFDX standard source format project locally in VS Code.
Initializes Git locally (git init).
Adds metadata, commits locally.
Adds remote repo (which was already created with a README, .gitignore, etc. in enterprise GitHub).
Tries to push:
git push origin main
Gets this error:
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'https://github.mycompany.com/team/salesforce-core.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
Root cause:
The remote has an initial commit (like README).
Your local has a different initial commit.
Git refuses to fast-forward — it demands you first pull and merge, which leads to unwanted conflicts on day one.
Pattern 2: Remote-first with README, cloned locally — leads to path confusion and push chaos
Engineer creates new GitHub repo from enterprise GitHub portal.
Adds README during repo creation.
Clones the repo locally in VS Code.
Creates the SFDX project inside the cloned folder.
Tries to push metadata.
Ends up seeing:
Confusion in source paths (force-app not showing properly).
Push errors when syncing metadata
Root cause:Cloning a repo that already has a README sets a remote baseline.When you create SFDX project inside the same folder, your local commits try to sit on top of a different commit history (from README), leading to ref errors, path confusions
The exact, correct sequence (learned the hard way)
Here’s the battle-tested sequence I follow, with no ambiguity.
1. Create an empty GitHub repo
Go to your enterprise GitHub (https://github.mycompany.com).
Create the repo.
IMPORTANT:
Do NOT add README, LICENSE, or .gitignore.
Keep it completely empty.
Why? This ensures remote is literally empty, ready to accept your local repo as the first push. You avoid all push ref errors right at the root.
2. Create local SFDX project in VS Code (standard source format)
Use SFDX: Create Project → Standard.
Confirm project has force-app, sfdx-project.json.
Double-check your folder is clean with only Salesforce standard project structure.
3. Authorize to Production org
Use:
sfdx auth:web:login -r https://login.salesforce.com
Pull metadata (initial download) from Production, not Sandbox.
You can use VS Code Org Browser for that
Or use commands from CLI for metadata types Org Browser may not support
sfdx force:source:retrieve
Why Prod? You want your initial repo to have the latest clean metadata baseline from production. Engineers later will point to their Sandboxes, but this gives a single source of truth for the repo initialization.
4. Initialize Git locally
git init
git branch -m main
Confirm current branch:
git branch --show-current
5. Add and commit all metadata
git add .
git commit -m "Initial commit"
Optional (only if Git config is missing on your local machine):
git config user.email "you@yourcompany.com"
git config user.name "Your Name"
6. Connect to your empty GitHub repo
git remote add origin https://github.mycompany.com/team/salesforce-core.git
Validate:
git fetch origin
7. Push your clean initial commit
git push origin main
Expected result: Clean push, no ref errors, no history mismatches. Your initial repo is now perfectly aligned between local and remote.
Comments