A repository is easy to create; choosing the wrong owner or pushing a forgotten .env file is just as easy. I like to pause at the New repository screen and decide whether GitHub should create the first commit or whether my laptop already owns that history. That one choice keeps the first push pleasantly boring.
Git and GitHub are different pieces
Git is the distributed version-control system that stores commits and branches locally.
GitHub hosts Git repositories and adds collaboration, permissions, pull requests, issues, automation, releases, and security features.
A local repository works without GitHub.
A GitHub repository can be edited in the browser, but cloning gives you a full local copy and history.
originis a conventional remote name, not a special GitHub keyword.
Decide ownership before creating anything
Personal owner: suitable for your own experiments and portfolio projects.
Organization owner: better for company/team continuity, policies, billing, teams, audit, and offboarding.
Public visibility: everyone can read the repository; never assume obscurity protects secrets.
Private visibility: access is limited, but credentials and regulated data still do not belong in Git history.
Internal visibility: available in eligible enterprise organizations and visible to enterprise members.
Repository transfers are possible, but starting under the durable owner avoids broken assumptions and policy gaps.
Path 1: create a repository in the browser
Sign in to
github.comand select the plus menu → New repository.Choose the correct personal account or organization in Owner.
Enter a short repository name using letters, numbers, hyphens, underscores, or periods as appropriate.
Write a description that says what the project does, not merely “my project.”
Choose Public, Private, or an available Internal option after reviewing who can read it.
For a brand-new project, optionally add a README, a language/framework
.gitignore, and a license you understand.Select Create repository.
Open Settings and confirm access, default branch, security features, and organization rules.
README, gitignore, and license are not decoration
README explains purpose, setup, usage, support, and contribution expectations.
.gitignoreprevents matching untracked files from being added; it does not protect already tracked files.A license states the permissions offered to other people; a public repository without a license is viewable but does not automatically grant broad reuse rights.
Choose a license based on project ownership and legal needs, not popularity.
For employer/client work, confirm authorization before selecting any public license or visibility.
Clone the new repository
git clone https://github.com/OWNER/REPOSITORY.git
cd REPOSITORY
git remote -v
git statusWhat those commands establish
git clonedownloads the repository, creates a working tree, and configuresorigin.Replace
OWNERandREPOSITORY; do not paste the placeholders literally.cdchanges into the new working directory.git remote -vshows fetch and push URLs so you can catch the wrong owner before publishing.git statusconfirms the branch and working-tree state without changing anything.HTTPS authentication uses GitHub-supported credentials; a normal account password is not accepted for Git command authentication.
Make and push the first local change
git status
git add README.md
git diff --cached
git commit -m "Document project setup"
git pushReview the exact commit, not just the command
git add README.mdstages one explicit file; usegit add .only after reviewing every untracked path.git diff --cacheddisplays the patch that will enter the commit.A commit records the staged snapshot locally with its author metadata and parent history.
git pushtransfers reachable commits to the configured upstream remote branch.Run tests and secret checks appropriate to the project before committing or pushing.
Path 2: publish an existing local project
On GitHub, create the repository under the correct owner but leave README, .gitignore, and license unchecked. An empty remote avoids a separate first commit. Then inspect the local project before initializing or changing anything.
pwd
git status
git remote -vThe inspection changes the next step
pwdproves which directory will become or already is the repository root.If
git statussucceeds, do not rungit initreflexively; inspect the existing branch and history.If it says “not a git repository,” initialize only this intended project directory.
An existing remote may point to another host or repository; never overwrite it until ownership is understood.
Nested Git repositories and copied
.gitdirectories need deliberate cleanup, not another initialization command.
Initialize a project that is not tracked yet
git init -b main
git status
git add README.md src/ .gitignore
git diff --cached
git commit -m "Initial project import"The first commit defines your public baseline
Git 2.28+ supports
git init -b main; older Git needs a separate branch-name step.Create and review
.gitignorebefore staging generated output, local configuration, IDE state, and dependencies.Explicit paths reduce accidental inclusion;
git status --shortis another useful review.A commit is local until push, giving you one more chance to inspect history.
Large binaries may need Git LFS; GitHub also enforces repository/push/file limits documented in its current guidance.
Connect the empty GitHub repository
git remote add origin https://github.com/OWNER/REPOSITORY.git
git remote -v
git branch --show-current
git push -u origin mainOrigin and upstream are now explicit
remote add originstores the GitHub URL under the conventional nameorigin.Verify the URL before push; a typo can publish to the wrong accessible repository.
git branch --show-currentreveals the actual local branch. Replacemainin the push if yours differs.-urecordsorigin/mainas the upstream, so latergit pushandgit pullknow the default relationship.The push changes remote state and may trigger Actions, webhooks, deployments, checks, or organization policies.
The GitHub CLI can do the handoff
gh auth status
gh repo create OWNER/REPOSITORY --private --source=. --remote=origin --pushRead the flags before running
gh auth statusdisplays whether the CLI is authenticated and which host/account is active.--privateis an explicit visibility choice; replace it with--publicor eligible--internalonly intentionally.--source=.uses the current local repository, so verify the directory first.--remote=originadds that remote name and--pushpublishes the commits.The command creates remote state immediately; confirm owner, name, visibility, history, and secrets first.
HTTPS or SSH remote
HTTPS works well with Git Credential Manager, GitHub CLI authentication, or an appropriately scoped token.
SSH uses a key pair associated with your GitHub account and an
git@github.com:OWNER/REPOSITORY.gitremote.Do not put a token directly in a remote URL that can appear in shell history, logs, or configuration.
Use separate identities/host configuration when personal and work GitHub accounts must remain distinct.
Changing transport does not change repository permissions; authentication identifies you, authorization decides what you may do.
Fix “remote origin already exists”
git remote -v
git remote get-url origin
git remote set-url origin https://github.com/OWNER/REPOSITORY.git
git remote -vDo not delete a remote you have not identified
The error means the name
originalready exists, not that GitHub rejected the repository.Inspect fetch and push URLs before changing them.
set-urlpreserves the remote name while replacing its URL.If the old remote is still useful, rename it with
git remote rename origin upstream-oldinstead of discarding it.Verify twice before the next push.
Fix “src refspec main does not match any”
There may be no commit yet; create a reviewed first commit.
The current branch may be named
masteror something else; inspectgit branch --show-current.Push the actual branch, or intentionally rename it with
git branch -M mainafter considering collaborators and automation.An empty repository has no branch to push until a commit exists.
Do not type branch-renaming commands merely to silence the error without understanding current history.
Fix non-fast-forward or unrelated histories
This usually happens when both GitHub and the local project created independent first commits. Do not force-push automatically. Decide which history should survive, fetch the remote, inspect both branches, and merge/rebase with a reviewed plan—or recreate the new remote as empty if nothing valuable exists there.
git fetch origin
git log --oneline --graph --decorate --all --max-count=30
git diff main..origin/mainInspection precedes reconciliation
fetchdownloads remote references without merging them into your branch.The graph reveals independent roots, unexpected commits, and branch names.
The diff helps identify README/license changes worth preserving.
--forcecan overwrite remote history; use protected branches and--force-with-leaseonly in an explicitly approved history rewrite.For a team repository, coordinate before rebasing, deleting, or replacing shared branches.
Authentication and permission failures
“Repository not found” can mean a wrong URL, missing access, wrong signed-in account, or genuinely missing repository.
Password authentication for Git over HTTPS is not supported; use GitHub CLI, credential manager, or an appropriately scoped token.
SSH “Permission denied (publickey)” requires checking the offered key, agent, GitHub account association, and host config.
Organization SSO or IP policies may require authorization beyond ordinary account access.
Protected branches/rulesets can require pull requests, reviews, signed commits, or passing checks instead of direct push.
Never solve a permission problem by making confidential code public.
Repository setup after the first push
Add a useful README, license decision, contribution instructions, code of conduct, and security reporting policy where appropriate.
Configure branch rules/rulesets and require pull requests/checks for important branches.
Review collaborators, teams, base permissions, outside collaborators, and deploy keys.
Enable applicable Dependabot, dependency review, secret scanning/push protection, and code scanning features.
Store automation credentials as scoped Actions secrets or use OIDC where supported; never commit them.
Configure topics, homepage, issue templates, releases, environments, and ownership (
CODEOWNERS) only when they serve the project.Protect default-branch deletion/force pushes and test backup/export or disaster recovery expectations.
A final verification loop
git status
git remote -v
git branch -vv
git log --oneline --decorate -5
git ls-remote --heads originWhat success looks like
The working tree contains only intentional changes.
Fetch and push URLs point to the durable owner and expected repository.
The local branch tracks the intended remote branch without unexplained divergence.
Recent commit subjects and identities are correct.
ls-remotecan read remote branch references with your current authentication.The GitHub page shows the expected files, commit, visibility, default branch, security settings, and no exposed secrets.
Primary references
GitHub’s official repository creation tutorial documents the browser workflow.
The current locally hosted code import guide covers Git, GitHub CLI, empty remotes, authentication, and the first push.
GitHub explains repository visibility and security, including public, private, and eligible internal access.
Review GitHub’s current security features and push protection before publishing sensitive or production projects.
Comments and corrections