Git Introduction

What Git is, installing it, the three areas, and making your first commit.

What Git is

Git is a distributed version control system — it tracks changes to files over time so you can see what changed, when, and by whom, and it lets you go back to any previous state. "Distributed" is the key word: unlike older centralized systems (Subversion, CVS) where one central server holds the only full history, every Git clone contains the entire project history. You can commit, branch, and inspect history completely offline; a "server" like GitHub is really just another copy of the repository that everyone agrees to treat as authoritative.

This distributed design is also why Git is fast for most operations — committing, branching, and viewing history all happen against your local copy, with no network round-trip required.

Installing Git

Bash
# Debian/Ubuntu
$ sudo apt update && sudo apt install git

# Fedora/RHEL
$ sudo dnf install git

# macOS (via Homebrew)
$ brew install git

# Verify installation
$ git --version
git version 2.45.2

First-time setup — Git records an author name and email on every commit, so set these once per machine:

Bash
$ git config --global user.name "Ali Raza"
$ git config --global user.email "ali@example.com"

Initializing a repository

Bash
$ mkdir my-project && cd my-project
$ git init
Initialized empty Git repository in /home/deploy/my-project/.git/

git init creates a hidden .git directory — this is the entire repository: every commit, branch, and piece of history lives inside it. Deleting .git deletes all Git history for the project (the working files remain, but their version history is gone).

The three areas

Understanding Git's day-to-day commands is much easier once you internalize that a Git project has three distinct areas, and files move between them explicitly:

Plaintext
Working Directory  --git add-->  Staging Area  --git commit-->  Repository (.git)
   (your edits)                  (what will be                  (permanent
                                   in the next commit)            history)
  • Working directory — the actual files on disk, as you're editing them right now.
  • Staging area (also called the "index") — a holding area for exactly the changes you intend to include in your next commit. This is what makes Git commits deliberate: you choose precisely what goes in, even if you've changed ten files.
  • Repository — the permanent, committed history stored in .git, made up of a chain of snapshots (commits).

Making your first commit

Bash
$ echo "# My Project" > README.md
$ git status
On branch main

No commits yet

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

git status is the command you'll run more than any other — it always tells you exactly what's staged, unstaged, and untracked.

Bash
$ git add README.md
$ git status
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   README.md

git add moves a change from the working directory into the staging area. You can stage specific files, specific directories, or everything at once (git add .).

Bash
$ git commit -m "Add initial README"
[main (root-commit) 3f2a1b9] Add initial README
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

git commit takes everything currently staged and permanently records it as a new snapshot in the repository, along with the message describing why the change was made. -m provides the message inline; omitting it opens your configured text editor instead, which is preferable for longer, multi-line commit messages.

Bash
$ git log
commit 3f2a1b9c8e4d5f6a7b8c9d0e1f2a3b4c5d6e7f8a (HEAD -> main)
Author: Ali Raza <ali@example.com>
Date:   Thu Aug 20 09:30:00 2026 +0500

    Add initial README

git log shows the commit history — each commit has a unique hash (the long hexadecimal string), an author, a timestamp, and a message, forming a chain back to the very first commit.

Common mistakes

  • Running git commit and expecting unstaged changes to be included — only what's in the staging area (via git add) makes it into the commit.
  • Writing vague commit messages like "fix" or "updates" — a good message explains why, since the diff already shows what changed.
  • Forgetting to run git status before committing, and accidentally including files you didn't mean to (secrets, build artifacts) — this is exactly what .gitignore (covered in Collaborating with Remotes) is for.

Interview questions

Q: What does it mean that Git is a "distributed" version control system? Every clone of a Git repository contains the complete project history, not just the current files — unlike centralized systems where only one server holds the full history. This means you can commit, branch, and browse history entirely offline, and there's no single point of failure: any clone can become the new "source of truth" if needed.

Q: What are the three areas in a Git repository, and how does a change move between them? The working directory (your actual edited files), the staging area/index (changes marked to be included in the next commit), and the repository (permanent committed history). git add moves changes from the working directory to the staging area; git commit takes what's staged and permanently records it in the repository's history.

Q: What's the difference between git init and cloning a repository? git init creates a brand-new, empty repository in the current directory with no history and no remote configured. Cloning (git clone <url>) copies an existing repository — its entire history and all branches — from a remote source and automatically sets up that remote as origin.