Sitemap

Git and GitHub: Version Control Essentials

9 min readApr 26, 2026

--

Press enter or click to view image in full size

When Code Gets Lost

You write code. It works. You change something. Break everything. Try to undo. Can’t remember what changed. Code is lost. Start over. Hours wasted.

You collaborate with others. You edit file. They edit same file. Copy paste changes back and forth. Email code. Dropbox folders. Version conflicts. Changes overwritten. Chaos.

You want to try new feature. Scared to break working code. Copy entire project folder. Project_v1, Project_v2, Project_final, Project_final_actual. Which has what? No idea. Folders everywhere.

Version control solves this. Git tracks every change. Every version saved. Undo anything. Try features safely in branches. Collaborate without conflicts. GitHub hosts code. Backs up automatically. Enables teamwork. Essential skill for developers.

QUICK SUMMARY

What You’ll Learn: Git is version control that tracks code changes. Initialize repository with git init. Stage changes with git add. Save changes with git commit. Branches let you work on features separately. Create branch with git branch, switch with git checkout. Merge branches with git merge. GitHub hosts Git repositories online. Connect local to GitHub with git remote. Push code with git push. Pull updates with git pull. Clone repository with git clone. Pull requests propose changes on GitHub. Merge conflicts happen when same code edited differently. Resolve conflicts manually. Rebase rewrites commit history cleanly. .gitignore excludes files from Git. Commit messages describe changes clearly. Branches enable parallel development.

Why It Matters:

  • Never lose code again
  • Undo any change easily
  • Try features safely
  • Collaborate without conflicts
  • Code is backed up
  • Required by all teams
  • Industry standard tool

Key Concepts:

  • Repository (project folder)
  • Commit (saved snapshot)
  • Branch (separate timeline)
  • Merge (combine branches)
  • Remote (GitHub repository)
  • Push (upload code)
  • Pull (download code)
  • Pull request (propose changes)

What You’ll Build:

  • Local Git repository
  • GitHub remote repository
  • Feature branches
  • Pull requests
  • Merge conflict resolution
  • Clean commit history
  • Collaborative workflow

Time Investment: Basic Git takes 1–2 hours to learn. Mastering branches and merging takes practice.

Prerequisites:

  • Command line basics
  • Text editor familiarity
  • GitHub account (free)
  • Understanding of files and folders

FULL DETAILED ARTICLE

Installing Git

Check if installed:

git --version
# git version 2.39.0

Install if needed:

# Mac
brew install git
# Ubuntu/Debian
sudo apt-get install git
# Windows
# Download from git-scm.com

Configure Git:

git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# Check config
git config --list

Basic Git Workflow

Initialize repository:

# Create project folder
mkdir my-project
cd my-project
# Initialize Git
git init
# Initialized empty Git repository in /my-project/.git/
# Check status
git status
# On branch main
# No commits yet

Make first commit:

# Create file
echo "# My Project" > README.md
# Check status
git status
# Untracked files:
# README.md
# Stage file
git add README.md
# Check status
git status
# Changes to be committed:
# new file: README.md
# Commit
git commit -m "Initial commit"
# [main (root-commit) abc123] Initial commit
# 1 file changed, 1 insertion(+)
# View history
git log
# commit abc123...
# Author: Your Name
# Date: ...
# Initial commit

Working with Files

Stage and commit changes:

# Create multiple files
touch index.html style.css script.js
# Stage all files
git add .
# Or stage specific files
git add index.html style.css
# Commit with message
git commit -m "Add HTML, CSS, and JavaScript files"
# View short status
git status -s
# ?? script.js (untracked)
# M index.html (modified)
# A style.css (staged)

Modify and commit:

# Edit file
echo "console.log('hello');" > script.js
# Check what changed
git diff
# Shows line-by-line changes
# Stage and commit
git add script.js
git commit -m "Add console log"
# Or stage and commit in one step
git commit -am "Update script"
# Only works for tracked files

Undo changes:

# Unstage file (keep changes)
git reset HEAD file.txt
# Discard changes (lose changes!)
git checkout -- file.txt
# Or in newer Git
git restore file.txt # Discard changes
git restore --staged file.txt # Unstage

View history:

# View commits
git log
# Compact view
git log --oneline
# abc123 Initial commit
# def456 Add HTML files
# ghi789 Add styles
# With graph
git log --oneline --graph --all
# View specific file history
git log -- file.txt

Branches

Create and switch branches:

# Create branch
git branch feature-login
# List branches
git branch
# * main
# feature-login
# Switch branch
git checkout feature-login
# Switched to branch 'feature-login'
# Or create and switch in one command
git checkout -b feature-signup
# In newer Git
git switch -c feature-signup

Work on branch:

# On feature-login branch
echo "Login component" > login.js
git add login.js
git commit -m "Add login component"
# Switch back to main
git checkout main
# login.js doesn't exist on main branch!
ls login.js
# No such file
# Switch back to feature-login
git checkout feature-login
ls login.js
# login.js exists here

Merge branches:

# Switch to main
git checkout main
# Merge feature branch into main
git merge feature-login
# Merge made by the 'recursive' strategy.
# login.js | 1 +
# 1 file changed, 1 insertion(+)
# Delete merged branch
git branch -d feature-login

Merge conflicts:

# main branch
echo "console.log('main');" > app.js
git add app.js
git commit -m "Add main version"
# feature branch
git checkout -b feature-branch
echo "console.log('feature');" > app.js
git add app.js
git commit -m "Add feature version"
# Try to merge
git checkout main
git merge feature-branch
# CONFLICT in app.js
# Automatic merge failed
# Open app.js
cat app.js
# <<<<<<< HEAD
# console.log('main');
# =======
# console.log('feature');
# >>>>>>> feature-branch
# Resolve conflict (edit file)
echo "console.log('both');" > app.js
# Stage and commit resolution
git add app.js
git commit -m "Resolve merge conflict"

GitHub Basics

Create repository on GitHub:

1. Go to github.com
2. Click "New repository"
3. Name: my-project
4. Public or Private
5. Don't initialize with README (we have local repo)
6. Create repository

Connect local to GitHub:

# Add remote
git remote add origin https://github.com/username/my-project.git
# Or with SSH
git remote add origin git@github.com:username/my-project.git
# Verify remote
git remote -v
# origin https://github.com/username/my-project.git (fetch)
# origin https://github.com/username/my-project.git (push)
# Push to GitHub
git push -u origin main
# -u sets upstream (only needed first time)
# Subsequent pushes
git push

Clone repository:

# Clone from GitHub
git clone https://github.com/username/my-project.git
# Clone into specific folder
git clone https://github.com/username/my-project.git my-folder
# Clone specific branch
git clone -b develop https://github.com/username/my-project.git

Pull changes:

# Fetch and merge changes
git pull
# Equivalent to:
git fetch origin
git merge origin/main
# Pull specific branch
git pull origin main

Pull Requests

Create pull request:

# 1. Create feature branch
git checkout -b feature-awesome
# 2. Make changes and commit
echo "Awesome feature" > feature.js
git add feature.js
git commit -m "Add awesome feature"
# 3. Push branch to GitHub
git push -u origin feature-awesome
# 4. On GitHub:
# - Go to repository
# - Click "Pull requests"
# - Click "New pull request"
# - Select feature-awesome branch
# - Click "Create pull request"
# - Add description
# - Request reviewers
# - Create
# 5. After review and approval:
# - Click "Merge pull request"
# - Delete branch on GitHub
# 6. Update local
git checkout main
git pull
git branch -d feature-awesome

.gitignore

Get Yakhilesh’s stories in your inbox

Join Medium for free to get updates from this writer.

Exclude files from Git:

# .gitignore
# Dependencies
node_modules/
vendor/
# Environment variables
.env
.env.local
.env.production
# Build output
build/
dist/
.next/
# IDE
.vscode/
.idea/
*.swp
# OS files
.DS_Store
Thumbs.db
# Logs
*.log
logs/
# Test coverage
coverage/

Ignore already tracked file:

# Remove from Git but keep file
git rm --cached file.txt
# Add to .gitignore
echo "file.txt" >> .gitignore
# Commit
git commit -m "Stop tracking file.txt"

Common Git Commands

Status and info:

# Status
git status
# Short status
git status -s
# Show changes
git diff
# Show staged changes
git diff --staged
# View commit
git show abc123
# View file at specific commit
git show abc123:file.txt

Commit history:

# View log
git log
# Compact log
git log --oneline
# Graph view
git log --graph --oneline --all
# Last 5 commits
git log -5
# By author
git log --author="John"
# By date
git log --since="2 weeks ago"
# Search commits
git log --grep="bug fix"

Undoing changes:

# Undo last commit (keep changes)
git reset HEAD~1
# Undo last commit (discard changes)
git reset --hard HEAD~1
# Undo specific commit (create new commit)
git revert abc123
# Amend last commit
git commit --amend -m "New message"
# Add to last commit
git add forgotten-file.txt
git commit --amend --no-edit

Stashing changes:

# Save changes temporarily
git stash
# List stashes
git stash list
# stash@{0}: WIP on main
# stash@{1}: WIP on feature
# Apply stash
git stash apply
# Apply and remove stash
git stash pop
# Stash with message
git stash save "Work in progress"
# Drop stash
git stash drop stash@{0}
# Clear all stashes
git stash clear

Git Rebase

Rewrite commit history:

# Rebase feature branch onto main
git checkout feature-branch
git rebase main
# Interactive rebase (last 3 commits)
git rebase -i HEAD~3
# Opens editor:
# pick abc123 Commit 1
# pick def456 Commit 2
# pick ghi789 Commit 3
# Change to:
# pick abc123 Commit 1
# squash def456 Commit 2
# squash ghi789 Commit 3
# (Combines into one commit)
# Other options:
# reword - change commit message
# edit - modify commit
# drop - remove commit

When to rebase vs merge:

Merge:
- Preserves history
- Safe for shared branches
- Shows when branches merged
Rebase:
- Clean linear history
- Only for local branches
- Rewrites commits (don't rebase pushed commits!)

Tags

Mark important commits:

# Create tag
git tag v1.0.0
# Create annotated tag
git tag -a v1.0.0 -m "Version 1.0.0"
# Tag specific commit
git tag v1.0.0 abc123
# List tags
git tag
# Push tags to GitHub
git push --tags
# Delete tag
git tag -d v1.0.0
# Delete remote tag
git push origin :refs/tags/v1.0.0

Collaboration Workflow

Feature branch workflow:

# 1. Update main
git checkout main
git pull
# 2. Create feature branch
git checkout -b feature/user-auth
# 3. Work on feature
# ... make changes ...
git add .
git commit -m "Add user authentication"
# 4. Push to GitHub
git push -u origin feature/user-auth
# 5. Create pull request on GitHub# 6. After review, merge on GitHub# 7. Update local main
git checkout main
git pull
# 8. Delete feature branch
git branch -d feature/user-auth
git push origin --delete feature/user-auth

Commit Message Best Practices

# Good commit messages:
git commit -m "Add user login functionality"
git commit -m "Fix navigation menu on mobile"
git commit -m "Update README with setup instructions"
# Bad commit messages:
git commit -m "update"
git commit -m "fix"
git commit -m "asdf"
# Conventional commits:
git commit -m "feat: add user authentication"
git commit -m "fix: resolve mobile menu bug"
git commit -m "docs: update API documentation"
git commit -m "refactor: simplify database queries"
git commit -m "test: add unit tests for auth"
# Multi-line commit:
git commit
# Opens editor for detailed message:
# Add user authentication
#
# - Implement login endpoint
# - Add JWT token generation
# - Create protected routes middleware

Branching Strategies

Git Flow:

main - production code
develop - development branch
feature/* - new features
release/* - release preparation
hotfix/* - urgent fixes

GitHub Flow (simpler):

main - always deployable
feature branches - all new work
Pull requests for review
Merge to main deploys

Common Mistakes

Mistake 1: Large commits:

# Bad - one commit with many changes
git add .
git commit -m "Update everything"
# Good - logical commits
git add auth.js
git commit -m "Add authentication"
git add navbar.js
git commit -m "Update navbar"

Mistake 2: Committing secrets:

# Never commit:
.env
config/secrets.js
keys/private.key
# If accidentally committed:
git rm --cached .env
# Add to .gitignore
# Rotate the secret!

Mistake 3: Working on main:

# Bad - work directly on main
git checkout main
# make changes
# Good - use feature branch
git checkout -b feature/new-feature
# make changes

GitHub Features

Issues:

1. Track bugs
2. Plan features
3. Assign to team members
4. Link to pull requests
5. Close with commits ("Fixes #123")

Projects:

1. Kanban boards
2. Track progress
3. Organize issues
4. Plan sprints

Actions:

# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm install
- run: npm test

Git Aliases

Make Git commands shorter:

# Add aliases
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.lg "log --oneline --graph --all"
# Use aliases
git co main
git br feature-new
git ci -m "Add feature"
git st
git lg

Summary: Your Git Checklist

Basic Workflow:

  • git init — create repository
  • git add — stage changes
  • git commit — save changes
  • git status — check status
  • git log — view history

Branching:

  • git branch — create branch
  • git checkout — switch branch
  • git merge — combine branches
  • git branch -d — delete branch

GitHub:

  • git remote add — connect to GitHub
  • git push — upload code
  • git pull — download code
  • git clone — copy repository

Collaboration:

  • Create feature branches
  • Make pull requests
  • Review code
  • Merge to main
  • Delete merged branches

Best Practices:

  • Commit often with clear messages
  • Use branches for features
  • Never commit secrets
  • Keep .gitignore updated
  • Pull before you push

Practice Challenges

Practice Git skills:

Challenge 1: Local Repository Create project, make commits, view history.

Challenge 2: Branching Create branches, make changes, merge.

Challenge 3: GitHub Integration Push to GitHub, create pull request.

Challenge 4: Collaboration Clone repository, make changes, contribute.

Challenge 5: Merge Conflicts Create conflicts, resolve them.

You are 65 posts into the 75-post series. Git and GitHub are now in your toolkit.

--

--

Yakhilesh
Yakhilesh

Written by Yakhilesh

I write about work, learning, and the things we overcomplicate. Clear thinking, honest notes from real experience. No hype. akhilesh.pages.dev