GitHub 04 ๐ Creating and Initializing a Repository (Public vs Private)
A repository is the container that holds a project’s files and their complete revision history. Creating one on GitHub is a four-step form: name it, choose who can see it, optionally seed it with starter files, and click create. The visibility choiceโpublic or privateโis the only decision that cannot be changed without consequences, and the consequences are asymmetric.
This chapter covers the repository creation workflow from the web UI and the GitHub CLI, the distinction between public and private visibility, and the initialization options that determine whether the repository starts empty or with a README, .gitignore, and license. It assumes the account and authentication setup from the previous chapters.
Key point: A repository created without starter files is completely empty. It has no commits, no branches, and no README. Cloning it produces an empty directory with a .git folder and a warning that you have cloned an empty repository.
Why visibility is the decision that matters
The public default. A public repository is visible to anyone on GitHub, and anyone can clone it, fork it, and read its entire history . This is the correct choice for open-source projects, portfolios, and anything intended to be shared. The code is not just visible; it is forkable, which means the history travels with it.
The private default. A private repository is visible only to the owner and the collaborators who are explicitly invited . This is the correct choice for proprietary code, work in progress, and anything that contains secrets, customer data, or unreleased features.
The one-way visibility trap. Visibility can be changed later in the repository settings, but the change is not symmetric. Switching a private repository to public exposes its entire history, including any secrets that were committed and later removed . The commit that contained the secret is still in the history, and anyone who clones the now-public repository can retrieve it. The rule is: if there is any doubt, start private. Making a public repository private is safe from a secrecy perspective, but it detaches forks and erases stars and watchers .
The organization restriction. In an organization, the ability to change visibility may be restricted to organization owners . A repository created as public by a member may not be changeable to private without the owner’s intervention. The visibility choice at creation is the one the creator controls.
a. Creating a repository from the web UI
The creation page is reached from the + menu in the upper-right corner of any GitHub page, then New repository . The URL https://github.com/new goes directly to the form.
The form has four sections. The owner dropdown selects the personal account or an organization where the creator has permission to create repositories . The repository name is limited to 100 characters, and it becomes part of the URL. The description is optional and appears on the repository page. The visibility radio buttons select public or private .
The initialization options are the checkboxes below the visibility. A README creates a README.md with the repository name as the heading and a placeholder description. A .gitignore template adds a file that excludes common build artifacts for the selected language. A license adds a LICENSE file with the chosen open-source license . If none of these are checked, the repository is created with no commits and no files.
The sequence is:
1. Click + โ New repository
2. Owner: your username or an organization
3. Name: my-project
4. Description: optional
5. Visibility: Public or Private
6. Add README: optional
7. Add .gitignore: optional
8. Choose a license: optional
9. Create repository
b. Creating a repository with the GitHub CLI
The gh repo create command creates a repository from the terminal. The interactive form asks for the name, visibility, and whether to clone the new repository locally. The non-interactive form uses flags.
# Interactive: prompts for name, visibility, and clone.
gh repo create
# Non-interactive: public repository, no clone.
gh repo create my-project --public
# Private repository, cloned locally.
gh repo create my-project --private --clone
# Repository in an organization.
gh repo create my-org/my-project --public
The CLI creates the remote repository on GitHub. The --clone flag clones it to the current directory, which is the equivalent of creating the repository on the web and then running git clone . Without --clone, the repository exists on GitHub only, and the local directory must be connected to it manually.
c. The empty repository and the first push
A repository created without starter files is completely empty. It has no default branch, no commit, and no files. The GitHub page after creation shows the two commands for connecting a local repository.
# Connect an existing local repository to the empty remote.
git remote add origin https://github.com/username/my-project.git
git branch -M main
git push -u origin main
The git branch -M main renames the current branch to main if it was created as master. The git push -u origin main pushes the local commits to the remote and sets the upstream tracking . If the local directory has no commits yet, the push fails with “src refspec main does not match any.” The fix is to commit first.
A repository created with a README already has a commit and a default branch. The clone command is the standard one, and the local repository starts with the README file.
Complete Example Session
# ============================================
# PART 1: THE WEB UI CREATION
# ============================================
# + โ New repository
# Name: my-project
# Visibility: Private
# Add README: checked
# Create repository
# ============================================
# PART 2: THE CLI CREATION
# ============================================
gh repo create my-project --private --clone
# ============================================
# PART 3: THE EMPTY REPOSITORY
# ============================================
# Created without README or .gitignore.
# The page shows the connection commands.
git remote add origin https://github.com/username/my-project.git
git branch -M main
git push -u origin main
# ============================================
# PART 4: THE INITIALIZED REPOSITORY
# ============================================
# Created with README.
# The clone command works immediately.
git clone https://github.com/username/my-project.git
# ============================================
# PART 5: THE VISIBILITY CHECK
# ============================================
# Confirm the repository is private or public.
gh repo view username/my-project --json visibility
# ============================================
# PART 6: THE STARTER FILES
# ============================================
# README.md: project description.
# .gitignore: build artifacts.
# LICENSE: open-source terms.
# ============================================
# PART 7: THE LOCAL-FIRST ALTERNATIVE
# ============================================
# Create the repository locally first.
git init my-project
cd my-project
echo "# My Project" > README.md
git add README.md
git commit -m "Initial commit"
gh repo create my-project --private --source=. --push
# ============================================
# PART 8: THE VISIBILITY CHANGE
# ============================================
# Settings โ Danger Zone โ Change visibility.
# Warning: private โ public exposes the full history.
# ============================================
# PART 9: THE ORGANIZATION CASE
# ============================================
# The owner dropdown selects the organization.
# The creator must have permission to create repos.
gh repo create my-org/my-project --private
# ============================================
# PART 10: THE FULL PICTURE
# ============================================
# Name, visibility, and starter files.
# Public: visible to all, forkable.
# Private: visible to owner and collaborators.
# Visibility change: private โ public exposes history.
echo "Repository creation complete."
The ten parts walk through the web UI, the CLI, the empty repository, the initialized repository, and the local-first alternative. The pattern is consistent: the remote is created on GitHub, and the local repository is either cloned from it or connected to it.
Quick Reference
Creation Methods
| Method | Command / Path |
|---|---|
| Web UI | + โ New repository or https://github.com/new |
| CLI interactive | gh repo create |
| CLI flags | gh repo create name --private --clone |
| Local-first | gh repo create name --source=. --push |
Visibility
| Visibility | Who Sees It | Typical Use |
|---|---|---|
| Public | Anyone on GitHub | Open source, portfolios |
| Private | Owner and collaborators | Proprietary, WIP |
Starter Files
| File | Effect |
|---|---|
| README | Creates README.md, initializes the repository |
.gitignore | Excludes build artifacts for a language |
| LICENSE | Adds open-source license terms |
Visibility Change Consequences
| Change | Consequence |
|---|---|
| Private โ Public | Full history exposed, including removed secrets |
| Public โ Private | Forks detached, stars erased |
| Private โ Public | Anyone can fork |
Best Practices
โ Do This:
# Start private if there is any doubt.
# Private โ public exposes the full history. // โ
# Use the CLI for repeatable creation.
gh repo create name --private --clone // โ
# Add a README to initialize the repository.
# Without it, the repository is empty. // โ
# Use a .gitignore template.
# Prevents accidental commits of build artifacts. // โ
โ Don’t Do This:
# Don't create public if the repository may contain secrets.
# The history is exposed on visibility change. // โ
# Don't assume a new repository has a default branch.
# Empty repositories have no branch until the first push. // โ
# Don't push to an empty repository without a local commit.
# The push fails with "src refspec does not match". // โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Push fails: “src refspec” | Local repository has no commits | git add and git commit first |
| Repository is empty after clone | Created without starter files | Expected behavior; add files and push |
| Visibility cannot be changed | Organization restricted it to owners | Contact the organization owner |
| Secrets exposed after visibility change | History contains the secret | Delete the repository and recreate, or rewrite history |
| CLI clone fails | --clone not passed | Run git clone manually |
Real-World Examples
1. Web UI Creation
+ โ New repository โ name, visibility, README โ Create
2. CLI Private Clone
gh repo create my-project --private --clone
3. Empty Repository Connection
git remote add origin https://github.com/user/repo.git && git push -u origin main
4. Local-First Creation
git init && git add . && git commit -m "init" && gh repo create --source=. --push
5. Visibility Check
gh repo view user/repo --json visibility
6. Organization Repository
gh repo create my-org/repo --private
7. Clone Initialized Repository
git clone https://github.com/user/repo.git
8. Change Visibility
Settings โ Danger Zone โ Change visibility
9. README Initialization
Checked: creates README.md, repository has one commit
10. .gitignore Initialization
Checked: creates .gitignore for the selected language
Visual
The Creation Form
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ NEW REPOSITORY โ
โ โ
โ Owner: [username โผ] โ
โ Name: [my-project ] โ
โ Description:[optional ] โ
โ โ
โ Visibility: โ Public โ Private โ
โ โ
โ Initialize: โ
โ โ Add a README file โ
โ โ Add .gitignore [None โผ] โ
โ โ Choose a license [None โผ] โ
โ โ
โ [Create repository] โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Empty vs Initialized
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ WITHOUT STARTER FILES โ
โ Repository: no commits, no branches, no files โ
โ Clone: empty directory + warning โ
โ Push: requires local commit first โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ WITH README โ
โ Repository: one commit, default branch, README.md โ
โ Clone: directory with README.md โ
โ Push: works immediately โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Visibility Trap
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PRIVATE REPOSITORY โ
โ Commit 1: adds config with API key โ
โ Commit 2: removes the key โ
โ History: both commits exist โ
โ โ โ
โ โผ visibility changed to public โ
โ Anyone can clone and see Commit 1. โ
โ The key is exposed. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Local-First Flow
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ git init my-project โ
โ โ โ
โ โผ โ
โ git add . && git commit -m "init" โ
โ โ โ
โ โผ โ
โ gh repo create my-project --source=. --push โ
โ โ โ
โ โผ โ
โ Remote created on GitHub, local pushed โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Web UI URL | https://github.com/new |
| CLI command | gh repo create |
| Public | Visible to anyone, forkable |
| Private | Owner and collaborators only |
| Starter files | README, .gitignore, license |
| Empty repository | No commits, no branch |
| Visibility change | Private โ public exposes history |
| Organization restriction | Owners may restrict visibility changes |
Key takeaways:
- Visibility is the decision with consequences. A public repository is visible and forkable by anyone. A private repository is restricted. The choice is reversible, but private โ public exposes the full history .
- Starter files determine the initial state. A README creates a commit and a default branch. No starter files leaves the repository completely empty.
- An empty repository cannot be pushed to without a local commit. The
git pushfails with “src refspec does not match any” if the local repository has no commits. - The CLI is the repeatable path.
gh repo create name --private --clonecreates the remote and clones it locally in one command. - The local-first flow is the alternative. Initialize the repository locally, commit, and use
gh repo create --source=. --pushto create the remote and push in one step. - Organization permissions may restrict visibility changes. The creator may not be able to change a public repository to private without the owner .
Remember: Creating a repository is a form with four decisions: name, owner, visibility, and starter files. The name determines the URL, the owner determines who controls it, the visibility determines who sees it, and the starter files determine whether the repository begins with a commit or with nothing. The visibility is the only decision that carries a lasting risk, and the risk is asymmetric: making a public repository private is safe from a secrecy perspective, but making a private repository public exposes everything that was ever committed. Start private if there is any doubt.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!