Version control from scratch — Linux edition
Note
No prior experience needed. If you can open a terminal, you’re ready.
Git is a version control system — it tracks every change you make to your files over time.
Think of it like a save system in a video game, but for code:
Tip
Git ≠ GitHub. Git is the tool. GitHub is a website that hosts your Git repositories online.
Without Git
project_final.pyproject_final_v2.pyproject_FINAL_USE_THIS.pyproject_FINAL_fixed.pyproject_FINAL_fixed2_omg.pyWith Git
project.pyOpen a terminal and run the command for your distro:
Ubuntu / Debian / Mint
Fedora / RHEL / CentOS
Arch / Manjaro
Verify the installation:
Before using Git, tell it who you are. This info is attached to every commit you make.
Set your preferred text editor (for commit messages):
# Use VS Code
git config --global core.editor "code --wait"
# Use nano (simplest for beginners)
git config --global core.editor "nano"
# Use vim
git config --global core.editor "vim"Check your config:
| Concept | What it means |
|---|---|
| Repository (repo) | A folder tracked by Git |
| Working directory | Your files as you see them |
| Staging area | Changes selected for the next commit |
| Commit | A saved snapshot of your staged changes |
| Branch | An independent line of development |
| Remote | A copy of the repo hosted online (GitHub, etc.) |
┌─────────────────────────────────────────────────────┐
│ YOUR PROJECT │
│ │
│ ┌─────────────┐ git add ┌──────────────┐ │
│ │ Working │ ────────► │ Staging │ │
│ │ Directory │ │ Area │ │
│ └─────────────┘ └──────┬───────┘ │
│ ▲ │ git commit │
│ │ ▼ │
│ │ ┌──────────────┐ │
│ └──────────────────│ Repository │ │
│ git checkout │ (History) │ │
│ └──────────────┘ │
└─────────────────────────────────────────────────────┘
Note
git add doesn’t save anything yet — it just prepares changes. git commit is the actual save.
Option A — Start from scratch (new project)
This creates a hidden .git/ folder — that’s where Git stores everything.
Option B — Clone an existing repo from GitHub
git clone https://github.com/username/repository.git
# Clone into a specific folder name
git clone https://github.com/username/repository.git my-folderCheck the status of your repo at any time:
Step 1: Create or modify a file
Step 2: Check what Git sees
Step 3: Stage the file
Step 4: Commit with a message
A good commit message tells what changed and why, not how.
❌ Bad messages
fixstuffchangesasdfghfinalfinal for real✅ Good messages
Add login form validationFix crash when user list is emptyRemove deprecated API callsUpdate README with install stepsTip
Use the imperative mood: “Add feature” not “Added feature”.
See all commits:
Compact one-line view (much nicer):
git log --oneline
# a3f1c2d Add login form
# 9b2e81a Fix crash on empty list
# 4c7a012 Initial commitSee what actually changed in each commit:
See changes not yet staged:
See changes already staged:
Unstage a file (keep your edits):
Discard all edits to a file (back to last commit):
Warning
git restore filename.py permanently discards unsaved changes. There’s no undo.
Undo the last commit (keep files intact):
Fix the last commit message:
A branch is an independent copy of your project where you can work freely without affecting the main code.
main ──●──●──●──────────────●──▶
\ /
feature ●──●──●──●──
Create and switch to a new branch:
List all branches:
Switch between branches:
Delete a branch (after merging):
Once your feature is ready, merge it back into main:
# 1. Switch to the target branch
git switch main
# 2. Merge the feature branch into it
git merge feature/loginIf there are no conflicts, Git merges automatically.
If there’s a conflict, Git marks the affected file:
<<<<<<< HEAD
print("Hello from main")
=======
print("Hello from feature")
>>>>>>> feature/login
Edit the file to keep what you want, remove the markers, then:
Add a remote to your local repo:
Check your remotes:
Push your commits to GitHub for the first time:
Push after the first time:
Pull latest changes from GitHub:
# 1. Get the latest changes from teammates
git pull
# 2. Create a branch for your task
git switch -c feature/my-task
# 3. Do your work... edit files...
# 4. Check what changed
git status
git diff
# 5. Stage and commit
git add .
git commit -m "Implement my task"
# 6. Push to GitHub
git push -u origin feature/my-task
# 7. Open a Pull Request on GitHub and ask for review.gitignore fileTell Git to ignore files you never want to commit (secrets, logs, build artifacts):
Example .gitignore for a Python project:
# Python
__pycache__/
*.pyc
*.pyo
.venv/
venv/
*.egg-info/
# Environment variables (NEVER commit these!)
.env
# Editor files
.vscode/
.idea/
# OS files
.DS_Store
Thumbs.db
Instead of typing your password every push, use an SSH key:
Step 1: Generate a key pair
Step 2: Copy your public key
Step 3: Add it to GitHub
GitHub → Settings → SSH and GPG keys → New SSH key → Paste → Save
Step 4: Test the connection
Step 5: Use SSH URLs instead of HTTPS
| Command | What it does |
|---|---|
git init |
Start a new repo |
git clone <url> |
Copy a remote repo locally |
git status |
Show current state |
git add . |
Stage all changes |
git commit -m "msg" |
Save a snapshot |
git log --oneline |
View commit history |
git push |
Upload to remote |
git pull |
Download from remote |
git switch -c <name> |
Create + switch branch |
git merge <branch> |
Merge a branch |
git restore <file> |
Discard file changes |
git diff |
Show unstaged changes |
“I committed to main by accident”
git reset --soft HEAD~1 # Undo commit, keep changes staged
git switch -c feature/oops # Move work to a new branch“I accidentally deleted a file”
“I need to see what the project looked like 3 commits ago”
git log --oneline # Find the commit hash
git checkout a3f1c2d # Look around (read-only)
git switch main # Come back“My push was rejected”
The golden flow
git pull — sync firstgit switch -c branch — work in isolationgit add . → git commitgit push — share your workThe golden rules
.env or secretsgit status is your best friendTip
The best way to learn Git is to use it every day, even for personal projects. Break things, recover them — that’s how it clicks.