Module 1: Why Git?

05. Your First Repository (git init)

About this lesson

In this lesson you will create your first Git repository with git init. You will learn what this command does, what the .git/ folder is, and how to turn any folder into a versioned project.

By the end, you will have your first Git repository running locally.


What is a repository?

Repository (repo):

A project folder that Git is tracking. It contains your code + the complete history of changes.

Analogy: a repository is like a "photo album" of your project. Git takes photographs (commits) every time you save important changes.


What does git init do?

git init turns a normal folder into a Git repository.

Before git init:

my-project/
├── index.html
└── styles.css

A normal folder, with no history.

After git init:

my-project/
├── .git/          ← Git creates this folder
├── index.html
└── styles.css

Now it is a Git repository.


Creating your first repository

Option 1: New project + repo

Step 1: Create a folder for your project

mkdir my-first-repo
cd my-first-repo

Step 2: Initialize Git

git init

Output:

Initialized empty Git repository in /Users/mike/my-first-repo/.git/

Repo created successfully


Option 2: Turn an existing project into a repo

If you already have a project without Git:

cd /path/to/your/project
git init

Git turns the project into a repo (without modifying your files).


What happened internally?

When you run git init, Git:

  1. ✅ Creates the .git/ folder (hidden)
  2. ✅ Initializes the database structure
  3. ✅ Sets up an empty repository
  4. ✅ Creates the default branch (main or master)

See the .git folder:

ls -la

Output:

drwxr-xr-x  .git/
-rw-r--r--  index.html
-rw-r--r--  styles.css

The .git/ folder starts with a dot → it is hidden by default.


Exploring the .git/ folder

⚠️ Warning: do NOT modify files inside .git/ by hand. Git manages them automatically.

See the contents of .git/:

ls .git/

Typical structure:

.git/
├── HEAD              ← Pointer to the current commit
├── config            ← Repo configuration
├── description       ← Project description
├── hooks/            ← Automatic scripts (pre-commit, etc)
├── info/             ← Additional configuration
├── objects/          ← Object database (commits, files)
└── refs/             ← References (branches, tags)

Key files:

HEAD:

cat .git/HEAD

Output:

ref: refs/heads/main

It tells you that you are on the main branch.

config:

cat .git/config

Output:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
[remote "origin"]
    url = ...

Configuration specific to this repo.


git init with options

Specify the initial branch

git init --initial-branch=main

Or the short version:

git init -b main

The result: it creates a repo with the main branch (instead of master).


Create a repo in a specific folder

git init project-name

The result:

  • It creates the project-name folder
  • It initializes Git inside
  • You do not need to cd first

Example:

git init my-website
cd my-website

Create a bare repository (advanced)

git init --bare

What is a bare repo?

  • A repo with no working directory
  • Only the .git/ database
  • Used as a central server (GitHub, GitLab)

You will not use it normally. It is for servers.


Verifying that Git is tracking the project

Method 1: the git status command

git status

Output:

On branch main

No commits yet

nothing to commit (create/copy files and use "git add" to track)

If you see this, Git is active.


Method 2: check the .git/ folder

ls -la | grep .git

Output:

drwxr-xr-x .git/

If you see .git/, it is a repo.


Method 3: the git rev-parse command

git rev-parse --is-inside-work-tree

Output:

true

true = you are inside a repo


The repository's initial state

After git init, your repo is empty:

git status

Output:

On branch main

No commits yet

nothing to commit

What it means:

  • Branch: main (just created)
  • Commits: 0 (empty repo)
  • Tracked files: 0 (Git is not tracking anything yet)

Next step: add files with git add (Lesson 06).


Difference: working directory vs repository

Working directory:

  • The files you see and edit
  • A normal project folder

Repository (.git/):

  • Git's hidden database
  • The complete history of changes

Example:

my-project/
├── index.html      ← Working directory
├── styles.css      ← Working directory
└── .git/           ← Repository (history)
    └── objects/    ← Commits stored here

Rule of thumb:

Working directory = the present
Repository = the past (history)


Creating an example file

Let's create a file to add later:

echo "# My First Project" > README.md

See the contents:

cat README.md

Output:

# My First Project

Check Git's state:

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

Git detects the new file, but it is not tracking it yet.

Next lesson: we will add README.md with git add.


Useful commands for repos

See the current branch

git branch

Output:

* main

The * marks the active branch.


See the commits (an empty history)

git log

Output:

fatal: your current branch 'main' does not have any commits yet

Normal in a new repo with no commits.


See the repo's configuration

git config --local --list

Output:

core.repositoryformatversion=0
core.filemode=true
core.bare=false

Configuration specific to this repo.


⚠️ Dangerous commands: do NOT do this

❌ Do NOT delete .git/

rm -rf .git/   # ❌ NEVER DO THIS

The consequence: you lose ALL your history. The project is still there, but without Git.

If you did it by mistake:

  • There is no recovery (unless you have a backup)
  • You need to git init again (history lost)

❌ Do NOT modify files inside .git/ by hand

An example of what you should NOT do:

nano .git/config  # ❌ Dangerous if you do not know what you are doing
rm .git/objects/* # ❌ NEVER, it corrupts the repo

The rule: let Git manage .git/. You use Git commands.


Common troubleshooting

Problem 1: "fatal: not a git repository"

Symptom:

git status
# fatal: not a git repository (or any of the parent directories): .git

Cause: you are not inside a Git repository.

Solution:

# Option 1: Initialize Git
git init

# Option 2: Check that you are in the right folder
pwd
cd /path/to/your/project

Problem 2: "Reinitialized existing Git repository"

Symptom:

git init
# Reinitialized existing Git repository in /path/.git/

Cause: you had already run git init before.

The result: nothing bad happens. Git re-initializes the repo but it does NOT delete your history.

Action: you can ignore this message.


Problem 3: I do not see the .git/ folder

Symptom:

ls
# I only see index.html, styles.css (no .git/)

Cause: .git/ is hidden (it starts with a dot).

Solution:

# macOS/Linux
ls -la

# Windows (PowerShell)
ls -Force

# Windows (Git Bash)
ls -la

Now you will see .git/.


Problem 4: I want to remove Git from the project

Solution:

rm -rf .git/

The result:

  • The project is still there
  • Git's history is deleted
  • It is no longer a repo

A common use: when you cloned an example project and want to start your own history.


Good practices

✅ DO: initialize Git at the start of the project

mkdir new-project
cd new-project
git init

Why: you capture the history from the very beginning.


✅ DO: create README.md right away

git init
echo "# My Project" > README.md
git add README.md
git commit -m "Initial commit"

Why: a first commit with basic documentation.


❌ DON'T: initialize Git in your home or root folder

cd ~
git init  # ❌ NEVER

Why: it would turn your entire home folder into a repo (total chaos).

The fix if you did it:

cd ~
rm -rf .git/  # Delete the accidental repo

❌ DON'T: initialize Git inside another repo

cd my-project/         # Already a repo
mkdir subfolder
cd subfolder
git init  # ❌ Avoid nested repos

Why: Git does not handle nested repos well. Use submodules if you truly need this (advanced).


Lesson summary

In this lesson you:

Created your first repository with git init
Understood the .git/ folder (where Git stores everything)
Learned what git init does internally
Verified that Git is active with git status
Learned about dangerous commands to avoid

Next lesson: the staging area and git add


Practical exercises

Exercise 1: Create a new repository

# 1. Create the folder
mkdir git-exercise
cd git-exercise

# 2. Initialize Git
git init

# 3. Verify
git status

Expected output:

On branch main
No commits yet
nothing to commit
See explanation

You have created an empty repo successfully.

Git is active but there are no commits yet.

Next step: add files with git add.


Exercise 2: Explore .git/

# See the .git/ folder
ls -la .git/

# See HEAD
cat .git/HEAD

# See config
cat .git/config

What do you see in HEAD?

ref: refs/heads/main
See explanation

HEAD points to the main branch.

config holds the repo's configuration.

Do NOT modify these files by hand.


Exercise 3: Create a file and check status

# Create the file
echo "Hello Git" > greeting.txt

# See status
git status

Expected output:

Untracked files:
  greeting.txt
See explanation

Git detects the new file (greeting.txt).

Untracked means Git is NOT tracking it yet.

Next step: git add greeting.txt (Lesson 06).


Additional resources

To go deeper into git init and repositories:

  1. Git Init Documentation - The official documentation
  2. Inside the .git Directory - Exploring .git/
  3. Git Repository Layout (Pro Git) - How Git stores data
  4. Git Basics Video (10 min) - A video tutorial on git init

Estimated time: 15 minutes

Next: 06. Staging Area and git add