Learn Git from scratch—what it is, why developers use it, core concepts (repository, commit, branch, HEAD), and essential commands. A practical guide with diagrams and a real workflow.
If you've ever renamed a file to project_final_v2_REALLY_FINAL.zip or lost track of which code change broke the build, you need Git. As a full-stack developer who's shipped code for years, I can tell you: Git isn't optional—it's the foundation of how modern teams ship software.
This guide introduces Git as a distributed version control system in plain terms, walks through core concepts, and gives you a real workflow from scratch. No fluff—just what you need to get productive.
Git is a distributed version control system (DVCS). In simple terms: it tracks every change you make to your files over time and lets you (and your team) work on the same codebase without stepping on each other's toes.
If your project folder is a rough draft on paper... Git is a time machine that keeps every version, lets you branch into alternate storylines, and merge them back when you're ready.
Unlike old-school tools that stored only the latest version on a central server, Git gives every developer a full copy of the project history. That means you can commit, branch, and experiment offline—and sync when you're ready.
| Feature | What it means |
|---|---|
| Distributed | Every clone has the full history; no single point of failure |
| Version control | Every change is recorded with who, when, and why |
| Branching | Create parallel lines of work and merge them safely |
Git: Working Directory, Staging Area, and Repository flow
Teams and solo developers use Git because it solves real problems:
In 4+ years of full-stack work, I've never seen a professional team ship without version control. Git is the default. Learning it early pays off in every interview and every project.
Before running commands, you need a clear mental model. Here are the terms you'll use every day.
A repository is the project folder that Git is tracking. It contains your files plus a hidden .git directory that holds all history, branches, and metadata.
my-project/
├── src/
├── package.json
└── .git/ # Git's database – don't delete this!
The working directory is the folder you see and edit—your normal project files. When you change a file here, Git sees it as modified until you stage and commit.
The staging area (or index) is a middle layer between your working directory and the repository. You choose which changes go into the next snapshot by adding them with git add. Nothing is committed until it's staged.
A commit is a snapshot of your project at a point in time. Each commit has a unique ID (hash), an author, a timestamp, and a message. The history of your project is a chain of commits.
A branch is a movable pointer to a commit. By default you have main (or master). You create new branches to try features; when ready, you merge them back.
HEAD is Git's pointer to the commit you're currently on. When you switch branches, HEAD moves to the tip of that branch. It answers: "Where am I in history right now?"
Local Git repository structure: .git folder, working tree, and key concepts
| Term | Meaning |
|---|---|
| Repository | Project + full history (including .git) |
| Working directory | The files you see and edit |
| Staging area | What will go into the next commit |
| Commit | A saved snapshot with message and hash |
| Branch | A line of commits (e.g. main, feature/login) |
| HEAD | Current commit / branch you're on |
The .git folder is Git's database. Deleting it removes all history and
branches. Edit your project files; let Git manage .git.
Follow one edit through all four places Git keeps it:
These are the commands you'll use constantly. Examples assume you're in a project directory.
Creates a new Git repo in the current folder (adds the .git directory).
mkdir my-app
cd my-app
git init
Output:
Initialized empty Git repository in /path/to/my-app/.git/
Shows which files are modified, staged, or untracked. Run this often.
git status
Example output:
On branch main
Changes not staged for commit:
modified: src/App.js
Untracked files:
README.md
Moves changes from the working directory to the staging area.
# Stage a single file
git add src/App.js
# Stage all changes in current directory
git add .
# Stage all modified/new files in the repo
git add -A
Use git add file1 file2 to stage only what you want in the next commit. It
keeps commits focused and easier to review and revert.
Creates a new commit from whatever is in the staging area. Always use a clear message.
git commit -m "Add user login form"
Best practice: Use present tense, be specific.
❌ fixed stuff
✅ Fix null check in login validation
Shows the commit history—who changed what and when.
# Default log (full messages)
git log
# One line per commit
git log --oneline
# Last 5 commits
git log -5 --oneline
# With graph for branches
git log --oneline --graph
Commit history flow: linear and branched commits with HEAD
| Command | Purpose |
|---|---|
git diff | Show unstaged changes (working dir vs staging) |
git diff --staged | Show staged changes (staging vs last commit) |
git branch | List branches; git branch feature/x creates one |
git checkout -b feature/x | Create and switch to a new branch |
git clone <url> | Copy a remote repo to your machine |
git pull | Fetch and merge from remote |
git push | Send your commits to remote |
Here's a minimal workflow: create a project, make changes, and save snapshots. Beginner-friendly and practical.
mkdir my-first-git-project
cd my-first-git-project
git init
echo "# My Project" > README.md
git status
git add README.md
git commit -m "Add README"
echo "## Getting Started" >> README.md
git status
git add README.md
git commit -m "Add Getting Started section"
git log --oneline
You should see two commits. That's your first Git workflow: edit → stage → commit.
Most days you'll repeat: git status → git add (what you want) → git commit -m "message" → optionally git push. Master this loop first;
branching and remotes come next.
node_modules/, .env, build outputs so they never get committed.git remote add origin <repo-url>git push -u origin maingit checkout -b feature/your-featuregit checkout main then git merge feature/your-featuregit init, git status, git add, git commit, git log.git add → git commit → repeat; then push to a remote when you're ready.Once this feels natural, move on to branching, merging, and pull requests. Git for beginners is about building the habit: small commits, clear messages, and a reliable history.
Questions about Git or version control? Drop a comment or reach out on Twitter @srtenginamath.

Written by Sharanayya R Tenginamath
Software Engineer at McD BERL with 4+ years building scalable full-stack applications with React.js, Next.js, TypeScript, FastAPI and Python. Available to join from Oct 12, 2026.
Master JavaScript Promises from scratch — lifecycle, .then()/.catch()/.finally(), all static methods (all, allSettled, race, any), real-world examples, visual diagrams, and hands-on assignments. Written from 4+ years of full-stack development experience.
17 min read
Master JavaScript operators — arithmetic, comparison, logical, and assignment — with real-world examples, visual diagrams, truth tables, and hands-on assignments. A practical guide from 4+ years of full-stack development.
19 min read

Learn JavaScript variables (var, let, const) and data types with real-life analogies, clear code examples, comparison diagrams, and hands-on assignments. A practical guide written from 4+ years of full-stack development experience.
15 min read