Skip to content
📖 Welcome to my knowledge base! Notes on AI/ML, Maths, CS, MBA, Trading, Economics, Health & Self-Help — all in one place.! 🎉 Discover what’s new

Git

Git is the industry-standard distributed version control system, essential for tracking code changes and enabling seamless collaboration. This tutorial covers everything from initial setup to advanced collaboration workflows.


Introduction and Core Concepts

What is Git?

Git is a distributed version control system that tracks changes in your code over time. Unlike centralized systems, every developer has a complete copy of the repository history on their local machine. This distributed nature makes Git fast, reliable, and resilient.

Key benefits:

  • Version Control: Save snapshots of your work and revert to previous versions if needed
  • Collaboration: Multiple people can work on the same project without conflicts
  • Experimentation: Try new features on branches without affecting the main codebase
  • Backup: Your entire project history is saved locally and can be synced to remote hosts

Git vs GitHub

  • Git: The version control software that runs on your computer
  • GitHub: A cloud-based hosting service for Git repositories, providing collaboration tools like pull requests and issue tracking

Installation and Setup

Installing Git

Windows:

# Download from https://git-scm.com/download/win
# Or use package manager
winget install Git.Git

Mac:

# Using Homebrew
brew install git
# Or download from git-scm.com

Linux (Ubuntu/Debian):

sudo apt update
sudo apt install git

Initial Configuration

Configure your identity and preferences:

# Set your name and email (used in commits)
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# Set default branch name
git config --global init.defaultBranch main

# Set default editor
git config --global core.editor "code --wait"  # VS Code
# Or use: nano, vim, etc.

# Verify configuration
git config --list

The --global flag applies these settings to all repositories on your computer.


Basic Workflow

The Three-Stage Architecture

Git uses three main states for your files:

  1. Working Directory: Your files as you edit them
  2. Staging Area (Index): Files you’ve marked to be committed
  3. Repository (Local Database): Committed snapshots

Initialize a Repository

# Create a new directory and navigate into it
mkdir my-project
cd my-project

# Initialize Git repository
git init

This creates a hidden .git folder that stores all version control data.

Core Commands

Check Repository Status

git status

Shows which files are modified, staged, or untracked.

Stage Changes

# Add a specific file
git add filename.py

# Add all files in current directory
git add .

# Add all .py files
git add *.py

Commit Changes

# Commit with a message
git commit -m "Add README file"

# Add and commit in one step (only for tracked files)
git commit -am "Update existing files"

Good commit messages are concise (under 50 characters for the first line) and use the imperative mood (“Add feature”, not “Added feature”).


Viewing History and Changes

View Commit History

# Full history
git log

# One line per commit
git log --oneline

# With graph visualization
git log --graph --oneline --all

# Last 5 commits
git log -5

# Search commits by message
git log --grep="bug fix"

View Differences

# Changes in working directory (unstaged)
git diff

# Changes in staging area
git diff --staged

# Changes in a specific file
git diff filename.py

# Changes between commits
git diff commit1 commit2

Undoing and Fixing Mistakes

Discard Uncommitted Changes

# Discard changes in working directory
git restore filename.py

# Discard all unstaged changes
git restore .

# Unstage a file (keep changes)
git restore --staged filename.py

Warning: git restore permanently discards uncommitted changes.

Remove Files

# Remove from Git and filesystem
git rm filename.py

# Remove from Git only (keep local file)
git rm --cached filename.py

# Remove directory
git rm -r directory/

Revert or Reset Commits

Revert (safe for public commits):

# Creates a new commit that undoes the changes
git revert commit-hash

Reset (use with caution):

# Undo last commit but keep changes staged
git reset --soft HEAD^

# Undo last commit and discard changes
git reset --hard HEAD^

Amend the last commit:

# Change the last commit message
git commit --amend -m "New commit message"

Branching

What are Branches?

Branches are parallel versions of your code. They allow you to work on features without affecting the main codebase, experiment safely, and collaborate without conflicts.

Working with Branches

# List local branches
git branch

# List all branches (local + remote)
git branch -a

# Create a new branch
git branch feature-name

# Create and switch to branch
git checkout -b feature-name
# OR (modern syntax)
git switch -c feature-name

# Switch to existing branch
git switch branch-name

Merging Branches

# Switch to target branch (e.g., main)
git switch main

# Merge feature branch into current branch
git merge feature-name

Handling Merge Conflicts

When Git can’t automatically merge changes, conflict markers appear in files:

<<<<<<< HEAD
This line was changed in the current branch
=======
And was also changed on the other branch
>>>>>>> branch-to-merge

To resolve:

  1. Edit the file to choose which changes to keep (or combine them)
  2. Stage the resolved file: git add filename
  3. Commit the merge: git commit

Delete Branches

# Delete local branch (safe, won't delete unmerged changes)
git branch -d branch-name

# Force delete (even if not merged)
git branch -D branch-name

Remote Repositories (GitHub)

Add a Remote

# Add remote (usually done once)
git remote add origin https://github.com/username/repo.git

# View remotes
git remote -v

origin is the default name for your main remote.

Clone a Repository

# Clone via HTTPS
git clone https://github.com/username/repo.git

# Clone via SSH
git clone git@github.com:username/repo.git

# Clone specific branch
git clone -b branch-name https://github.com/username/repo.git

Push and Pull

# Push local commits to remote
git push origin main

# Pull changes from remote (fetch + merge)
git pull origin main

# First push (sets upstream)
git push -u origin main

Collaborate with Forks

Update your fork from the original repository:

# Add original repo as "upstream"
git remote add upstream https://github.com/original-owner/repo.git

# Fetch and merge upstream changes
git fetch upstream
git checkout main
git merge upstream/main
git push origin main

Advanced Techniques

Stashing Changes

Temporarily save uncommitted work to switch branches:

# Save changes temporarily
git stash

# List stashes
git stash list

# Apply most recent stash
git stash apply

# Apply and remove most recent stash
git stash pop

# Remove most recent stash
git stash drop

Interactive Rebase

Squash, reorder, or edit commits:

# Rebase last 3 commits interactively
git rebase -i HEAD~3

Cherry-Picking

Apply a specific commit to the current branch:

git cherry-pick commit-hash

Tagging

Mark specific points in history (e.g., releases):

# Create a lightweight tag
git tag v1.0

# Create an annotated tag
git tag -a v1.0 -m "Version 1.0"

# Push tags to remote
git push origin --tags

.gitignore

Prevent Git from tracking unnecessary files (e.g., node_modules, .env, IDE files).

Example .gitignore:

# General
.DS_Store

# Editors
.idea
.vscode

# Project
.env
node_modules/

# Wildcard to ignore all .log files
*.log

Best Practices

Commit Messages

  • Write clear, concise commit messages in the imperative mood
  • First line should be 50 characters or less
  • Provide a detailed body if necessary, separated by a blank line

Workflow Tips

  • Commit often, push regularly
  • Pull before you push to avoid conflicts
  • Use branches for features and bug fixes
  • Use .gitignore to exclude unnecessary files
  • Check status frequently (git status) to understand your current state

Common Mistakes to Avoid

“fatal: refusing to merge unrelated histories”

git pull origin main --allow-unrelated-histories

“error: failed to push some refs”

git pull origin main  # Pull changes first

Authentication failures on GitHub: Use a Personal Access Token (PAT) instead of a password.

Last updated on