Git Init Explained: How to Initialize a Git Repository Step-by-Step (Complete Beginner's Guide)


Git Init Explained: How to Initialize a Git Repository Step-by-Step (Complete Beginner's Guide)


Introduction

Every Git project starts with a single command: git init. It's the first thing you run when you begin tracking a project with version control, and understanding exactly what it does — not just how to type it, but what happens when you do — makes everything else in Git click into place.

This guide is written for beginners who are just getting started with Git, developers who use Git but never quite understood what's actually happening under the hood, and students who need to set up version control for a project. It covers what Git is, what a repository actually is, exactly what git init creates, the full workflow from initialization to GitHub, every git init option, common mistakes and how to avoid them, and real project examples across different tech stacks.

By the end you'll be able to initialize any project confidently, understand what you're doing and why at each step, and know how to connect your local repository to GitHub for backup and collaboration.


What is Git?

Before git init makes sense, Git itself needs to be clear.

Git is a distributed version control system — software that tracks changes to files over time so you can recall specific versions, see exactly what changed and when, and collaborate with others without overwriting each other's work.

Without Git (or some version control system), you'd manage versions manually: project_final.zip, project_final_v2.zip, project_ACTUALLY_final.zip. Anyone who has done this knows exactly how badly it breaks down. Git replaces that chaos with a clean, structured history of every meaningful change ever made to a project.

Git is distributed, which means every developer has a complete copy of the project history on their machine. There's no single "master" copy that everyone depends on — this makes Git fast, offline-capable, and resilient.

Git was created by Linus Torvalds in 2005 to manage the development of the Linux kernel. It's now the standard version control system used by essentially every software project in the world, from a student's first assignment to the Linux kernel itself.


What is a Git Repository?

A Git repository (repo) is a project folder that Git is tracking. It contains:

  • Your actual project files (code, assets, documentation)
  • A hidden .git folder that stores all of Git's tracking data (history, configuration, branches, commits)

The .git folder is what makes an ordinary folder a Git repository. When you run git init, you're asking Git to create that .git folder and start tracking the project.

Two types of repositories:

Type Description Use Case
Local repository On your machine, has working directory Your daily development
Remote repository Hosted on GitHub/GitLab/Bitbucket Backup, collaboration, sharing

A project typically has one local repository per developer and one remote repository that everyone syncs to.


What Does git init Actually Do?

When you run git init in a directory, Git creates a hidden .git subfolder containing everything Git needs to track your project. Before git init:

my-project/
├── index.html
├── style.css
└── script.js

After git init:

my-project/
├── .git/          ← hidden folder (this is the repository)
│   ├── HEAD
│   ├── config
│   ├── description
│   ├── hooks/
│   ├── info/
│   ├── objects/
│   └── refs/
├── index.html
├── style.css
└── script.js

Your project files are untouched. Git just added the .git folder.


Inside the .git Folder

Most tutorials treat .git as a black box. Understanding what's inside makes Git much less mysterious.

.git/
├── HEAD           ← Points to the current branch you're on
├── config         ← Local repository configuration (author, remote URLs, etc.)
├── description    ← Repository description (mainly for GitWeb)
├── hooks/         ← Scripts that run automatically on Git events (pre-commit, post-push, etc.)
├── info/
│   └── exclude    ← Local .gitignore that isn't committed (only for this machine)
├── objects/       ← All commits, trees, and file contents are stored here as hashed objects
│   ├── info/
│   └── pack/
└── refs/          ← References (pointers to commits)
    ├── heads/     ← Local branches (refs/heads/main = your main branch's latest commit)
    └── tags/      ← Tags (named references to specific commits)

What each piece does:

HEAD: A pointer to the current branch. When you switch branches with git checkout or git switch, HEAD updates to point to the new branch. It's how Git knows "where you are" in the repository.

config: Local settings for this repository — the remote URL, author name/email overrides, merge preferences. When you run git remote add origin <url>, it writes to this file.

objects/: This is where all your actual data lives. Every file version, every commit, every directory structure is stored here as a SHA-1 hashed object. Git never stores file diffs — it stores complete snapshots, compressed and deduplicated.

refs/heads/: When you make a commit on main, Git updates refs/heads/main to point to that new commit's hash. That's all a branch is — a named file containing a commit hash.

hooks/: Scripts that run automatically at specific points in the Git workflow. A pre-commit hook runs before every commit (useful for running linters or tests automatically). The sample files in this folder have .sample extension so they don't run until you rename them.


Prerequisites

Before running git init, you need:

1. Install Git:

# macOS (using Homebrew)
brew install git

# Ubuntu/Debian Linux
sudo apt-get install git

# Windows
# Download Git for Windows from git-scm.com

2. Configure your identity (only needed once per machine):

git config --global user.name "Your Name"
git config --global user.email "youremail@example.com"

Git records your name and email with every commit. If you skip this, commits will have no author information.

3. Verify installation:

git --version
# Expected output: git version 2.x.x

The Git Workflow

Here's the big picture of how Git works from initialization to GitHub. Every step in this diagram will make sense by the end of this guide:

Create/Navigate to project folder
           │
           ▼
       git init
    (Creates .git folder)
           │
           ▼
   Create/edit files
           │
           ▼
       git add .
  (Stage files for commit)
           │
           ▼
   git commit -m "message"
    (Save snapshot to history)
           │
           ▼
  git remote add origin <url>
     (Link to GitHub)
           │
           ▼
    git push -u origin main
     (Upload to GitHub)
           │
           ▼
    Continue: edit → add → commit → push

Step-by-Step: Initialize a New Project

Step 1: Create and enter your project folder

mkdir my-project
cd my-project

mkdir creates the folder. cd enters it. You can also create the folder in your file manager and navigate there in your terminal.

Step 2: Run git init

git init

Expected output:

Initialized empty Git repository in /path/to/my-project/.git/

If you see this, the repository was created successfully. The .git folder now exists (hidden by default in most file managers — show hidden files to see it).

Step 3: Check status

git status

Output on a fresh repository with no files:

On branch main

No commits yet

nothing to commit (create/copy files and start working)

Step 4: Create some files and check status again

# Create a simple README
echo "# My Project" > README.md
git status

Output:

On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        README.md

nothing added to commit but untracked files present (use "git add" to track)

Git can see the file but isn't tracking it yet. "Untracked" means Git knows the file exists but hasn't been told to include it in version control.

Step 5: Stage files

git add .

The . adds all files in the current directory (and all subdirectories) to the staging area. The staging area is a preparation zone — you choose which changes to include in your next commit before actually saving them.

To add a single specific file instead:

git add README.md

Step 6: Make your first commit

git commit -m "Initial commit"

Output:

[main (root-commit) a1b2c3d] Initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

A commit is a permanent snapshot of your staged files saved to the repository's history. The -m flag provides the commit message. The hash (a1b2c3d) is a short version of the unique SHA-1 identifier for this commit.

Step 7: Connect to GitHub (Optional but Standard)

Create a new repository on github.com (don't initialize it with a README — you already have one locally). Then:

git remote add origin https://github.com/yourusername/my-project.git
git push -u origin main

git remote add origin saves the GitHub URL as a named remote called origin. git push -u origin main uploads your commits and sets origin/main as the default tracking branch for future pushes (so you can just type git push afterward).


Initialize an Existing Project

If you already have a project folder with files and want to start tracking it with Git:

cd existing-project
git init
git add .
git commit -m "Initial commit: add existing project files"

That's it. The files are untouched — Git just starts tracking them from this point forward.


All git init Options

Most tutorials only cover the basic git init. Here are all the options:

git init (basic)

git init

Creates a new repository in the current directory. This is what you use 95% of the time.

git init [directory]

git init my-new-project

Creates a new folder named my-new-project and initializes it as a Git repository in one step. Equivalent to mkdir my-new-project && cd my-new-project && git init.

git init --bare

git init --bare

Creates a "bare" repository — one that has no working directory, only the .git contents. Bare repositories are used as centralized shared repositories on servers. When you push to GitHub, you're pushing to a bare repository on GitHub's servers. You wouldn't work directly in a bare repository; you'd only push to and pull from it.

git init --initial-branch=main

git init --initial-branch=main

Sets the default branch name. Older versions of Git defaulted to master. Modern Git (2.28+) defaults to main (configurable). If your Git version creates master by default and you want main, use this flag.

To set the default globally so every new repository uses main:

git config --global init.defaultBranch main

git init --shared

git init --shared

Sets permissions so a group of users can share the repository. Used for setting up shared servers where multiple team members need write access to the same repository.


Real Project Examples

Example 1: Initialize a Web Project

mkdir portfolio-site
cd portfolio-site

# Create project files
touch index.html style.css script.js
mkdir images

git init
git add .
git commit -m "Initial commit: create project structure"

Example 2: Initialize a Python Project

mkdir data-analysis
cd data-analysis

# Create virtual environment and project files
python3 -m venv venv
touch main.py requirements.txt README.md

# Create .gitignore to exclude virtual environment
echo "venv/" > .gitignore
echo "__pycache__/" >> .gitignore
echo "*.pyc" >> .gitignore

git init
git add .
git commit -m "Initial commit: Python project setup"

Note the .gitignore file: it tells Git which files and folders to ignore. The venv/ folder contains thousands of library files that shouldn't be committed — only requirements.txt (which lists dependencies) needs to be tracked.

Example 3: Initialize a Node.js Project

mkdir my-node-app
cd my-node-app

npm init -y  # Creates package.json

# Create .gitignore before adding
echo "node_modules/" > .gitignore

git init
git add .
git commit -m "Initial commit: Node.js project with package.json"

node_modules/ often contains hundreds of megabytes of installed packages. Always .gitignore it and commit only package.json — anyone who clones the project can run npm install to restore the packages.

Example 4: Initialize a React Project

npx create-react-app my-react-app
cd my-react-app

# create-react-app already runs git init automatically
# Verify:
git log --oneline
# Should show: "Initialize project using Create React App"

Many project scaffolding tools (create-react-app, npm create vite@latest, Django, etc.) run git init automatically. Check before running it yourself — running git init inside an existing Git repository is harmless but unnecessary.


Command Comparison Table

Command What it does When to use
git init Creates a new local repository Starting a new project from scratch
git clone <url> Downloads an existing repository Starting from someone else's project
git add <file> Stages specific file for commit When you want to commit specific files
git add . Stages all changed files When you want to commit everything
git commit -m "msg" Saves staged changes as a snapshot After staging, to record your changes
git status Shows current state of working directory Any time you want to see what's changed
git log Shows commit history Reviewing what was changed and when
git remote add origin <url> Links local repo to a remote URL Before your first push to GitHub
git push Uploads local commits to remote After committing, to sync to GitHub
git pull Downloads and merges remote changes Before starting work, to get others' changes

When NOT to Use git init

Don't run git init if:

  1. You cloned the repository. git clone already initializes the repository — running git init afterward is redundant (though harmless, it reinitializes the existing one).

  2. The project already has a .git folder. Check with ls -a (Mac/Linux) or dir /a (Windows). If .git is there, Git is already set up.

  3. You're inside another Git repository. Running git init in a subdirectory of an existing repo creates a "nested" repository, which causes confusing behavior and is almost never what you want.

  4. You want to contribute to an existing project. Use git clone to download it first, then work in your clone.

How to check if you're already in a Git repository:

git rev-parse --is-inside-work-tree
# Returns: true (you're in a repo) or an error (you're not)

Common Mistakes (And How to Fix Them)

Mistake 1: Forgetting .gitignore before the first commit

If you commit node_modules/, venv/, .env files, or build artifacts, they're in the history. Even deleting them later doesn't remove them from previous commits (someone could still see them by checking out that commit).

Fix: Always create .gitignore before your first git add. GitHub provides template .gitignore files for every major language at github.com/github/gitignore.

Mistake 2: Using the wrong branch name

Older Git defaults to master; modern Git defaults to main. If you initialize with master but GitHub expects main (or vice versa), git push will fail or create an unexpected branch.

Fix: Set the default globally once:

git config --global init.defaultBranch main

Mistake 3: Committing sensitive files

API keys, passwords, and private configuration files (config.py, .env, secrets.json) should never be committed — even in private repositories.

Fix: Add them to .gitignore immediately. If you accidentally committed a secret, it's not enough to delete it in the next commit — it's still in the history. Use git filter-repo (or contact GitHub support for private repos) to fully remove it, and rotate the compromised credential immediately.

Mistake 4: Forgetting git add before git commit

git commit only commits staged files. If you changed a file but didn't run git add, the changes won't be in the commit.

Fix: Check git status before every commit to see what's staged vs. unstaged. Or use git commit -am "message" which stages and commits all tracked (already-added) modified files in one step. Note: -a doesn't add brand-new untracked files — only files Git is already tracking.

Mistake 5: Running git push without setting the remote first

fatal: 'origin' does not appear to be a git repository

Fix: Link to the remote before pushing:

git remote add origin https://github.com/username/repo.git
git push -u origin main

Mistake 6: Initializing in the wrong directory

If you run git init from your home directory by accident, Git will track everything in your home folder.

Fix: Always cd to your specific project folder first, then run git init. Check where you are with pwd (Mac/Linux) or cd alone (Windows).


Frequently Asked Questions

What happens immediately after git init? Git creates a hidden .git folder in the current directory. Your project files are untouched. The repository is empty — no commits yet, no history. Git is now watching the folder but hasn't recorded anything.

Can I delete the .git folder? Yes. Deleting .git removes all Git tracking, history, branches, and configuration. Your project files remain. The directory becomes an ordinary folder again. This is how you "un-Git" a project.

Does git init delete or change my existing files? No. git init only creates the .git folder. It never touches your existing project files.

Do I need to run git init every time I start working on a project? No — only once per project. After initialization, the .git folder persists and Git keeps tracking the project until you delete it.

What is HEAD in Git? HEAD is a pointer to the current branch you're on. When you make a commit, HEAD (via the branch it points to) updates to point to the new commit. When you switch branches, HEAD updates to point to the new branch. It tells Git "this is where you currently are."

Can I rename the default branch from master to main after init? Yes:

git branch -m master main

This renames your local branch. If you've already pushed to GitHub, you'll also need to update the remote default branch in GitHub's repository settings.

What is the difference between git init and git clone? git init creates a new, empty repository locally. git clone downloads an existing repository (with all its history) from a remote URL. Use git init when starting from scratch, git clone when starting from an existing project.

What is a bare repository (git init --bare)? A bare repository has no working directory — only the .git contents, stored directly in the root folder. You can't edit files in a bare repository; it's only used as a remote that other developers push to and pull from. GitHub stores your repositories as bare repositories on their servers.

Is it safe to run git init in a directory that's already a Git repository? Yes — it reinitializes the existing repository without deleting any history or data. Git will output "Reinitialized existing Git repository." This is occasionally useful for resetting hooks or configuration.

Why does my terminal show (master) instead of (main) after git init? Your Git version or configuration defaults to master. Set the global default:

git config --global init.defaultBranch main

Then new repositories will use main. For the current one: git branch -m master main.


Quick Reference Card

# Initialize new repository
git init

# Initialize in a new directory
git init my-project

# Check status
git status

# Stage all files
git add .

# Stage specific file
git add filename.txt

# Make first commit
git commit -m "Initial commit"

# Connect to GitHub
git remote add origin https://github.com/username/repo.git

# Push to GitHub (first time)
git push -u origin main

# Push to GitHub (subsequent times)
git push

Conclusion

git init is one command, but understanding what it does — creating the .git folder, setting up the object store, the HEAD reference, the branch pointer — turns Git from a collection of magic incantations into a coherent system that makes sense.

The workflow after git init is always the same pattern: edit files, stage changes with git add, record a snapshot with git commit, and push to a remote with git push. That loop is the foundation of every Git workflow, from a solo student project to a multi-thousand-developer open source codebase.

Start with a project you're actually working on. Run git init. Make your first commit. Push it to GitHub. The concepts become concrete very quickly once you're doing them for real rather than just reading about them.

For the next steps in your Git journey, see: How to Use git add and git commit, Branching and Merging in Git, How to Work with GitHub Repositories, and the Big Tech Roadmap for CS Students which covers where Git fits in the broader software engineering skill set.

Post a Comment

0 Comments