Version Control

Git

Git is the world's most popular version control system. Here's what it is, how it works, and how to start using it to track changes and collaborate with others.

beginner18 min readUpdated Sep 15, 2026
bash
# Initialize a new repository
git init

# Stage and commit changes
git add .
git commit -m "Initial commit"

# Check status and history
git status
git log --oneline
Created
2005, by Linus Torvalds
Type
Distributed version control system
Written in
C, Shell scripts, Perl
Repository format
.git directory
Default branch
main (formerly master)

Why it matters

Why Git matters

Complete history

Every change is tracked with a unique identifier, author, timestamp, and message. You can rewind to any point in your project's history.

Team collaboration

Multiple developers can work on the same codebase simultaneously without overwriting each other's work. Git handles merging changes automatically.

Data integrity

Git uses SHA-1 hashing to ensure every commit is tamper-proof. If a file changes, the hash changes — corruption is immediately detectable.

The big picture

The three pillars of version control

Snapshots record history, branches let work diverge, and remotes bring it back together.

Snapshots

Commit

Each commit is a full snapshot of the project at a point in time, addressed by a hash, forming an immutable history.

Branches

Diverge

A branch is a lightweight, movable pointer to a commit, so you can work in parallel and merge back.

Remotes

Collaborate

A remote is another copy of the repository; push and pull move commits between them so teams stay in sync.

Git at a glance

What Git gives you

Repositories

Project directories that Git tracks, containing your files and a hidden .git folder with all version history.

Commits

Snapshots of your project at specific moments, linked together in a chain of history.

Branches

Independent lines of development that let you work on features without affecting the main codebase.

Merging

Combining changes from different branches, with automatic conflict resolution when edits overlap.

Remotes

Copies of your repository hosted on servers like GitHub, enabling team collaboration over the internet.

Tags

Named labels for specific commits, commonly used to mark version releases like v1.0.0.

A short history

From local tool to global standard

  1. 2005

    Born from necessity

    Linus Torvalds creates Git to manage Linux kernel development after the previous tool becomes unavailable.

    05
  2. 2008

    GitHub launches

    GitHub makes Git repositories accessible in the cloud, transforming how developers collaborate.

    08
  3. 2010

    Git goes mainstream

    Git becomes the most popular version control system, surpassing SVN and CVS in adoption.

    10
  4. 2015

    GitLab and Bitbucket rise

    Alternative platforms emerge, giving teams more options for hosting and collaborating with Git.

    15
  5. Today

    The industry standard

    Over 90% of developers use Git. It powers open source, enterprise teams, and everything in between.

    Today

The complete guide

Git: Everything you need to know

What is Git?

Git is a distributed version control system that tracks changes in files over time. It lets you save snapshots of your project at any point, compare versions, revert mistakes and collaborate with other people without overwriting each other’s work.

Created by Linus Torvalds in 2005 to manage the Linux kernel, Git has become the most widely used version control system in the world. Whether you are building a solo side project or contributing to a thousand-developer codebase, Git is the tool that makes it possible.

The core idea is simple: instead of saving a single copy of your project, Git saves a series of commits — snapshots of every tracked file at a specific moment. You can travel back in time, compare versions, branch off to try new ideas and merge your work back when it is ready. That model scales from one person to thousands.

Why version control matters

Without version control, collaboration is chaos. Two people editing the same file means someone’s work gets overwritten. A bug introduced last week means manually undoing hours of changes. A feature experiment gone wrong means starting from scratch.

Git solves all of these problems:

  • Track every change — who changed what, when and why. The full history is always available.
  • Revert safely — go back to any previous state without losing current work.
  • Work in parallel — branches let multiple people work on different features simultaneously.
  • Collaborate without fear — Git merges changes intelligently and flags conflicts for you to resolve.
  • Work offline — everything is local until you choose to push to a remote server.

Version control is not optional for professional development. It is a foundational skill that every developer needs, regardless of language, framework or platform.

How Git works

Git operates on three main areas: the working directory, the staging area and the repository.

Your working directory is where you edit files. When you run git add, changes move to the staging area — a preparation zone for the next commit. When you run git commit, the staged changes are saved as a new snapshot in the repository.

# Edit a file in your working directory
echo "Hello, Git!" > hello.txt

# Stage the change
git add hello.txt

# Commit the staged change
git commit -m "Add hello.txt"

This three-step flow — edit, stage, commit — gives you precise control over what goes into each snapshot. You can stage parts of a file, stage multiple files together and create commits that each represent a single logical change.

Under the hood, Git stores data as a directed acyclic graph (DAG) of commit objects. Each commit points to its parent, forming a chain of history. Branches are just lightweight pointers to specific commits, and HEAD is a pointer to the commit you are currently on.

Installing Git

Git is available for every major operating system:

macOS:

# Using Homebrew
brew install git

# Or install Xcode Command Line Tools
xcode-select --install

Windows:

# Download from git-scm.com or use winget
winget install Git.Git

Linux:

# Debian/Ubuntu
sudo apt install git

# Fedora
sudo dnf install git

# Arch
sudo pacman -S git

Verify the installation:

git --version
# git version 2.45.0

After installing, set your identity — this information is included in every commit you make:

git config --global user.name "Your Name"
git config --global user.email "[email protected]"

Core Git commands

Creating a repository

# Start a new repository in the current directory
git init

# Clone an existing repository
git clone https://github.com/user/repo.git

git init creates a hidden .git/ folder that contains all of Git’s tracking data. git clone copies an existing repository — including its full history — to your machine.

Tracking changes

# See which files are modified, staged or untracked
git status

# Stage a specific file
git add filename.js

# Stage all changes
git add .

# Commit with a message
git commit -m "Add user authentication"

git status is the command you will run most often. It tells you what has changed, what is staged and what Git is not tracking. Always check status before committing.

Viewing history

# Show commit history
git log

# Compact one-line format
git log --oneline

# Show changes in each commit
git log -p

# Show a visual branch graph
git log --oneline --graph --all

The commit history is your project’s timeline. Use it to understand how code evolved, who made changes and why decisions were made.

Comparing changes

# Diff between working directory and staging area
git diff

# Diff between staging area and last commit
git diff --staged

# Diff between two commits
git diff abc1234 def5678

git diff shows you exactly what changed, line by line. It is essential for reviewing your own work before committing and for understanding what someone else changed in a pull request.

Undoing changes

# Discard changes in working directory
git checkout -- filename.js

# Unstage a file
git reset HEAD filename.js

# Amend the last commit
git commit --amend -m "Updated commit message"

# Revert a commit (creates a new commit that undoes it)
git revert abc1234

Git makes it safe to experiment because you can always go back. The key is understanding the difference between discarding changes, unstaging them and creating new commits that reverse previous ones.

Working with branches

# List branches
git branch

# Create a new branch
git branch feature-login

# Switch to a branch
git checkout feature-login

# Create and switch in one command
git checkout -b feature-signup

# Delete a branch
git branch -d feature-login

Branches are Git’s superpower. They let you work on new features, fix bugs or experiment without affecting the main codebase. When your work is ready, you merge the branch back.

Merging and rebasing

When a branch is ready, you integrate it back into the main line. git merge creates a merge commit that joins the two histories, while git rebase replays your commits on top of another branch for a linear history:

# Merge a feature branch into main
git checkout main
git merge feature-login

# Rebase a feature branch onto the latest main
git checkout feature-login
git rebase main

If the same lines changed in both branches, Git stops and marks the files as conflicted. Edit the files to keep the correct content, remove the conflict markers (<<<<<<<, =======, >>>>>>>), then stage and continue:

git add .
git merge --continue   # or: git rebase --continue

To keep history tidy, a squash merge collapses every commit from a feature branch into a single commit on the target branch:

git checkout main
git merge --squash feature-dark-mode
git commit -m "Add dark mode feature"

Merge when you want to preserve the full branch history; rebase or squash when you want a clean, linear main branch. Never rebase or squash commits that have already been pushed to a shared branch.

Syncing with remotes

# Add a remote server
git remote add origin https://github.com/user/repo.git

# Push commits to remote
git push origin main

# Pull latest changes
git pull origin main

# Fetch without merging
git fetch origin

Remotes are copies of your repository hosted on servers. The default remote is usually called origin. Push sends your commits to the remote, and pull downloads and merges remote changes into your branch.

The .gitignore file

Not everything should be tracked. Dependencies, build outputs, environment files and IDE settings are typically ignored:

# Dependencies
node_modules/
vendor/

# Build output
dist/
build/

# Environment variables
.env
.env.local

# IDE settings
.vscode/
.idea/

# OS files
.DS_Store
Thumbs.db

Place a .gitignore file in your repository root. Git will skip any file or directory matching these patterns. If you have already committed files you want to ignore, remove them from tracking first:

git rm -r --cached node_modules/
git commit -m "Remove node_modules from tracking"

Understanding commits

A commit is the fundamental unit of Git. Each commit contains:

  • A unique hash — a 40-character SHA-1 identifier like a1b2c3d4e5f6...
  • A message — a description of what changed and why
  • An author — who made the change
  • A timestamp — when the change was made
  • A parent — the commit it builds on (except the first commit)
  • A snapshot — the state of all tracked files at that moment

Good commit messages follow a convention. The first line is a short summary in imperative mood (under 72 characters). An optional body explains the context:

git commit -m "Fix null pointer in user authentication

The login endpoint was throwing a 500 error when the email
field was missing from the request body. Added a null check
before accessing user properties."

Each commit should represent one logical change. This makes it easy to understand, review and revert individual changes without affecting unrelated work.

Common Git workflows

Centralized workflow

Everyone works on the main branch. Simple but risky for teams:

git pull origin main
# make changes
git add .
git commit -m "Update feature"
git push origin main

Feature branch workflow

Each feature or fix gets its own branch. Merges happen through pull requests:

git checkout -b feature-user-profile
# make changes
git push origin feature-user-profile
# open a pull request on GitHub

Gitflow workflow

A structured model with main, develop, feature, release and hotfix branches. Best for projects with scheduled releases:

git checkout -b develop
git checkout -b feature-new-login
# work on feature
git checkout develop
git merge feature-new-login
git checkout -b release-v1.0
# finalize release
git checkout main
git merge release-v1.0
git tag v1.0.0

Trunk-based development

Everyone commits to main (the trunk) frequently, using short-lived feature flags. Popular at companies like Google and Meta:

git checkout main
# make small, frequent changes
git add .
git commit -m "Add feature flag for new dashboard"
git push origin main

Best practices

  • Commit early, commit often — small commits are easier to understand and revert.
  • Write clear commit messages — use imperative mood and explain why, not just what.
  • Branch for every feature — keep main clean and deployable.
  • Pull before you push — always integrate remote changes before sharing your work.
  • Review your own diff — run git diff --staged before committing to catch mistakes.
  • Never commit secrets — use environment variables and .gitignore.
  • Tag releases — use semantic version tags like v1.0.0 for easy rollback.
  • Keep history clean — rebase feature branches before merging to avoid messy merge commits.

Common mistakes

  • Committing too many unrelated changes in one commit.
  • Using vague messages like “fix” or “update” that explain nothing.
  • Force-pushing to shared branches and overwriting others’ work.
  • Not setting up .gitignore, leading to committed node_modules or .env files.
  • Working on main instead of creating a feature branch.
  • Forgetting to pull before pushing, causing merge conflicts.
  • Not backing up remote repositories — local is not enough.

What to learn next

You now have the Git fundamentals: repositories, commits, branches, merging and remotes. From here the natural next step is GitHub for cloud collaboration, issues, pull requests and Actions. Pick a project, build something real and let the practice compound.

Commit messages

Write messages that explain why, not just what. The imperative mood keeps history scannable.

Prefer
Fix null pointer in user authentication
Add rate limiting to API endpoints
Remove deprecated legacy payment module
Avoid
fix
update
changes
work in progress

Staging changes

Stage specific files for focused commits instead of dumping everything at once.

Prefer
git add src/auth.js
git add src/user.js
git commit -m "Refactor user authentication"
Avoid
git add .
git commit -m "stuff"

FAQ

Frequently asked questions

Keep learning

Related topics from the roadmap.

$ start learning

Ready to start learning Git?

Our interactive tutorial walks you through Git step by step — with quizzes and real code you can run in the browser.