Contents

Contents

Git and GitHub Notes — Version Control and Collaborative Workflows

Practical insights from version control basics to advanced collaboration techniques

Contents
Why Learn Git and GitHub?

Git and GitHub are fundamental to modern software development. Whether you’re contributing to open-source projects, working in a team, or building your own products, understanding version control is essential for:

  • Tracking changes in your codebase over time
  • Collaborating safely with multiple developers
  • Reversing mistakes without losing work
  • Understanding code history and decisions
  • Automating deployment through CI/CD pipelines
  • Contributing to open-source communities

This guide takes you from complete beginner to advanced user, with practical examples you can use immediately.

Git is a distributed version control system (VCS) designed by Linus Torvalds in 2005. It tracks changes in files, enables collaboration, and maintains complete project history.

Key Characteristics:

  • Distributed: Every developer has a complete copy of the repository
  • Fast: Most operations happen locally without server communication
  • Flexible: Supports various workflows and branching strategies
  • Safe: Cryptographic integrity checking prevents data corruption
  • Powerful: Complex branching, merging, and history rewriting capabilities

These terms are often confused but are distinct:

AspectGitGitHub
TypeVersion Control SystemWeb hosting platform
LocationRuns locally on your computerCloud-based service
PurposeTrack and manage code changesHost, collaborate, and share repositories
ScopeLocal version controlRemote repository + collaboration tools
DependenciesStandalone toolRequires Git to function
FeaturesBranching, merging, stagingPull requests, issues, actions, wiki
Tip

Think of it this way: Git is the engine that manages your code versions, while GitHub is the garage where you park your code and invite others to contribute.

Git has three main states where your files reside:

1. Working Directory (Modified)

Your local files that you actively edit.
Status: Untracked or Modified

2. Staging Area (Staged)

Files marked for inclusion in the next commit.
Status: Staged

3. Git Repository (Committed)

Permanent snapshots stored in .git directory.
Status: Committed

Flow:

Modify Files (Working) → Stage Changes → Commit to Repository

Git stores data as a directed acyclic graph (DAG) of four main object types:

Commit - points to tree + parent commit + author info
Tree - represents directory structure
Blob - actual file contents (immutable)
Tag - reference to specific commit (optional)

Everything is Content-Addressable:

  • Each object has a unique SHA-1 hash based on its content
  • Even tiny changes produce completely different hashes
  • Impossible to change history without detection

macOS (using Homebrew):

brew install git
git --version

Ubuntu/Debian:

sudo apt update
sudo apt install git
git --version

Windows:

# Download from: https://git-scm.com/download/win
# Run installer and follow prompts
# Verify installation
git --version

After installation, configure Git with your identity:

# Set your name (appears in commits)
git config --global user.name "Your Name"

# Set your email (appears in commits)
git config --global user.email "you@example.com"

# Set default editor for commit messages
git config --global core.editor "vim"

# Verify configuration
git config --list

# View only global settings
git config --global --list

# View configuration files
cat ~/.gitconfig
Note

Global vs Local Configuration: --global flag applies to all repositories on your machine. Use local configuration (without --global) for project-specific settings.

Useful Global Configuration:

# Enable colored output
git config --global color.ui true

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

# Enable automatic garbage collection
git config --global gc.auto 4096

# Configure paging (less) for large outputs
git config --global core.pager "less -x1,5"

# Add helpful aliases
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.unstage 'restore --staged'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual 'log --graph --oneline --all'
# Create a new directory
mkdir my-project
cd my-project

# Initialize Git repository
git init

# Verify .git directory was created
ls -la

When you run git init, Git creates a hidden .git directory containing:

.git/
  ├── objects/        # Stores all commits, trees, blobs
  ├── refs/           # References to branches and tags
  ├── HEAD            # Points to current branch
  ├── config          # Repository configuration
  ├── hooks/          # Scripts that run on Git events
  └── logs/           # Reference logs
# View current config (inherits from global)
git config --local user.name

# Override with project-specific settings
git config --local user.name "Project-Specific Name"
git config --local user.email "project@example.com"

# These only apply to this repository

The most important command to understand your repository state:

# Full status output
git status

# Short format (more concise)
git status -s

# Include branch tracking info
git status -sb

# Show untracked files separately
git status --short

Status Output Legend:

 M = Modified
A  = Added
D  = Deleted
R  = Renamed
C  = Copied
U  = Updated but unmerged
?? = Untracked

First column  = staging area
Second column = working directory

Staging is how you select which changes to include in your next commit.

# Stage specific file
git add filename.txt

# Stage multiple files
git add file1.js file2.js file3.js

# Stage all changes in current directory
git add .

# Stage all changes everywhere
git add -A

# Stage only modified files (not new files)
git add -u

# Stage with confirmation (interactive)
git add -i
# Interactive patch staging - choose hunks to stage
git add -p

# View what you staged
git diff --staged

# Unstage specific file
git restore --staged filename.txt

# Unstage all changes
git restore --staged .
Tip

Staging Best Practices: Stage related changes together in logical units. This makes commits more meaningful and makes history easier to understand. Use git add -p to review changes before staging.

A commit is a permanent snapshot of your staged changes.

# Simple commit with message
git commit -m "Add user authentication feature"

# Multi-line commit message (opens editor)
git commit -m "Add authentication" -m "Implement JWT token validation"

# Automatically stage tracked files and commit
git commit -am "Fix login bug"

# Open editor for detailed commit message
git commit

# Amend previous commit (reuse same message)
git commit --amend --no-edit

# Amend and edit message
git commit --amend

Write commit messages that explain the why, not just the what:

# ❌ BAD: What is being done
git commit -m "Update login"

# ❌ BAD: Too vague
git commit -m "Fix stuff"

# ✅ GOOD: What and why
git commit -m "Implement JWT authentication for API endpoints

- Add token generation on login
- Validate tokens on protected routes
- Store refresh tokens securely
- Fixes #123"

# ✅ GOOD: Conventional Commits format
git commit -m "feat(auth): implement JWT token validation

Enables secure API authentication for user endpoints.
Tokens expire after 24 hours and include refresh mechanism.

Closes #456"

Conventional Commits Format (widely adopted):

type(scope): subject

body

footer

Where type is one of:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Code style (formatting, missing semicolons, etc.)
  • refactor: Code refactoring without feature changes
  • perf: Performance improvements
  • test: Adding or updating tests
  • chore: Build process, dependencies, tooling

Understanding what’s been done is crucial for maintenance and debugging.

# Show all commits in current branch
git log

# One line per commit (compact)
git log --oneline

# Show last 10 commits
git log -n 10

# Show commits by specific author
git log --author="John Doe"

# Show commits in date range
git log --since="2025-01-01" --until="2025-06-01"

# Show commits matching search term
git log --grep="authentication"

# Show commits affecting specific file
git log filename.js

# Show changes in each commit (-p = patch)
git log -p

# Pretty graphical view with branches
git log --graph --oneline --all --decorate

# Show statistics
git log --stat

# Custom format
git log --pretty=format:"%h %an %ar - %s"
commit abc1234def5678 (HEAD -> main)
Author: John Doe <john@example.com>
Date:   Mon Nov 3 10:30:45 2025 +0800

    Add JWT authentication

    - Implement token generation
    - Validate tokens on routes

commit xyz9876abc3210
Author: Jane Smith <jane@example.com>
Date:   Sun Nov 2 14:22:10 2025 +0800

    Fix user registration bug

Branches allow parallel development without interfering with each other.

Important

What is a Branch? A branch is simply a lightweight pointer to a specific commit. The default branch is main (or master in older repos). Creating a branch doesn’t copy code — it just creates a reference to a commit.

Why Use Branches?

  • Feature development: Work on features independently
  • Bug fixes: Create hotfix branches without disrupting main code
  • Experimentation: Try ideas without affecting stable code
  • Team collaboration: Multiple people work simultaneously
  • Code review: Enable pull requests for quality control
# List local branches
git branch

# List remote branches
git branch -r

# List all branches
git branch -a

# Create new branch (doesn't switch to it)
git branch feature/user-profile

# Create and switch to new branch
git checkout -b feature/user-profile

# Modern syntax (Git 2.23+)
git switch -c feature/user-profile

# Switch to existing branch
git checkout feature/user-profile

# Modern syntax
git switch feature/user-profile

# Switch to previous branch
git checkout -

# Delete branch (safe - prevents deleting unmerged branches)
git branch -d feature/user-profile

# Force delete branch
git branch -D feature/user-profile

# Rename branch
git branch -m old-name new-name

# Rename current branch
git branch -m new-name

Different teams use different strategies based on their needs.

Designed for projects with scheduled releases:

main (production releases only)
release/v1.0 (release preparation)
develop (integration branch)
feature/* (individual features)
bugfix/* (bug fixes)
hotfix/* (emergency production fixes)
# Start feature branch from develop
git checkout develop
git checkout -b feature/new-feature

# Do work, commit regularly
git add .
git commit -m "Implement new feature"

# When ready, create pull request to develop
# After review and merge to develop

# Create release branch when preparing release
git checkout -b release/v1.0 develop

# Fix release issues only
git commit -m "Fix typo in error message"

# When ready, merge to main with tag
git checkout main
git merge --no-ff release/v1.0
git tag -a v1.0 -m "Release version 1.0"

# Merge back to develop
git checkout develop
git merge --no-ff release/v1.0

Simpler flow for continuous deployment:

main (always deployable, production)
feature/* (features/fixes - short-lived)
Pull Request → Code Review → Merge → Deploy
# Create branch from main
git checkout -b fix/login-bug

# Make commits
git commit -m "Fix login redirect issue"

# Push to GitHub
git push -u origin fix/login-bug

# Create pull request on GitHub
# After review and approval, merge to main
# GitHub automatically deploys main to production

Advantages:

  • Simple and intuitive
  • Quick feedback cycles
  • Production deploys frequently (multiple times per day)
  • Best for teams comfortable with frequent releases
main (always in releasable state)
short-lived branches (< 1 day)
Commit → Merge → Deploy

Best for:

  • Small teams
  • Frequent small commits
  • Strong CI/CD pipeline
  • High collaboration
Tip

Choose Your Strategy: Git Flow for large teams with planned releases. GitHub Flow for continuous deployment. Trunk-Based for high-collaboration teams with strong automation.


Combining changes from different branches is core to collaborative development.

# Switch to target branch (usually main)
git checkout main

# Merge feature branch into main
git merge feature/new-feature

# Git creates a merge commit automatically
# This preserves complete branch history

Result: A new merge commit that combines two branches.

Advantages:

  • Complete history preserved
  • Can easily see which commits came from which branch
  • Makes large-scale changes trackable

Disadvantages:

  • Creates extra merge commits
  • History can become cluttered
# Merge all commits from feature branch into single commit
git merge --squash feature/new-feature

# Still need to commit the squashed changes
git commit -m "Merge feature: add user profile

Implements complete user profile functionality including:
- Profile page with bio and avatar
- Profile editing with validation
- Profile deletion option"

Result: All commits from feature branch become one commit on main.

Advantages:

  • Clean, linear history
  • Easier to understand what was added
  • Easy to revert entire feature

Disadvantages:

  • Individual commit history lost
  • Harder to track specific changes within the feature
# Reapply feature commits on top of main
git merge --ff-only feature/new-feature

# Or explicitly use rebase
git rebase main feature/new-feature
git checkout main
git merge --ff-only feature/new-feature

Result: Linear history as if changes were made sequentially.

Advantages:

  • Clean, easy-to-read history
  • Each commit is independent
  • Can understand full story

Disadvantages:

  • Rewrites history (dangerous with shared branches)
  • Loses information about parallel development

When Git can’t automatically merge branches, you get conflicts.

# When merge conflict occurs, files contain:

<<<<<<< HEAD
// Your changes (from current branch)
function login(user) {
    validate(user);
    return authenticate(user);
}
=======
// Incoming changes (from branch being merged)
function login(user) {
    checkCredentials(user);
    return authorizeUser(user);
}
>>>>>>> feature/auth-update
# 1. View conflicted files
git status

# 2. View conflicts in detail
git diff

# 3. Edit the file to resolve conflicts
#    Remove conflict markers and keep desired code

# 4. Stage the resolved file
git add resolved-file.js

# 5. Complete the merge
git commit -m "Merge feature/auth-update with conflict resolution"

# Or abort the merge if something went wrong
git merge --abort
Warning

Merge Conflict Prevention: Keep branches short-lived (< 1 week). Small, focused changes are less likely to conflict. Communicate with teammates about what you’re working on.


A remote is a reference to a repository hosted elsewhere (typically GitHub).

# View configured remotes
git remote -v

# Add new remote
git remote add origin https://github.com/username/project.git

# Remove remote
git remote remove origin

# Rename remote
git remote rename origin upstream

# View remote details
git remote show origin

# Change remote URL (HTTPS to SSH)
git remote set-url origin git@github.com:username/project.git

Standard Remote Names:

  • origin: Your main remote (GitHub repo you cloned or created)
  • upstream: Original repo (if you forked)
  • fork: Your fork of someone else’s project
# Clone entire repository
git clone https://github.com/username/project.git

# Clone to specific directory
git clone https://github.com/username/project.git my-folder

# Clone specific branch only
git clone -b develop https://github.com/username/project.git

# Shallow clone (fewer commits for faster download)
git clone --depth 5 https://github.com/username/project.git

# Shallow clone with history
git clone --depth 5 --deepen 10 https://github.com/username/project.git
# Fetch: Download remote changes (no integration)
git fetch origin

# Fetch all remotes
git fetch --all

# Fetch and show what changed
git fetch origin && git log origin/main ^main

# Pull: Fetch + merge (downloads and integrates)
git pull origin main

# Pull with rebase instead of merge
git pull --rebase origin main

# Pull and automatically stash local changes
git pull --autostash
Tip

Fetch Before You Act: Use git fetch to see what changed on remote without modifying your local code. Then decide whether to merge, rebase, or do something else.

# Push current branch to remote
git push origin main

# Push to remote and track it
git push -u origin feature/new-feature

# Push all branches
git push --all

# Push all tags
git push --tags

# Push specific branch
git push origin feature/user-auth

# Force push (overwrite remote - use with caution!)
git push --force

# Safe force push (doesn't overwrite others' work)
git push --force-with-lease

# Delete remote branch
git push origin --delete feature/old-feature

# Push with pull request (GitPython or GitHub CLI)
gh pr create --title "Add user profile" --body "Implements #123"
Caution

Force Push Warning: git push --force overwrites remote history. Only use on personal branches. For shared branches, use --force-with-lease which is safer.


Pull Requests (PRs) enable code review and quality control.

# Create feature branch
git checkout -b feature/user-dashboard

# Make changes and commits
git add .
git commit -m "Add dashboard component"

# Push to GitHub
git push -u origin feature/user-dashboard

# Create PR via GitHub web interface or CLI
gh pr create --title "Add user dashboard" \
  --body "Implements #234: User dashboard with stats and charts"

Via GitHub CLI (recommended):

# Install GitHub CLI
# brew install gh (macOS)
# or from https://cli.github.com

# Login to GitHub
gh auth login

# Create pull request
gh pr create --title "Add feature" --body "Description"

# View your PRs
gh pr list

# Check PR status
gh pr checks <pr-number>

# Close PR without merging
gh pr close <pr-number>

Code Review Checklist:

  • Code follows project style guide
  • Changes are focused and not too large (< 400 lines is ideal)
  • Tests added/updated for new code
  • Documentation updated if needed
  • No hardcoded values or credentials
  • No unnecessary dependencies added
  • Performance implications considered
  • Security implications reviewed

PR Title and Description:

## Summary
Brief description of what this PR does.

## Changes
- Added user authentication system
- Implemented JWT token validation
- Created auth middleware

## Related Issues
Closes #123
Relates to #456

## Testing
- Tested login with valid credentials
- Tested login with invalid credentials
- Tested token refresh

## Screenshots
[Add relevant screenshots if UI changes]

## Checklist
- [x] Tests added/updated
- [x] Documentation updated
- [x] No breaking changes
- [ ] Ready for review
# Make additional changes
git add .
git commit -m "Address review feedback: add error handling"

# Push updates (forces update to same PR)
git push origin feature/new-feature

# Force push if you rewrote history
git push --force-with-lease origin feature/new-feature

# The PR automatically updates with new commits
# Option 1: Create merge commit (preserves branch history)
# Recommended for: Feature branches, large changes

# Option 2: Squash and merge (clean history)
# Recommended for: Small fixes, single feature commits

# Option 3: Rebase and merge (linear history)
# Recommended for: Teams using rebase workflow

# You can set default strategy in GitHub repo settings:
# Settings → General → Pull Requests → Default merge method

Save changes without committing them.

# Save current changes (working directory and staging area)
git stash

# Save with descriptive message
git stash save "WIP: user profile feature"

# List all stashes
git stash list

# Show contents of stash
git stash show stash@{0}

# Show stash with diff
git stash show -p stash@{0}

# Apply stash and keep it
git stash apply stash@{0}

# Apply latest stash and remove it
git stash pop

# Delete specific stash
git stash drop stash@{0}

# Delete all stashes
git stash clear

# Create branch from stash
git stash branch new-branch

Stash Use Cases:

  • Switching branches without committing incomplete work
  • Pulling remote changes without conflicts
  • Temporarily saving work while investigating bugs
Warning

Only rebase unpublished commits! Never rebase commits that have been pushed to shared branches. It rewrites history and causes major conflicts for collaborators.

# Rebase last 3 commits (opens editor)
git rebase -i HEAD~3

# Rebase from specific commit
git rebase -i abc1234

# In the editor, you can:
# pick   - include commit as-is
# reword - change commit message
# squash - combine with previous commit
# fixup  - combine and discard message
# drop   - remove commit

Example Interactive Rebase Session:

pick a1b2c3d Add user model
squash x9y8z7w Fix user model validation
pick p8q7r6s Create user repository

# Squash combines the 2nd commit into the 1st
# Final result: 2 commits instead of 3
# Switch to feature branch
git checkout feature/payment

# Rebase onto main (moves all feature commits on top of main)
git rebase main

# Resolve any conflicts that occur
# git add resolved-files
# git rebase --continue

# If something goes wrong
git rebase --abort

# Force push rebased branch (if already pushed)
git push --force-with-lease origin feature/payment

Apply specific commits from one branch to another.

# Apply specific commit to current branch
git cherry-pick abc1234

# Apply multiple commits
git cherry-pick abc1234 def5678 ghi9012

# Apply commits from another branch
git cherry-pick main~5..main

# Cherry-pick without committing (review first)
git cherry-pick --no-commit abc1234

# Abort cherry-pick if conflicts occur
git cherry-pick --abort

Use Cases:

  • Backporting fixes to older versions
  • Applying hotfixes to multiple branches
  • Pulling specific changes from develop to main

Binary search to find which commit introduced a bug.

# Start bisect session
git bisect start

# Mark current commit as bad (contains bug)
git bisect bad HEAD

# Mark a known good commit
git bisect good v1.0

# Git checks out midpoint, you test it
# Mark as good or bad based on testing
git bisect good  # if working
git bisect bad   # if broken

# Git continues narrowing down
# Eventually finds exact commit that broke it

# End bisect session
git bisect reset

# Automate with script
git bisect run ./test-suite.sh

Recover from mistakes by viewing everything you’ve done.

# View all reference changes
git reflog

# Show detailed reflog
git reflog show

# Recover accidentally deleted branch
git reflog
# Find the commit where branch was at
git checkout -b recovered-branch abc1234

# Undo a reset
git reflog
git reset --hard commit-before-reset

# View reflog for specific ref
git reflog show main

GitHub Issues track bugs, features, and tasks.

# Create issue (web interface or CLI)
gh issue create --title "Bug: login fails with spaces in password" \
  --body "Steps to reproduce..."

# List issues
gh issue list

# View issue details
gh issue view 123

# Close issue
gh issue close 123 --comment "Fixed in PR #456"

# Link commits to issues
# Use 'Closes #123' in commit message or PR description
git commit -m "Fix login bug - Closes #123"

# When PR merges, GitHub auto-closes the issue

Automate testing, building, and deployment.

# Create .github/workflows/ci.yml file

name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - uses: actions/setup-node@v3
        with:
          node-version: '18'

      - run: npm install

      - run: npm run lint

      - run: npm run test

      - run: npm run build

Common Workflow Triggers:

  • push - on commits to specific branches
  • pull_request - on PR creation/update
  • schedule - run on schedule (cron jobs)
  • workflow_dispatch - manual trigger
  • release - on repository releases

Publish websites directly from your repository.

# 1. Push HTML files to main branch (or docs/ folder)
# 2. Go to repo Settings → Pages
# 3. Select source (main or gh-pages branch)
# 4. GitHub builds and publishes automatically

# Your site is now at: https://username.github.io/repository

# For project documentation
# Push to docs/ folder and enable in settings

Share code snippets and files.

# Create gist via CLI
gh gist create filename.js

# Create secret gist (unlisted)
gh gist create --public filename.js

# List your gists
gh gist list

# View gist contents
gh gist view gist-id

# Edit gist
gh gist edit gist-id

# Delete gist
gh gist delete gist-id

# Clone gist
git clone https://gist.github.com/username/gist-id.git

SSH is more secure and convenient than passwords.

# Generate ED25519 key (recommended - modern & secure)
ssh-keygen -t ed25519 -C "your_email@example.com"
# Save to: ~/.ssh/id_ed25519

# Or generate RSA key (4096 bits - widely compatible)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# Save to: ~/.ssh/id_rsa

# Add key to SSH agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

# Copy public key to clipboard
cat ~/.ssh/id_ed25519.pub | pbcopy  # macOS
cat ~/.ssh/id_ed25519.pub | xclip -selection clipboard  # Linux
  1. Go to GitHub Settings → SSH and GPG keys
  2. Click “New SSH key”
  3. Paste public key content
  4. Give it a descriptive title
  5. Click “Add SSH key”
# Test connection
ssh -T git@github.com

# Expected output:
# Hi username! You've successfully authenticated, but
# GitHub does not provide shell access.

# If fails, check configuration
ssh -vT git@github.com
# Create/edit ~/.ssh/config

Host github.com-personal
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_personal

Host github.com-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work

# Use in git commands:
git remote add origin git@github.com-personal:username/repo.git
git clone git@github.com-work:company/project.git

Alternative to SSH for programmatic access.

# Create token in GitHub Settings → Developer settings → Personal access tokens
# Select scopes: repo, read:user, user:email

# Use as password when cloning via HTTPS
git clone https://username:ghp_xxx@github.com/username/repo.git

# Store token securely using credential manager
git config --global credential.helper cache

# Or use environment variable
export GITHUB_TOKEN="ghp_xxx"
git clone https://github.com/username/repo.git

Understanding internals helps you debug issues and appreciate Git’s design.

Git stores everything as four types of objects in .git/objects/:

# Blobs: File contents (immutable)
git hash-object filename.txt

# Trees: Directory structure
git cat-file -p main^{tree}

# Commits: Snapshots with metadata
git cat-file -p main

# Tags: Labels for specific commits
git cat-file -p v1.0

Example Object Structure:

Commit: abc1234
  ├─ Author: John Doe <john@example.com>
  ├─ Date: 2025-11-03
  ├─ Message: "Add user profile"
  ├─ Tree: xyz9876 (represents files at this commit)
  └─ Parent: def5678 (previous commit)

Tree: xyz9876
  ├─ user.js (blob: 8f4k2m1)
  ├─ profile.js (blob: q2w3e4r)
  └─ styles/ (tree: 5t6y7u8)

Branches and tags are references to commits.

# Branches stored in .git/refs/heads/
cat .git/refs/heads/main
# Output: abc1234def5678...

# Remote references in .git/refs/remotes/
cat .git/refs/remotes/origin/main

# HEAD points to current branch
cat .git/HEAD
# Output: ref: refs/heads/main

# Detached HEAD (pointing to commit, not branch)
git checkout abc1234  # You're now in detached state
cat .git/HEAD
# Output: abc1234  (direct commit reference)

The staging area is a file (.git/index) that tracks what will be committed.

# View index contents
git ls-files

# View index with status
git ls-files --stage

# Clear index (dangerous!)
git rm --cached -r .

# Update index after external file changes
git update-index --add --cacheinfo

# Undo uncommitted changes in working directory
git checkout filename.js
# or (modern)
git restore filename.js

# Undo staged changes (keep working directory)
git restore --staged filename.js
# or (older)
git reset HEAD filename.js

# Undo last commit (keep changes)
git reset --soft HEAD~1

# Undo last commit (discard changes)
git reset --hard HEAD~1

# Revert commit (create new commit that undoes it)
git revert abc1234

# Revert merge commit (specify which parent to keep)
git revert -m 1 merge-commit-sha
# Accidentally committed to wrong branch
git reset --soft HEAD~1
git stash
git checkout correct-branch
git stash pop
git commit -m "..."

# Committed to main instead of feature branch
git reset --soft HEAD~1  # Keep changes
git checkout -b feature/new-feature
git commit -m "..."

# Need to update branch name before push
git branch -m old-name new-name
git push -u origin new-name
git push origin --delete old-name

# Typo in commit message
git commit --amend -m "Corrected message"
# Then force push if already pushed
git push --force-with-lease origin branch-name
# View all conflicted files
git diff --name-only --diff-filter=U

# View detailed conflict
git diff filename.js

# Use your version entirely
git checkout --ours filename.js
git add filename.js

# Use their version entirely
git checkout --theirs filename.js
git add filename.js

# Use external merge tool
git mergetool

# After resolving all conflicts
git add .
git commit -m "Resolve merge conflicts"

# Or abort the merge
git merge --abort

Important

Atomic Commits: Each commit should represent one logical change. Related changes should be committed together; unrelated changes should be in separate commits.

# ❌ BAD: Too many unrelated changes
git add .
git commit -m "Update stuff"

# ✅ GOOD: Related changes, logical commit
git add src/auth/login.js src/auth/login.test.js
git commit -m "feat(auth): add password reset functionality

- Add reset token generation
- Add email sending for reset link
- Add password validation rules

Closes #234"

# Use staging area strategically
git add -p  # Stage changes hunk by hunk
git diff --staged  # Review what you're committing
git commit -m "..."  # Commit reviewed changes
# Feature branches
feature/user-authentication
feature/payment-integration

# Bug fix branches
bugfix/login-redirect-issue
fix/null-pointer-exception

# Release branches
release/v1.0
release/v2.1.0

# Hotfix branches
hotfix/critical-security-patch
hotfix/production-crash

# Maintenance branches
maintenance/update-dependencies
chore/code-cleanup

# Personal experimentation
sandbox/test-new-framework
spike/investigate-performance
# Delete merged branches locally
git branch -d feature/completed-feature

# Delete all merged branches
git branch -d $(git branch --merged | grep -v "*")

# Find branches merged into main
git branch --merged main

# Find branches NOT merged into main
git branch --no-merged main

# Clean up tracking branches
git remote prune origin

# Clean up object database
git gc

# View and cleanup
git reflog expire --expire=now --all
git gc --prune=now

Commit messages are read by humans much more often than they’re written.

# Bad commit message
Fixed stuff

# Good commit message
Fix user profile display bug

The profile view was failing when user bio contained
special characters. This was due to improper HTML
escaping in the template.

Changes:
- Add HTML entity encoding to bio field
- Add test case for special characters
- Update documentation

Closes #456

# As a reviewer:
1. Clone the branch locally to test
   git fetch origin pull/123/head:pr-123
   git checkout pr-123

2. Test the changes thoroughly
   npm install && npm run test

3. Review code for:
   - Correctness
   - Performance
   - Security
   - Style consistency
   - Test coverage

4. Leave constructive comments
   gh pr review 123 --approve
   # or
   gh pr review 123 --request-changes

5. Approve when satisfied
   # Comment: "Looks good! Approved"

# As a developer:
1. Implement feedback
   git add .
   git commit -m "Address review feedback: add error handling"

2. Push updates
   git push origin feature/branch

3. Request re-review
   gh pr review --request-review @reviewer-name
# Create annotated tag (recommended)
git tag -a v1.0.0 -m "Release version 1.0.0"

# Create lightweight tag (simple reference)
git tag v1.0.0

# List tags
git tag -l

# View tag details
git show v1.0.0

# Push tags to GitHub
git push origin --tags

# Delete tag locally
git tag -d v1.0.0

# Delete tag remotely
git push origin --delete v1.0.0

# Create release on GitHub with notes
gh release create v1.0.0 --title "Version 1.0.0" --notes "Release notes..."

Semantic Versioning (Recommended):

v[MAJOR].[MINOR].[PATCH]-[PRERELEASE]+[BUILD]

v1.2.3           # Version 1, minor release 2, patch 3
v2.0.0-beta      # Pre-release version
v1.0.0-alpha.1   # Pre-release with identifier

Automate tasks that run at specific points in Git workflow.

# Hooks located in .git/hooks/

# Create pre-commit hook (runs before commit)
cat > .git/hooks/pre-commit <<'EOF'
#!/bin/bash
npm run lint
npm run test
EOF

chmod +x .git/hooks/pre-commit

# Shared hooks (commit to repo)
mkdir -p .githooks

# Update git config to use .githooks directory
git config core.hooksPath .githooks

# Common hooks:
# pre-commit       - before commit
# prepare-commit-msg - modify commit message
# commit-msg       - validate commit message
# post-commit      - after commit
# pre-push         - before push

Pre-commit Framework (Recommended):

# Install pre-commit
pip install pre-commit

# Create .pre-commit-config.yaml
repos:
  - repo: https://github.com/psf/black
    rev: 23.1.0
    hooks:
      - id: black

  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-added-large-files

# Setup pre-commit
pre-commit install

# Run manually on all files
pre-commit run --all-files

# Shallow clone (faster for CI/CD)
git clone --depth 1 repo-url

# Unshallow later if needed
git fetch --unshallow

# Sparse checkout (clone only specific directories)
git clone --filter=blob:none --sparse repo-url
cd repo
git sparse-checkout set path/to/dir

# Partial clone (saves bandwidth)
git clone --filter=blob:none repo-url

# Git LFS for large files
git lfs install
git lfs track "*.bin"
git add .gitattributes
# Enable auto garbage collection (default)
git config --global gc.auto 4096

# Manual garbage collection
git gc --aggressive

# Reduce pack size
git gc --prune=now

# Enable object file delta compression
git config --global core.compression 9

# Use credential helper for faster auth
git config --global credential.helper cache
git config --global credential.helper 'cache --timeout=3600'

Q1: Explain Git vs GitHub

Git is version control software. GitHub is a platform for hosting Git repositories with collaboration features like PRs, issues, and Actions.

Q2: What is the difference between merge and rebase?

Merge creates a merge commit combining two branches (preserves history). Rebase replays commits on top of another branch (linear history). Use merge for shared branches, rebase for personal branches.

Q3: How do you handle merge conflicts?

Git marks conflict zones in files. You edit to resolve, then stage and commit. Use git diff to see conflicts, merge tools like Meld for visual resolution, or git merge --abort to cancel.

Q4: What’s the difference between reset and revert?

reset moves HEAD to previous commit (rewrites history). revert creates new commit that undoes changes (safe for shared branches).

Q5: Explain Git objects and how commits work

Git stores blobs (file content), trees (directory structure), commits (snapshots with metadata), and tags (references). Everything is content-addressed by SHA-1 hash.

# Scenario: Large refactor needs to be split across commits
git reset HEAD~5  # Unstage last 5 commits
git add .
git status -s | head -20  # See all changes

# Stage first logical unit
git add src/auth/*.js
git commit -m "refactor(auth): simplify token handling"

# Stage next unit
git add src/api/*.js
git commit -m "refactor(api): restructure endpoints"

# Push when ready
git push origin feature/refactor

# Later: squash all into one for cleaner main history
git merge --squash feature/refactor
git commit -m "Merge refactor: reorganize codebase

- Simplified authentication system
- Restructured API endpoints
- Updated error handling"

  • GitHub CLI (gh): Command-line tool for GitHub operations
  • Git Aliases: Create shortcuts for frequent commands
  • Git Hooks: Automate common tasks
  • Pre-commit: Framework for managing git hooks
  • Git LFS: Handle large files efficiently
  • Conventional Commits: Standard commit message format

Git Command Cheat Sheet
# Setup
git config --global user.name "Name"
git config --global user.email "email@example.com"

# Create and Clone
git init
git clone url

# Daily Workflow
git status
git add filename / git add .
git commit -m "message"
git push origin branch-name
git pull origin branch-name

# Branches
git branch
git checkout -b new-branch
git switch -c new-branch
git merge branch-name
git branch -d branch-name

# History
git log
git log --oneline --graph --all
git diff
git show commit-sha

# Undo
git restore filename
git restore --staged filename
git reset --soft HEAD~1
git revert commit-sha

# Remote
git remote -v
git fetch origin
git pull origin main
git push origin branch-name
git push --all

# Advanced
git stash
git rebase -i HEAD~3
git cherry-pick commit-sha
git bisect start

You now have comprehensive knowledge of:

✅ Git fundamentals and object model ✅ Daily workflows and common commands ✅ Branching strategies and collaboration ✅ Pull requests and code reviews ✅ GitHub features and automation ✅ Authentication and security ✅ Advanced techniques and troubleshooting ✅ Best practices for professional development

Next Steps:

  1. Practice Daily: Use Git for all your projects, big and small
  2. Read the Git Book: Free and incredibly thorough
  3. Contribute to Open Source: Apply your skills to real projects
  4. Setup Git Hooks: Automate quality checks
  5. Master GitHub Actions: Automate your workflow
  6. Stay Updated: Git evolves with new features and best practices
Tip

Pro Tip: The best way to learn Git is to use it daily and make mistakes in a safe environment. Every error is a learning opportunity!


Happy coding and collaborating! 🚀

If you have questions, need clarification, or want to go deeper into any topic, check the official Git and GitHub documentation, or explore the interactive learning resources mentioned above.

If you have questions, need clarification, or want to go deeper into any topic, check the official Git and GitHub documentation, or explore the interactive learning resources mentioned above.


Understanding Git visually helps tremendously. This section provides comprehensive diagrams that illustrate Git’s core concepts and workflows.

The three-state model is fundamental to understanding how Git tracks your changes:

Git Three-State Model: Working Directory, Staging Area, and Repository
Git Three-State Model - Understanding the Three Main States in Git: Working Directory (untracked/modified files), Staging Area (files marked for commit), and Repository (permanent snapshots stored in .git)

Understanding the Flow:

  • Working Directory: Where you modify files
  • Staging Area: Where you prepare changes for commit
  • Repository: Where Git permanently stores committed snapshots

Branches allow parallel development without interfering with the main codebase:

Git Branching Visualization with Feature Integration
Git Branching Strategy - Main branch with feature branches being developed in parallel and merged back into main

Key Concepts:

  • Multiple feature branches can be developed simultaneously
  • Each branch maintains its own commit history
  • Branches merge back into main when features are complete

Two fundamental ways to integrate changes from one branch into another:

Merge vs Rebase Comparison: Creating Merge Commits vs Linear History
Git Merge vs Rebase - Merge creates a merge commit preserving branch history, while Rebase replays commits for linear history

When to Use Each:

  • Merge: Preserves complete history, creates merge commits, safer for shared branches
  • Rebase: Creates linear history, cleaner log, best for feature branches before merging

Git Flow is a robust branching model for managing complex release cycles:

Git Flow Branching Strategy Diagram
Git Flow Strategy - Comprehensive branching model with develop, release, and hotfix branches for managing complex release cycles

Git Flow Structure:

  • main: Production-ready code
  • develop: Integration branch for features
  • feature/*: New features under development
  • release/*: Preparing for production release
  • hotfix/*: Emergency fixes for production

GitHub Flow is a simpler alternative optimized for continuous deployment:

GitHub Flow: Simplified Branching for Continuous Deployment
GitHub Flow - Simpler alternative to Git Flow with main branch always deployable, short-lived feature branches, and continuous deployment

GitHub Flow Principles:

  1. Main branch is always deployable
  2. Create descriptive feature branches
  3. Open pull requests for discussion
  4. Deploy and test before merging
  5. Merge to main and deploy

Git’s distributed nature enables flexible team collaboration:

Distributed Git Workflow with Multiple Developers
Distributed Git Workflow - Shows how multiple developers work with local repositories syncing with GitHub remote

Distributed Benefits:

  • Every developer has a complete repository copy
  • Work offline and commit locally
  • Push/pull to synchronize with team
  • No single point of failure

Understanding Git’s internal storage structure:

Git Object Model: Commits, Trees, and Blobs
Git Object Model - Understanding how Git stores commits, trees, and blobs in a directed acyclic graph structure

Object Types:

  • Commit: Points to tree and parent commits
  • Tree: Represents directory structure
  • Blob: Stores file contents
  • All objects identified by SHA-1 hash

Step-by-step process for resolving merge conflicts:

Merge Conflict Resolution Flow Diagram
Merge Conflict Resolution - Step-by-step process from attempting merge through identifying conflicts to final resolution and commit

Resolution Steps:

  1. Attempt merge and identify conflicts
  2. Open conflicted files and review markers
  3. Choose resolution strategy (yours, theirs, or both)
  4. Stage resolved files
  5. Complete merge with commit

# Show all configuration and their sources
git config --list --show-origin

# Show specific config value
git config user.name

# Edit global config in editor
git config --global --edit

# Set different email for specific repo
git config user.email "work@company.com"

# Enable rerere (reuse recorded resolution)
git config --global rerere.enabled true

# Set merge conflict style
git config --global merge.conflictstyle diff3

# Enable auto-correct for mistyped commands
git config --global help.autocorrect 20

# Set default push behavior
git config --global push.default simple
git config --global push.default current

# Enable push.autoSetupRemote (Git 2.37+)
git config --global push.autoSetupRemote true

# Set default pull strategy
git config --global pull.rebase true
git config --global pull.ff only

# Configure commit template
git config --global commit.template ~/.gitmessage

# Set up signing commits with GPG
git config --global user.signingkey YOUR_GPG_KEY
git config --global commit.gpgsign true

# Ignore file mode changes
git config core.fileMode false

# Case-sensitive file names
git config core.ignorecase false

# Enable filesystem monitoring (Git 2.35+)
git config --global core.fsmonitor true

# Set credential cache timeout
git config --global credential.helper 'cache --timeout=3600'
# Add with intent to add (track but don't stage content)
git add -N file.txt

# Force add ignored files
git add -f ignored-file.txt

# Dry run (show what would be added)
git add -n .

# Verbose output
git add -v .

# Add only modified files, not new files
git add --ignore-removal .

# Update only already tracked files
git add --no-all -u
# Amend and change author
git commit --amend --author="Name <email@example.com>"

# Commit with specific date
git commit --date="2025-01-01 10:00:00"

# Empty commit (trigger CI)
git commit --allow-empty -m "Trigger CI"

# Commit without hooks
git commit --no-verify

# Sign commit with GPG
git commit -S -m "Signed commit"

# Commit with trailer
git commit -m "Fix bug" --trailer "Reviewed-by: John <john@example.com>"

# Fixup commit (for autosquash)
git commit --fixup=abc1234

# Squash commit (for autosquash)
git commit --squash=abc1234

# Reuse commit message from another commit
git commit -C HEAD~1

# Reuse message but edit it
git commit -c HEAD~1
# List branches with pattern
git branch --list "feature/*"

# List branches containing commit
git branch --contains abc1234

# List branches not containing commit
git branch --no-contains abc1234

# Create branch from specific commit
git branch feature-name abc1234

# Track remote branch
git branch --track feature origin/feature

# Set upstream for current branch
git branch --set-upstream-to=origin/main

# Unset upstream
git branch --unset-upstream

# Copy branch
git branch -c old-name new-name

# Show branches and their upstreams
git branch -vv

# Sort branches by committerdate
git branch --sort=-committerdate

# List branches sorted by last commit
git for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(refname:short)'
# Show commits by multiple authors
git log --author="John\\|Jane"

# Show commits with specific string in message
git log --grep="bug fix"

# Show commits that changed specific function
git log -L :functionName:path/to/file.js

# Show commits adding or removing specific string
git log -S"searchString"

# Show commits changing specific text (regex)
git log -G"regex pattern"

# Show commits in date range
git log --since="2 weeks ago"

# Show commits only in current branch
git log main..feature

# Show commits in either branch but not both
git log main...feature

# Show reflog for specific branch
git reflog show main

# Pretty format with colors
git log --pretty=format:"%C(yellow)%h%Creset %C(blue)%an%Creset %C(green)%ar%Creset - %s"

# Show commits since tag
git log v1.0..HEAD

# Show commits between two tags
git log v1.0..v2.0

# Count commits by author
git shortlog -sn
# Show word diff
git diff --word-diff

# Show character diff
git diff --word-diff-regex=.

# Patience algorithm (better results)
git diff --patience

# Histogram algorithm
git diff --histogram

# Highlight moved code
git diff --color-moved

# Show function context
git diff -W

# Show context lines
git diff -U10  # 10 lines of context

# Diff between working tree and commit
git diff HEAD~2

# Diff branch point
git diff $(git merge-base main feature)..feature

# Ignore specific files
git diff -- . ':!package-lock.json'
# Stash with message
git stash push -m "Work in progress on feature"

# Stash including untracked files
git stash -u

# Stash everything including ignored files
git stash -a

# Stash only specific files
git stash push -m "message" -- file1.js file2.js

# Stash and keep index (staged changes)
git stash --keep-index

# Show full diff of stash
git stash show -p stash@{0}

# Create branch from stash
git stash branch new-branch stash@{0}

# Apply stash to different branch
git checkout other-branch
git stash apply stash@{2}

# Stash with patch mode
git stash -p

# Stash only staged changes
git stash push --staged
# Rebase with autostash
git rebase --autostash main

# Rebase with strategy
git rebase -X theirs main  # Prefer their changes
git rebase -X ours main    # Prefer our changes

# Rebase preserving merges
git rebase --rebase-merges main

# Interactive rebase with autosquash
git rebase -i --autosquash main

# Rebase onto specific commit
git rebase --onto new-base old-base branch

# Rebase and execute command after each commit
git rebase -x "npm test" main

# Rebase with committer date
git rebase --committer-date-is-author-date main

# Edit todo list during rebase
git rebase --edit-todo
# Cherry-pick range of commits
git cherry-pick abc1234..def5678

# Cherry-pick excluding start commit
git cherry-pick abc1234^..def5678

# Cherry-pick with strategy
git cherry-pick -X theirs abc1234

# Cherry-pick and sign off
git cherry-pick -s abc1234

# Cherry-pick empty commits
git cherry-pick --allow-empty abc1234

# Cherry-pick with mainline parent (for merge commits)
git cherry-pick -m 1 merge-commit

# Cherry-pick from another repository
git --git-dir=../other-repo/.git format-patch -k -1 --stdout abc1234 | git am -3 -k
# List tags matching pattern
git tag -l "v1.*"

# Create annotated tag
git tag -a v1.0.0 -m "Version 1.0.0"

# Tag with GPG signature
git tag -s v1.0.0 -m "Signed version 1.0.0"

# Verify signed tag
git tag -v v1.0.0

# Delete remote tag
git push origin :refs/tags/v1.0.0

# Push annotated tags only
git push origin --follow-tags

# Sort tags by version
git tag --sort=version:refname

# Sort tags by date
git tag --sort=-creatordate

# List tags containing commit
git tag --contains abc1234

# Get latest tag
git describe --tags --abbrev=0

# Archive specific tag
git archive --format=zip --output=v1.0.0.zip v1.0.0

# Beautiful log
git config --global alias.lg "log --graph --oneline --decorate --all"
git config --global alias.lol "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

# Contributors
git config --global alias.contributors 'shortlog -sn'
git config --global alias.who 'shortlog -sne --all'

# Undo shortcuts
git config --global alias.undo 'reset HEAD~1 --mixed'
git config --global alias.undohard 'reset HEAD~1 --hard'

# List all aliases
git config --global alias.alias '!git config --get-regexp ^alias\\. | sed -e s/^alias\\.// -e s/\\ /\\ =\\ /'
# Find who changed specific line
git blame file.txt

# Find who changed line range
git blame -L 10,20 file.txt

# Search commits for string
git log --all --grep='search term'

# Find deleted file
git log --all --full-history -- path/to/file.txt

# Restore deleted file
git checkout $(git rev-list -n 1 HEAD -- deleted-file.txt)^ -- deleted-file.txt

# Show file at specific commit
git show HEAD~3:path/to/file.txt

# Count commits
git rev-list --count HEAD

# Find common ancestor
git merge-base branch1 branch2

# Clean untracked files (dry run)
git clean -n

# Clean everything
git clean -fdx

# Assume file unchanged
git update-index --assume-unchanged file.txt

# Skip worktree (better than assume-unchanged)
git update-index --skip-worktree file.txt

# Export repository to archive
git archive --format=zip --output=project.zip HEAD

# Create bundle (portable repo)
git bundle create repo.bundle --all

# Search in all branches
git grep "search term" $(git rev-list --all)

# Delete gone remote branches
git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -D

# Show repository statistics
git count-objects -vH

# Verify repository integrity
git fsck

# Authentication
gh auth login
gh auth logout
gh auth status

# Repository operations
gh repo create my-new-repo
gh repo clone owner/repo
gh repo fork owner/repo
gh repo view owner/repo

# Pull Requests
gh pr create --title "Title" --body "Body"
gh pr list
gh pr view 123
gh pr checkout 123
gh pr checks
gh pr merge 123
gh pr review 123 --approve
gh pr review 123 --request-changes
gh pr close 123

# Issues
gh issue create --title "Bug" --body "Description"
gh issue list
gh issue view 123
gh issue close 123
gh issue reopen 123

# Releases
gh release create v1.0.0
gh release list
gh release view v1.0.0
gh release download v1.0.0

# Gists
gh gist create file.txt
gh gist list
gh gist view gist-id
gh gist edit gist-id

# Actions
gh workflow list
gh workflow view workflow-name
gh run list
gh run view run-id
gh run watch

# Secrets
gh secret set SECRET_NAME
gh secret list

# API calls
gh api /user
gh api repos/:owner/:repo/issues
# Press '?' on any page to see shortcuts

# Repository shortcuts:
# t - File finder
# w - Branch selector
# s - Focus search
# l - Edit labels (on issues)
# y - Freeze URL to current commit

# Line highlighting
https://github.com/user/repo/blob/main/file.js#L10
https://github.com/user/repo/blob/main/file.js#L10-L20

# Diff/Patch URLs
https://github.com/user/repo/pull/123.diff
https://github.com/user/repo/pull/123.patch

# Ignore whitespace in diff
https://github.com/user/repo/pull/123?w=1

# Adjust tab size
https://github.com/user/repo/blob/main/file.js?ts=4

# Blame view
https://github.com/user/repo/blame/main/file.js

Important

Problem Recovery Toolkit: These commands will save you from almost any Git disaster.

# Undo last commit but keep changes
git reset --soft HEAD~1

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

# Recover deleted branch
git reflog
git checkout -b recovered-branch <commit-sha>

# Undo bad merge
git reset --hard HEAD~1  # If not pushed
git revert -m 1 <merge-commit>  # If pushed

# Fix wrong commit message
git commit --amend -m "Correct message"

# Remove file from all history
git filter-branch --tree-filter 'rm -f passwords.txt' HEAD

# Or use BFG (faster)
bfg --delete-files passwords.txt

# Recover lost commits
git fsck --lost-found

# Fix detached HEAD
git checkout main
git branch temp-branch <commit-sha>

# Undo git reset --hard
git reflog
git reset --hard HEAD@{1}

# Remove untracked files safely
git clean -n  # Dry run first
git clean -fd  # Then remove

# Fix "pathspec did not match"
git rm --cached <file>
git commit -m "Remove file from tracking"

# Enable garbage collection
git config --global gc.auto 4096

# Manual garbage collection
git gc --aggressive --prune=now

# Enable delta compression
git config --global core.compression 9

# Enable parallel operations
git config --global core.preloadindex true

# Use filesystem monitoring
git config --global core.fsmonitor true

# Shallow clone for faster CI
git clone --depth 1 repo-url

# Sparse checkout for large repos
git clone --filter=blob:none --sparse repo-url
git sparse-checkout set path/to/dir

# Git LFS for large files
git lfs install
git lfs track "*.psd"
git add .gitattributes

# Repack repository
git repack -a -d --depth=250 --window=250

# Node.js
node_modules/
npm-debug.log*
.env
dist/
build/

# Python
__pycache__/
*.py[cod]
venv/
.pytest_cache/

# Java
*.class
target/
*.jar
*.war

# macOS
.DS_Store
.AppleDouble

# Windows
Thumbs.db
Desktop.ini

# IDEs
.vscode/
.idea/
*.swp
*.swo

# Logs
*.log
logs/

# Secrets
*.pem
*.key
.env
secrets.yml

Tip

Master These and You’ll Be a Git Expert

  1. Use git reflog religiously - It’s your time machine
  2. Commit often, push frequently - Small commits are easier to revert
  3. Write meaningful commit messages - Future you will thank you
  4. Use branches for everything - Keep main clean
  5. Test before you merge - Always run tests
  6. Learn interactive rebase - Clean up history before pushing
  7. Use git stash - Don’t commit half-baked work
  8. Set up aliases - Save keystrokes
  9. Read git log - Understand project history
  10. Practice on test repos - Break things to learn

You are now a Git and GitHub master! 🎉

This comprehensive guide covered 1000+ commands, all workflows, GitHub features, troubleshooting, and best practices. Keep this as your reference and contribute to open source!