Git & GitHub Guide
A complete beginner-friendly walkthrough — from your first commit to collaborating on GitHub. Each section builds on the previous one. Every code block has a Copy button.
Copy button on each code block · ● Beginner ● Intermediate ● Advanced01 Introduction — What are Git & GitHub?
Git is a tool that tracks changes to your files over time — like a "save history" for your entire project. Every time you decide to save a checkpoint, Git takes a snapshot of your files. You can go back to any snapshot later, compare versions, and work on multiple experiments at once without risk.
GitHub is a website that hosts Git repositories online. It lets you:
- Back up your code to the cloud
- Collaborate with others on the same codebase
- Review changes before merging them
- Showcase your work to the world
Git (local repo)
Remote backup
Collaboration
02 Installation & First-Time Setup
Install Git
- Linux (Debian/Ubuntu):
sudo apt install git - Linux (Fedora):
sudo dnf install git - macOS:
brew install gitor download from git-scm.com - Windows: Download from git-scm.com
Configure your identity
These details are attached to every commit you make — like a signature.
# Check version
git --version
# Set your name & email (use the one on GitHub)
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
Recommended settings
git config --global init.defaultBranch main
git config --global color.ui auto
git config --global core.editor "code --wait"
Run git config --list to see all your settings. Make sure your name and email are correct — they appear in every commit!
ssh-keygen -t ed25519 -C "you@example.com" then add the public key at GitHub → Settings → SSH and GPG keys. This lets you push without typing a password every time.03 Your First Repository
A repository (or "repo") is a folder that Git is watching. There are two ways to start:
▶git init Create a new repo from scratch
mkdir my-project
cd my-project
git init
This creates a hidden .git folder inside your project. Now Git is tracking everything in this directory. Run ls -la to see the .git folder — that's Git's "brain". Don't touch it manually!
▶git clone Copy an existing repo from GitHub
git clone https://github.com/user/repo.git
# or with SSH (no password each time):
git clone git@github.com:user/repo.git
This downloads the entire project history to your computer. You get everything — all files, all branches, all commits.
▶git status Check what's happening
git status
This is the most-used Git command. It tells you which files are modified but not staged, which files are staged ready to commit, and which files are untracked (new files Git doesn't know about).
mkdir test && cd test && git init — then create a file hello.txt, write something in it, and run git status. You'll see it as "Untracked".
04 The Daily Workflow Beginner
Git has three areas where your files live. Understanding these is the key to everything else:
You edit files here
Prepare your snapshot
Saved permanently
The daily cycle is always: Edit → Add → Commit
▶git add Stage changes
git add filename.txt # stage one specific file
git add . # stage ALL changes
git add -p # stage interactively — pick what to include
Staging is like picking which items to put in a photo before taking the picture. You don't have to commit everything.
▶git commit Take a snapshot
git commit -m "Add login button"
git commit -am "Fix typo" # shortcut: add + commit (tracked files only)
Every commit has a message describing what changed. Write clear messages so your future self (and others) understand why.
Good commit messages
# Use imperative mood (like giving a command):
git commit -m "Add user authentication"
git commit -m "Fix crash when file is missing"
git commit -m "Update dependencies"
05 Exploring History Beginner
Once you have commits, you can explore your project's timeline.
▶git log View commit history
git log # full history
git log --oneline # compact (one line per commit)
git log --oneline --graph # show branch structure visually
git log --oneline -5 # last 5 commits only
git log --author="Laksh" # commits by a specific person
▶git show See what a commit changed
git show HEAD # show the latest commit
git show abc1234 # show a specific commit (use its hash)
git show HEAD~2 # show what changed 2 commits ago
▶git diff Compare changes
git diff # unstaged changes (working dir vs staging)
git diff --staged # staged changes (vs last commit)
git diff HEAD~1..HEAD # changes between two commits
git diff branch-a..branch-b # compare two branches
▶git shortlog Summarized log (grouped by author)
git shortlog # shows commits grouped by author
git shortlog -sn # same but with commit count only
▶git blame See who changed each line
git blame README.md # shows who last touched each line
git blame -L 10,20 src/app.js # lines 10-20 only
Useful when you find a bug and want to ask "who wrote this line?" (including your past self).
▶git grep Search within tracked files
git grep "search-term" # search all tracked files
git grep "TODO" # find all TODOs in your project
Faster than regular grep because it only searches tracked files.
06 Ignoring Files Beginner
Not everything should be committed. Create a file called .gitignore in your project root to tell Git which files to skip.
# .gitignore — example for a Node.js project
node_modules/
.env
*.log
.DS_Store
dist/
coverage/
.vscode/
node_modules/— installed packages (reinstall withnpm install).env— secret keys, passwords, API tokens*.log— log files that change constantlydist/— generated build output
.gitignore before committing sensitive files. If you accidentally commit a password, it stays in the history forever!Need a template? github/gitignore has templates for every language.
▶git check-ignore Debug why a file is ignored
git check-ignore -v some-file.log
Shows which rule in .gitignore is ignoring that file.
07 Undoing Changes Intermediate
Mistakes are normal. Here's how to undo at every stage — from safest to most destructive.
▶git restore Discard unstaged changes (safe)
git restore filename.txt # discard changes in working directory
git restore . # discard all unstaged changes
# Older syntax (still works):
git checkout -- filename.txt
⚠ This permanently discards unsaved work in that file. You cannot get it back!
▶git restore --staged Unstage a file (keep changes)
git restore --staged filename.txt # unstage, but keep file changes
git restore --staged . # unstage everything
Your file changes are preserved — they just move out of the staging area back to your working directory.
▶git reset Undo commits (rewrite history)
# Soft — undo commit, keep changes staged
git reset --soft HEAD~1
# Mixed (default) — undo commit, unstage changes
git reset HEAD~1
# Hard — DESTROY everything after the target commit ⚠
git reset --hard HEAD~1
HEAD~1 = "one commit before HEAD". Use HEAD~n for n commits, or a full commit hash like abc1234. --hard permanently deletes uncommitted changes and commits. Only use it on commits you haven't shared.
▶git revert Safe undo (creates a new commit)
git revert HEAD # create a new commit that undoes HEAD
git revert abc1234 # undo a specific commit by hash
Unlike reset, revert does not delete history. It makes a new commit that cancels out the old one. Safe to use on shared branches!
▶git clean Remove untracked files
git clean -n # preview what would be deleted (dry run)
git clean -f # delete untracked files
git clean -fd # delete untracked files + directories
Always run git clean -n first to see what will be removed!
08 Branching Intermediate
A branch is like an alternate timeline. You can experiment freely on a branch without affecting the main code. This is the foundation of Git collaboration.
main: ●──●──●──────────────●
\ /
feature: ●──●──●
The default branch is main. Feature branches branch off, get work done, then merge back.
▶git branch List, create, rename, delete
git branch # list local branches (* = current)
git branch feature-x # create a new branch called feature-x
git branch -m old new # rename a branch
git branch -d feature-x # delete branch (only if merged)
git branch -D feature-x # force delete (unmerged work!)
▶git switch Move between branches (modern way)
git switch feature-x # switch to existing branch
git switch -c new-branch # create AND switch to new branch
git switch - # switch back to previous branch
▶git branch -a See all branches (local + remote)
git branch -a # list all branches
git branch -r # remote branches only
git switch -c experiment — create and switch to a new branch. Make a commit here, then git switch main. Your commit on experiment is hidden away, safe and separate.
main. Always create a branch for each feature or bug fix.09 Merging Intermediate
Merging brings changes from one branch into another. It creates a merge commit that ties the two histories together.
▶git merge Basic merge
# First, switch to the branch you want to merge INTO
git switch main
# Then merge the feature branch into main
git merge feature-x
# Force a merge commit (even if fast-forward is possible)
git merge --no-ff feature-x
Merge conflicts
When two branches change the same line of the same file, Git doesn't know which one to keep. This is a merge conflict.
# Git tells you which files have conflicts.
# Open them — you'll see markers like:
<<<<<<< HEAD
console.log("Hello");
=======
console.log("Hi there!");
>>>>>>> feature-x
# Edit the file to keep what you want, remove the markers, then:
git add resolved-file.txt
git commit # Git creates the merge commit automatically
git merge --abort to cancel a conflicted merge and go back to how things were.10 Rebasing Advanced
Rebasing rewrites history by moving your commits to sit on top of another branch. It creates a clean, linear history — unlike merge which keeps a record of every fork.
▶git rebase Basic rebase
# While on your feature branch:
git switch feature-x
git rebase main
# Now your commits sit on top of main's latest commit
Before vs After
# Merge keeps the fork visible:
main: ●──●──●─────────●───●
\ /
feature: ●──●─●
# Rebase creates a straight line:
main: ●──●──●
\
feature: ●──●──● (now on top of main)
▶git rebase -i Interactive rebase — squash, reword, reorder
# Edit the last 3 commits before pushing:
git rebase -i HEAD~3
# Inside the editor, you can:
# pick — keep the commit as-is
# reword — change the commit message
# squash — combine with previous commit
# edit — pause to make changes
# drop — delete the commit
This is how you clean up messy commit history before sharing it.
merge for shared branches.▶git rebase --abort Cancel a rebase
git rebase --abort # go back to before you started rebasing
11 Cherry-Pick Intermediate
git cherry-pick lets you take a specific commit from one branch and apply it to another — without merging the whole branch.
# Apply a specific commit to your current branch
git cherry-pick abc1234
# Apply multiple commits
git cherry-pick abc1234 def5678
# Cherry-pick without making a commit right away
git cherry-pick -n abc1234
When to use it:
- You need one bug fix from a feature branch without taking the whole branch
- A commit was made on the wrong branch
- You want to backport a fix to an older release
12 Tagging (Version Releases) Intermediate
Tags mark specific points in history — usually for releases like v1.0, v2.3.1. Unlike branches, tags don't move.
# Create a lightweight tag
git tag v1.0.0
# Create an annotated tag (recommended — includes metadata)
git tag -a v1.0.0 -m "Release version 1.0.0"
# List all tags
git tag
# See details of a tag
git show v1.0.0
# Push tags to GitHub
git push origin v1.0.0
# Push ALL tags
git push origin --tags
# Delete a local tag
git tag -d v1.0.0
git tag -a saves the tagger name, date, and a message — much more useful than lightweight tags.13 Remote Repositories & GitHub Intermediate
A remote is a Git repository hosted on a server — typically GitHub. You push your local commits there to back them up and share them.
Connecting your local repo to GitHub
# Create a repo on GitHub first (no README, no .gitignore)
# Then connect your local repo:
git remote add origin https://github.com/your-username/your-repo.git
# Or use SSH (no password prompts):
git remote add origin git@github.com:your-username/your-repo.git
Working with remotes
git remote -v # list all remotes
git remote remove origin # remove a remote
git remote rename origin upstream
▶git push Send commits to GitHub
# First push (set upstream):
git push -u origin main
# Subsequent pushes (just):
git push
# Push a specific branch:
git push origin feature-x
# Delete a remote branch:
git push origin --delete feature-x
▶git pull Get latest changes from GitHub
git pull origin main # fetch + merge latest changes
git pull # if upstream is configured
git pull is a shortcut for git fetch + git merge. It downloads changes and immediately merges them.
▶git fetch Download without merging
git fetch origin # download changes, DON'T merge
git fetch --prune # remove stale remote-tracking branches
git diff main origin/main # see what changed before merging
Use fetch when you want to review changes before integrating them.
git pull = fetch + merge. Use git fetch then git diff to review, then git merge manually.14 Collaboration on GitHub Intermediate
Pull Requests (PRs)
A Pull Request tells others: "I've made changes on a branch — please review and merge them." This is the heart of GitHub collaboration.
The PR workflow:
- Create a branch:
git switch -c fix-login-bug - Make changes and commit them
- Push the branch:
git push -u origin fix-login-bug - Open a PR on GitHub from
fix-login-bug→main - Review & discuss: Teammates comment, suggest changes
- Update if needed: Push more commits — the PR updates automatically
- Merge once approved
- Clean up: Delete the remote and local branch
Forking (Open-Source Contribution)
When you don't have write access to a repo, you fork it — make a copy under your GitHub account.
# 1. Click "Fork" on GitHub
# 2. Clone YOUR fork:
git clone https://github.com/YOUR-USERNAME/repo.git
# 3. Add the original repo as "upstream":
git remote add upstream https://github.com/ORIGINAL-OWNER/repo.git
# 4. Keep your fork in sync:
git pull upstream main
git push origin main
▶git remote -v See your remotes (after forking)
origin https://github.com/YOU/repo.git (fetch)
origin https://github.com/YOU/repo.git (push)
upstream https://github.com/OWNER/repo.git (fetch)
upstream https://github.com/OWNER/repo.git (push)
origin = your fork, upstream = the original repo you forked from.
GitHub Issues
- Create issues for bugs, feature requests, or tasks
- Reference issues in commits:
git commit -m "Fix crash (#42)" - Close issues automatically with keywords: "Closes #42" in your PR description
GitHub Discussions
A forum-like space for questions, ideas, and community conversations — separate from Issues (which are for actionable tasks).
15 Stash — Save Work in Progress Intermediate
You're in the middle of work but need to switch branches? Stash shelves your changes temporarily so you can come back later.
# Save current changes (tracked files only)
git stash
# Stash with a name (organize multiple stashes)
git stash push -m "WIP: fixing login bug"
# Stash untracked files too
git stash -u
Managing stashes
git stash list # see all saved stashes
git stash apply # apply latest stash (keep it)
git stash pop # apply latest stash + remove it
git stash drop # delete latest stash
git stash clear # delete ALL stashes
git stash show -p # see diff of latest stash
stash@{0}, the one before is stash@{1}, etc. Use git stash pop most of the time.16 Recovery Tools Advanced
Accidentally lost a commit? Deleted something you shouldn't have? Git has safety nets.
▶git reflog The safety net — reference log
git reflog # shows EVERYTHING you've done
# Output like:
# abc1234 HEAD@{0}: commit: Fix login
# def5678 HEAD@{1}: reset: moving to HEAD~1
# Recover a "lost" commit:
git reset --hard HEAD@{2} # go back to that point
The reflog is Git's local journal of every action you've taken. Even after a git reset --hard or git rebase, you can find your old commits here. Your reflog expires after ~90 days.
▶git bisect Find the commit that introduced a bug
# Start bisecting:
git bisect start
# Mark the current commit as bad:
git bisect bad
# Mark an old commit (that you know worked) as good:
git bisect good abc1234
# Git checks out a commit halfway in between.
# Test it, then mark:
git bisect good # if it works
git bisect bad # if it's broken
# Git narrows it down to one commit. When done:
git bisect reset
git bisect uses binary search to find the exact commit where a bug was introduced. For 1000 commits, it takes only ~10 steps!
17 More GitHub Features
▶Actions Automate workflows (CI/CD)
GitHub Actions runs tasks automatically when events happen — like running tests on every push.
# .github/workflows/test.yml — example
name: Run tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm install
- run: npm test
Common use cases: run tests, deploy to a server, lint code, publish packages.
▶Pages Host websites for free
GitHub Pages serves static websites directly from a repository. Great for docs, portfolios, project sites.
- Go to repo → Settings → Pages
- Select branch (usually
mainorgh-pages) - Your site is live at
https://username.github.io/repo-name
▶Projects Kanban-style project management
GitHub Projects is a built-in project management board (like Trello) linked to issues and PRs.
- Create columns: To Do → In Progress → Done
- Drag issues and PRs between columns
- Automate with Actions (e.g., move to "Done" when PR merges)
▶GitHub CLI Manage GitHub from your terminal
Install gh and never leave the terminal:
gh repo create my-repo # create a repo on GitHub
gh pr create # create a pull request
gh pr checkout 42 # checkout PR #42 locally
gh issue list # list open issues
gh repo view # view repo details
Install: brew install gh (macOS), sudo apt install gh (Linux), or download from cli.github.com.
18 Advanced Topics Advanced
▶git submodule Include other repos inside your repo
# Add a submodule
git submodule add https://github.com/user/library.git lib/library
# Clone a repo WITH its submodules
git clone --recurse-submodules https://github.com/user/project.git
# Update submodules to their latest commit
git submodule update --remote
Submodules let you keep a Git repo as a dependency inside another Git repo.
▶git archive Export a snapshot (without .git)
# Create a zip of your project (no .git folder)
git archive --format=zip HEAD > project.zip
# Create a tar.gz
git archive --format=tar.gz -o project.tar.gz HEAD
Perfect for sharing a clean copy of your code — no .git history, no ignored files.
▶git worktree Work on two branches at once
# Check out a branch in a separate directory
git worktree add ../project-hotfix hotfix-branch
# List worktrees
git worktree list
# Remove a worktree when done
git worktree remove ../project-hotfix
Lets you have two different branches checked out at the same time in different folders — no stashing or switching needed.
19 Quick Command Reference
Print this section or keep it bookmarked — it covers 95% of what you'll ever need.
Getting Started
Daily Work
History
Undoing
Branches
Remote & GitHub
Saving & Recovery
git --help or git <command> --help opens the manual for any command. Come back to this guide whenever you need.