Linux Edition — 2025

Master Git
on Linux

// A hands-on guide from installation to GitHub collaboration — everything you need to version-control your work.

01 What is Git?

Git is a distributed version control system — it tracks every change you make to files over time. Think of it as an intelligent, unlimited undo history for your entire project, shared across as many machines or collaborators as you like.

🗂️

Repository (repo)

A folder that Git tracks. Contains all your project files plus a hidden .git/ folder storing the full history.

📸

Commit

A snapshot of your files at a moment in time. Each commit has a unique ID (SHA hash) and a message you write.

🌿

Branch

An independent line of development. You can have dozens of branches, each with its own history.

🔀

Merge

Combining changes from one branch into another. Git is usually smart enough to do this automatically.

☁️

Remote

A copy of your repository hosted elsewhere — GitHub, GitLab, your own server. Used to collaborate and back up.

🎭

Staging Area

A holding area where you decide exactly which changes go into your next commit. Like a shopping basket before checkout.

The Three States

Every file in a Git project lives in one of three states:

Working Directory
files you edit
──git add──▶
Staging Area
changes queued
─git commit─▶
Local Repository
history saved
──git push──▶
Remote (GitHub)
shared online

02 Installing Git on Linux

Git is available in every major Linux distribution's package manager. Pick your distro below:

Ubuntu / Debian / Linux Mint

bash
$ sudo apt update
$ sudo apt install git
Reading package lists... Done
Building dependency tree... Done
git is already the newest version (1:2.43.0-1ubuntu7).

Fedora / RHEL / Rocky Linux

bash
$ sudo dnf install git

Arch / Manjaro

bash
$ sudo pacman -S git

Verify Installation

bash
$ git --version
git version 2.43.0

03 First-Time Configuration

Before making any commits, tell Git who you are. This information is attached to every commit you create.

bash
# Set your name and email (use same email as your GitHub account)
$ git config --global user.name "Your Name"
$ git config --global user.email "you@example.com"

# Set your preferred editor (nano is beginner-friendly)
$ git config --global core.editor nano

# Name the default branch "main" (modern standard)
$ git config --global init.defaultBranch main

# View all your settings
$ git config --list
user.name=Your Name
user.email=you@example.com
core.editor=nano
init.defaultBranch=main
ℹ Info
The --global flag saves settings to ~/.gitconfig, applying them to all your repos. You can override per-project by omitting --global inside a repo folder.

04 Core Workflow — The Basics

Starting a New Repository

bash
# Create a new project folder and initialise Git
$ mkdir my-project
$ cd my-project
$ git init
Initialized empty Git repository in /home/user/my-project/.git/

Checking Status & Adding Files

bash
# Check what Git sees
$ git status
On branch main
Untracked files:
  index.html
  style.css

# Stage a specific file
$ git add index.html

# Stage all changes at once
$ git add .

# See exactly what's staged vs unstaged
$ git diff --staged

Making Commits

bash
# Commit with a message (keep it short and descriptive)
$ git commit -m "Add homepage and base stylesheet"
[main (root-commit) a3f1d7e] Add homepage and base stylesheet
 2 files changed, 47 insertions(+)

# Stage ALL tracked files and commit in one step
$ git commit -am "Fix typo in header"
✅ Good Commit Messages
Write messages in the imperative: "Add login form", "Fix broken link", "Update README". Start with a capital letter, no period at the end. Keep the first line under 72 characters.

Viewing History

bash
# Full log
$ git log

# Compact one-liner view
$ git log --oneline
a3f1d7e Add homepage and base stylesheet
d92c1b5 Initial commit

# Beautiful graph view
$ git log --oneline --graph --all

Undoing Things

bash
# Unstage a file (keeps your changes)
$ git restore --staged index.html

# Discard changes in a file (PERMANENT — use with care)
$ git restore index.html

# Fix the last commit message (before pushing)
$ git commit --amend -m "Corrected commit message"

# Undo last commit but KEEP the changes in staging
$ git reset --soft HEAD~1

Ignoring Files — .gitignore

Create a .gitignore file in your project root to tell Git which files to never track:

.gitignore
# Compiled outputs
*.o
*.pyc
__pycache__/
dist/

# Environment & secrets — NEVER commit these!
.env
*.key
*.pem

# Editor / OS clutter
.DS_Store
.vscode/
Thumbs.db

# Node / PHP dependencies
node_modules/
vendor/

05 Branching & Merging

Branches let you work on features or fixes in isolation without disturbing the main codebase. They are cheap and fast in Git — use them liberally.

Creating & Switching Branches

bash
# List all branches (* = current)
$ git branch
* main

# Create and switch to a new branch
$ git switch -c feature/contact-form
Switched to a new branch 'feature/contact-form'

# Switch back to main
$ git switch main

# Delete a branch (after it's merged)
$ git branch -d feature/contact-form

Merging

bash
# Make sure you're on the target branch (e.g. main)
$ git switch main

# Merge your feature branch into main
$ git merge feature/contact-form
Merge made by the 'ort' strategy.
 contact.html | 45 +++++++++++++++++++++
 1 file changed, 45 insertions(+)

Resolving Merge Conflicts

If Git can't automatically combine changes, it marks the file with conflict markers you resolve manually:

index.html (conflict)
<<<<<<< HEAD
<h1>Welcome to my site</h1>
=======
<h1>Hello, world!</h1>
>>>>>>> feature/contact-form
# Edit the file to keep what you want, remove the markers, then:
$ git add index.html
$ git commit -m "Merge feature/contact-form — resolve heading conflict"

Stashing Work in Progress

bash
# Quickly save dirty work to switch context
$ git stash push -m "half-finished nav menu"

# List stashes
$ git stash list
stash@{0}: On main: half-finished nav menu

# Restore the most recent stash
$ git stash pop

06 Connecting to GitHub

GitHub is the most popular remote Git host. Setting it up on Linux involves creating an SSH key so your computer can authenticate securely without needing a password every time.

Step 1 — Create a GitHub Account

Visit github.com and sign up. Use the same email address you configured in Git.

Step 2 — Generate an SSH Key

bash
# Generate an ED25519 SSH key (modern, secure)
$ ssh-keygen -t ed25519 -C "you@example.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519): [press Enter]
Enter passphrase (empty for no passphrase): [type a passphrase]

# Start the SSH agent
$ eval "$(ssh-agent -s)"
Agent pid 12345

# Add your key to the agent
$ ssh-add ~/.ssh/id_ed25519

Step 3 — Add the Key to GitHub

bash
# Copy your PUBLIC key to clipboard (never share the private key!)
$ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3Nza... you@example.com

# If xclip is installed, pipe it to clipboard directly
$ cat ~/.ssh/id_ed25519.pub | xclip -selection clipboard

Then in GitHub: Settings → SSH and GPG keys → New SSH key. Paste the contents of your .pub file and give it a descriptive name like "My Linux Laptop".

Step 4 — Test the Connection

bash
$ ssh -T git@github.com
Hi username! You've successfully authenticated, but GitHub does
not provide shell access.
✅ Success!
If you see your username in that message, you're connected. You'll never need to type a password for GitHub operations again.

Persistent SSH Agent (optional but handy)

Add this to your ~/.bashrc or ~/.zshrc so the agent starts automatically:

~/.bashrc
# Auto-start SSH agent
if [ -z "$SSH_AUTH_SOCK" ]; then
   eval "$(ssh-agent -s)"
   ssh-add ~/.ssh/id_ed25519
fi

07 Working with Remotes

Pushing a Local Repo to GitHub

First, create an empty repository on GitHub (no README, no .gitignore). Then back in your terminal:

bash
# Add the GitHub repo as the "origin" remote
$ git remote add origin git@github.com:username/my-project.git

# Verify the remote was added
$ git remote -v
origin  git@github.com:username/my-project.git (fetch)
origin  git@github.com:username/my-project.git (push)

# Push and set main as the upstream tracking branch
$ git push -u origin main
Enumerating objects: 5, done.
Branch 'main' set up to track remote branch 'main' from 'origin'.
 * [new branch]      main -> main

Cloning an Existing Repository

bash
# Clone via SSH (recommended — uses your SSH key)
$ git clone git@github.com:username/repo-name.git

# Clone to a specific folder name
$ git clone git@github.com:username/repo-name.git my-local-name

Fetch, Pull & Push

bash
# Download remote changes WITHOUT merging
$ git fetch origin

# Download AND merge remote changes into current branch
$ git pull

# Push current branch to origin
$ git push

# Push a new branch for the first time
$ git push -u origin feature/my-feature
⚠ Pull Before You Push
Always git pull before starting work for the day and before pushing. It avoids conflicts and keeps your history clean.

08 A Real-World Workflow

Here's the full cycle you'll use day-to-day when collaborating on a project:

bash — complete feature workflow
# 1. Make sure main is up to date
$ git switch main
$ git pull

# 2. Create a feature branch
$ git switch -c feature/add-dark-mode

# 3. Make your changes, then stage and commit
$ nano style.css
$ git add style.css
$ git commit -m "Add dark mode colour variables"

# 4. Push the feature branch to GitHub
$ git push -u origin feature/add-dark-mode

# 5. On GitHub: open a Pull Request → review → merge

# 6. Back locally, clean up after merge
$ git switch main
$ git pull
$ git branch -d feature/add-dark-mode
$ git push origin --delete feature/add-dark-mode

Useful Aliases — Work Faster

Add these shortcuts to your git config:

bash
$ git config --global alias.st status
$ git config --global alias.co switch
$ git config --global alias.lg "log --oneline --graph --all --decorate"
$ git config --global alias.unstage "restore --staged"

# Now you can use them
$ git st
$ git lg

09 Quick Reference Cheatsheet

Setup

CommandWhat it does
git initInitialise a new repository in the current folder
git clone <url>Clone a remote repository locally
git config --global user.name "X"Set your name globally
git config --global user.email "X"Set your email globally

Staging & Committing

CommandWhat it does
git statusShow working tree and staging status
git add <file>Stage a specific file
git add .Stage all changes
git commit -m "msg"Commit with a message
git commit -am "msg"Stage tracked files and commit in one step
git diff --stagedShow what's staged vs last commit

Branches

CommandWhat it does
git branchList all local branches
git switch -c <name>Create and switch to a new branch
git switch <name>Switch to an existing branch
git merge <branch>Merge a branch into current
git branch -d <name>Delete a merged branch

Remote

CommandWhat it does
git remote add origin <url>Add a remote called "origin"
git push -u origin mainPush and set upstream tracking
git pushPush current branch to remote
git pullFetch + merge remote changes
git fetchDownload remote changes without merging
git remote -vShow configured remotes

Undoing

CommandWhat it does
git restore <file>Discard working directory changes
git restore --staged <file>Unstage a file
git reset --soft HEAD~1Undo last commit, keep changes staged
git revert <hash>Create a new commit that undoes a specific one (safe for shared history)
git stashStash uncommitted changes
git stash popRe-apply stashed changes
🚀 You're ready!
The commands above cover 95% of real-world Git usage. The most important thing is to commit often with clear messages and always pull before you push. Happy version controlling!