iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

git init

git init turns a directory into a Git repository by creating the .git/ folder, configuring the default branch, and giving you a clean working tree ready for your first commit. Get the first few minutes right and the project starts on solid footing.

init, branch, ignore, first commit

EXAMPLE
# 1) Initialise a brand-new repo
git init                              # current dir
git init my-app                       # creates ./my-app + ./my-app/.git
git init -b main                       # explicit default branch (recommended)

# If your global config already sets init.defaultBranch=main, -b is unnecessary.
git config --global init.defaultBranch main

# 2) What just happened?
# .git/
#   HEAD                — points at current branch (refs/heads/main)
#   config              — local repo config (remotes, branch tracking, etc.)
#   description         — used by GitWeb, mostly ignored
#   hooks/              — sample scripts (post-commit, pre-push, etc.)
#   info/exclude        — local-only ignore patterns (not committed)
#   objects/            — content-addressable storage (blobs, trees, commits)
#   refs/               — branches, tags, remote tracking refs

# 3) Set who you are (per-repo or globally)
git config user.name  'Mara Example'
git config user.email 'mara@example.com'
# Or globally for all repos
git config --global user.name  'Mara Example'
git config --global user.email 'mara@example.com'

# Verify
git config --list --show-origin       # values + where they're set

# 4) Useful first-time global defaults
git config --global init.defaultBranch  main
git config --global pull.rebase          true
git config --global rebase.autoStash     true
git config --global core.autocrlf         input   # macOS/Linux; 'true' on Windows
git config --global core.fileMode         true     # honour exec bit
git config --global help.autoCorrect      prompt  # suggest fixes for typos

# 5) Sign commits (recommended for production projects)
git config --global user.signingkey       'YOUR_SSH_OR_GPG_KEY_ID'
git config --global commit.gpgsign         true
git config --global gpg.format             ssh         # or 'openpgp'
git config --global gpg.ssh.allowedSignersFile ~/.config/git/allowed_signers

# 6) Add a .gitignore BEFORE your first commit
# Otherwise you'll commit node_modules or .env once, and removing them later is fiddly.
# Generate from a template:
curl -fsSL https://www.toptal.com/developers/gitignore/api/node,macos > .gitignore

# Example .gitignore for a Node project
node_modules/
.env
.env.*
!.env.example
dist/
build/
coverage/
*.log
.DS_Store
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
.idea/

# 7) First commit — verify what's staged BEFORE committing
git status
git add README.md package.json .gitignore
git status
git diff --staged              # exactly what's going into the commit
git commit -m 'chore: initialize repository'

# 8) Connect to a remote (after creating it on GitHub/GitLab)
git remote add origin git@github.com:me/my-app.git
git branch -M main             # make sure local branch is named 'main'
git push -u origin main        # -u sets upstream tracking

# Subsequent pushes
git push

# 9) Re-init — what if .git already exists?
# Safe: 'git init' is idempotent; it tops up missing files and leaves history alone.
# WARNING: rm -rf .git wipes ALL history. Only do it when you mean to start over.

# 10) Bare repos — for serving over SSH
git init --bare repo.git
# Bare repos have no working tree — used as the server-side authoritative copy.
# Clients run: git clone user@host:/srv/git/repo.git

# 11) Init from existing files
mkdir new-project && cd new-project
echo 'project goes here' > README.md
git init -b main
git add .
git commit -m 'chore: import existing project'

# 12) Init at a specific Git template
git init --template ~/my-git-templates/
# Useful for shared hooks, default .gitignore, and config defaults.

# 13) Convert a downloaded archive into a repo
unzip project-1.0.zip && cd project-1.0
git init -b main
git add -A
git commit -m 'import: project-1.0 baseline'

# 14) Common bugs at init
#   • Forgot to add .gitignore — committed node_modules; remove with:
#       git rm -r --cached node_modules && echo 'node_modules/' >> .gitignore && git commit -am 'fix: ignore node_modules'
#   • Default branch still 'master' on older Git — set init.defaultBranch=main
#   • Wrong user.email on first commits — rewrite with: git rebase -r --root --exec 'git commit --amend --reset-author -CHEAD'
#       (works but rewrites history — only on local-only branches)
#   • Initialised inside another repo (nested) — use git submodule or move the inner directory
#   • Pushed credentials in .env — rotate immediately AND rewrite history with git-filter-repo
#   • Cloned a template repo and forgot to remove origin — set new remote with 'git remote set-url origin <new>'

# 15) Verify a healthy fresh repo
git log --oneline           # at least one commit
git status                   # clean working tree
git branch -a                # local + remote branches
git remote -v                # origin (fetch + push)
git config --get user.email  # correct identity
git config --get init.defaultBranch  # main

Why it matters

Start every new repo with the right defaults: main as the default branch, a real .gitignore before the first commit, and user.email set correctly so the first commit isn’t attributed wrong. Sign commits if your project pushes to GitHub — SSH signing now works without GPG and reviewers can trust who wrote what.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
mkdir my-repo && cd my-repo
git init
ls .git/    # the staging metadata lives here
Try it Yourself »

Discussion

Loading…