C
h
i
L
L
u
.
.
.

Git Mastery Guide

Complete guide from basics to advanced Git workflows

Understanding Git: The Foundation of Modern Development

Git is a distributed version control system that has revolutionized how developers track changes, collaborate on code, and manage software projects. Created by Linus Torvalds in 2005, Git provides powerful tools for managing project history and enabling team collaboration.

Why Git Matters

  • • Track every change in your codebase
  • • Collaborate seamlessly with teams
  • • Experiment safely with branches
  • • Recover from mistakes easily
  • • Maintain project history indefinitely

Key Benefits

  • • Distributed development
  • • Non-linear workflow support
  • • Fast performance
  • • Data integrity guarantees
  • • Free and open source

1. Git Fundamentals & Basic Concepts

What is Git?

Git is a distributed version control system designed to handle everything from small to very large projects with speed and efficiency. Unlike centralized version control systems, every Git directory on every computer is a full-fledged repository with complete history and version-tracking capabilities.

Key Insight: Git doesn't just store file differences - it takes snapshots of your entire project. When you commit, Git stores a reference to that snapshot, making operations incredibly fast.

The Three States of Git

Understanding Git's three main states is crucial for mastering version control. These states define where your files can reside and how they move between different stages.

1

Working Directory

Where you modify files. Changes exist only on your local machine.

2

Staging Area

Where you prepare changes for the next commit. Acts as a preview area.

3

Repository

Where committed changes are permanently stored as snapshots.

Git Workflow Visualization

Working Directory   →   git add   →   Staging Area   →   git commit   →   Repository
     ↓                          ↓                       ↓
 Modify files            Stage changes          Save snapshot
 Untracked changes       Ready to commit        Permanent history

Initial Git Setup

Before you start using Git, you need to configure your environment. This includes setting up your identity, preferred editor, and other important settings.

Basic Configuration

# Set your identity (required before first commit)
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# Set default branch name (modern practice)
git config --global init.defaultBranch main

# Configure line ending handling
git config --global core.autocrlf true   # Windows
git config --global core.autocrlf input  # Linux/Mac

# Set your preferred text editor
git config --global core.editor "code --wait"  # VS Code
git config --global core.editor "vim"          # Vim
git config --global core.editor "nano"         # Nano

# View your configuration
git config --list

# Check specific setting
git config user.name

Pro Tip: Use --global for system-wide settings or omit it for repository-specific configuration. Repository-specific settings override global ones.

2. Essential Git Commands & Workflows

Creating and Cloning Repositories

Start by creating a new repository or cloning an existing one. This is your first step in any Git project.

Repository Management

# Initialize a new repository
mkdir my-project
cd my-project
git init

# Clone an existing repository
git clone https://github.com/user/repository.git
git clone https://github.com/user/repository.git my-folder  # Specific folder

# Clone with SSH (requires SSH key setup)
git clone git@github.com:user/repository.git

# Check repository status
git status

# View remote repositories
git remote -v

# Add a remote repository
git remote add origin https://github.com/user/repo.git

The Basic Git Workflow

The daily Git workflow involves making changes, staging them, and committing. This cycle forms the foundation of version control.

Daily Workflow Example

# Check what's changed
git status

# Add files to staging area
git add filename.txt           # Specific file
git add .                      # All files in current directory
git add -A                     # All changes including deletions

# Commit changes with a message
git commit -m "Add user authentication feature"

# View commit history
git log
git log --oneline              # Compact view
git log --graph --oneline      # Visual history with branches
git log -p                     # Show changes in each commit

# Remove files from staging
git reset filename.txt         # Unstage specific file
git reset                      # Unstage all files

Best Practice: Write clear, descriptive commit messages. Start with a verb in imperative mood (Add, Fix, Update, Remove) and keep the first line under 50 characters.

File Management in Git

Git provides commands to manage files within your repository, including moving, removing, and ignoring files.

File Operations

# Remove files from repository
git rm filename.txt            # Remove and stage deletion
git rm --cached filename.txt   # Remove from repo but keep locally

# Move or rename files
git mv oldname.txt newname.txt

# Ignore files with .gitignore
# Create .gitignore file with patterns:

# Dependencies
node_modules/
vendor/

# Build outputs
dist/
build/
*.jar

# Environment files
.env
.env.local

# IDE files
.vscode/
.idea/

# OS files
.DS_Store
Thumbs.db

# Logs
*.log
logs/

Real-World Example

# Complete workflow example
mkdir awesome-project
cd awesome-project
git init

# Create initial files
echo "# My Awesome Project" > README.md
echo "console.log('Hello Git!')" > app.js

# Check status
git status

# Stage and commit
git add .
git commit -m "Initial commit: Add README and basic app"

# Make changes
echo "// New feature" >> app.js
git add app.js
git commit -m "Add new feature to app"

# View history
git log --oneline

3. Branching & Merging Strategies

Understanding Branches

Branches are parallel lines of development that allow you to work on features without affecting the main codebase. They're Git's killer feature for managing complex development workflows.

Why Use Branches?

  • Isolate features: Work on new features without breaking main code
  • Parallel development: Multiple team members can work simultaneously
  • Safe experimentation: Try new ideas without risk
  • Organized releases: Prepare releases while development continues

Branch Types

  • main/master: Production-ready code
  • develop: Integration branch for features
  • feature/*: Individual feature development
  • hotfix/*: Emergency production fixes
  • release/*: Release preparation

Branch Management Commands

# List branches
git branch                    # Local branches
git branch -r                 # Remote branches
git branch -a                 # All branches

# Create and switch to new branch
git branch feature-branch     # Create branch
git checkout feature-branch   # Switch to branch
git checkout -b feature-branch # Create and switch in one command

# Delete branches
git branch -d feature-branch  # Safe delete (only if merged)
git branch -D feature-branch  # Force delete

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

# View branch relationships
git log --oneline --graph --all

Merging vs Rebasing

Two main strategies for integrating changes: merging preserves history while rebasing creates a linear history. Each has its use cases and trade-offs.

Merging

  • ✅ Preserves complete history
  • ✅ Safe for shared branches
  • ✅ Maintains context of parallel development
  • ❌ Can create complex history
  • ❌ Merge commits can clutter history

Rebasing

  • ✅ Creates clean, linear history
  • ✅ Easier to follow project evolution
  • ✅ No unnecessary merge commits
  • ❌ Rewrites history (dangerous for shared branches)
  • ❌ Can be complex with conflicts

Merging and Rebasing Examples

# Merging branches
git checkout main
git merge feature-branch          # Fast-forward merge
git merge --no-ff feature-branch  # Always create merge commit

# Rebasing branches
git checkout feature-branch
git rebase main                   # Rebase feature onto main

# Interactive rebase (rewrite history)
git rebase -i HEAD~3              # Rebase last 3 commits

# Options in interactive rebase:
# pick    - use commit
# reword  - use commit, but edit message
# edit    - use commit, but stop for amending
# squash  - combine with previous commit
# fixup   - like squash, but discard message
# drop    - remove commit

# Handling merge conflicts
git status                        # See conflicted files
# Edit files to resolve conflicts <<<<<<<, =======, >>>>>>>
git add resolved-file.txt         # Mark as resolved
git commit                        # Complete the merge
git merge --abort                 # Cancel merge

Feature Branch Workflow

A practical example of developing a feature using branches, keeping main clean, and integrating changes safely.

Complete Feature Development

# Start from main branch
git checkout main
git pull origin main

# Create feature branch
git checkout -b feature/payment-integration

# Make commits on feature branch
echo "// Payment gateway setup" > payment.js
git add payment.js
git commit -m "Setup payment gateway"

echo "// Process payment" >> payment.js
git add payment.js
git commit -m "Implement payment processing"

# Update with latest main (keep feature current)
git checkout main
git pull origin main
git checkout feature/payment-integration
git rebase main

# Resolve any conflicts during rebase
# Edit conflicted files, then:
git add resolved-file.js
git rebase --continue

# Merge feature to main
git checkout main
git merge --no-ff feature/payment-integration
git push origin main

# Clean up feature branch
git branch -d feature/payment-integration

Team Workflow: In team environments, use pull requests (GitHub) or merge requests (GitLab) for code review before merging features. This ensures code quality and knowledge sharing.

4. Collaboration & Remote Repositories

Working with Remote Repositories

Git's distributed nature enables powerful collaboration patterns. Remote repositories act as central hubs for team coordination.

Remote Repository Management

# Add remote repository
git remote add origin https://github.com/user/repo.git

# View remotes
git remote -v

# Remove remote
git remote remove origin

# Rename remote
git remote rename old-name new-name

# Push to remote
git push origin main
git push -u origin main           # Set upstream branch
git push origin feature-branch    # Push specific branch

# Pull changes from remote
git pull origin main
git pull --rebase origin main     # Pull with rebase

# Fetch without merging
git fetch origin                  # Download changes
git merge origin/main             # Merge fetched changes

# Push new branch to remote
git push -u origin feature-branch

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

Collaboration Workflows

Different teams use different collaboration patterns. Choose the workflow that fits your team's size and process.

Centralized Workflow

Simple workflow where all developers push to a single repository. Good for small teams.

# Team member workflow
git clone https://github.com/team/repo.git
git checkout -b feature/my-feature

# Work and commit
git add .
git commit -m "My feature"

# Push to remote
git push origin feature/my-feature

# Create Pull Request on GitHub
# After PR approval and merge:
git checkout main
git pull origin main
git branch -d feature/my-feature

Forking Workflow

Common in open source. Each developer works on their own fork. Excellent for large teams and public projects.

# Fork repository on GitHub UI first
# Then clone your fork
git clone https://github.com/yourname/repo.git

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

# Sync with upstream
git fetch upstream
git merge upstream/main

# Work on feature branch
git checkout -b feature/my-contribution

# Push to your fork
git push -u origin feature/my-contribution

# Create PR from your fork to original repo
# After PR merge, update your fork:
git checkout main
git fetch upstream
git merge upstream/main
git push origin main

Tags and Releases

Tags mark specific points in history as important, typically for version releases. They provide permanent references to specific commits.

Tag Management

# Create tags
git tag v1.0.0                          # Lightweight tag
git tag -a v1.0.0 -m "Version 1.0.0"    # Annotated tag (recommended)

# Push tags to remote
git push origin v1.0.0
git push origin --tags                   # Push all tags

# List tags
git tag
git tag -l "v1.*"                        # Filter tags

# Show tag details
git show v1.0.0

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

# Checkout specific tag
git checkout v1.0.0

# Create branch from tag
git checkout -b version-1.0 v1.0.0

Semantic Versioning: Use semantic versioning (SemVer) for tags: MAJOR.MINOR.PATCH. Major for breaking changes, minor for new features, patch for bug fixes.

5. Advanced Git Techniques

Stashing Changes

Stashing allows you to temporarily save uncommitted changes so you can work on something else, then reapply them later. Perfect for context switching.

Stash Operations

# Save uncommitted changes
git stash
git stash save "Work in progress on user auth"  # Stash with message

# List stashes
git stash list

# Apply stashed changes
git stash apply               # Apply latest stash
git stash apply stash@{1}     # Apply specific stash

# Remove stashes
git stash pop                 # Apply and remove latest
git stash drop stash@{1}      # Remove specific stash
git stash clear               # Remove all stashes

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

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

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

Use Case: When you need to quickly switch branches but have uncommitted work, use git stash to save your progress, switch branches, then git stash pop to restore your work.

Undoing Changes and Rewriting History

Git provides multiple ways to undo changes at different stages. Understanding these tools is crucial for recovering from mistakes.

Undo Operations

# Undo working directory changes
git checkout -- filename.txt           # Discard changes in file
git checkout -- .                      # Discard all changes

# Unstage files
git reset HEAD filename.txt            # Unstage specific file
git reset                              # Unstage all files

# Amend last commit
git commit --amend                     # Edit last commit message
git commit --amend --no-edit           # Add changes to last commit

# Reset to previous commit
git reset --soft HEAD~1                # Keep changes staged
git reset --mixed HEAD~1               # Keep changes unstaged (default)
git reset --hard HEAD~1                # Discard all changes

# Revert a commit (safe for shared history)
git revert COMMIT_HASH                 # Create undo commit
git revert --no-commit COMMIT_HASH     # Revert without committing

# Find lost commits
git reflog                            # Show HEAD movements
git fsck --lost-found                 # Find dangling commits

Reset --soft

Moves HEAD, keeps changes staged. Use to recommit with different message.

Reset --mixed

Moves HEAD, keeps changes unstaged. Default behavior.

Reset --hard

Moves HEAD, discards all changes. Dangerous but useful.

Advanced History Manipulation

Powerful tools for cleaning up history, combining commits, and managing complex project timelines.

Interactive Rebase and Cherry-picking

# Interactive rebase last 5 commits
git rebase -i HEAD~5

# During interactive rebase, you can:
# - Reorder commits
# - Combine commits (squash)
# - Edit commit messages
# - Split commits
# - Remove commits

# Cherry-pick specific commits
git cherry-pick COMMIT_HASH            # Apply specific commit
git cherry-pick COMMIT1..COMMIT2       # Apply range of commits
git cherry-pick --no-commit COMMIT_HASH # Apply without committing

# Cherry-pick with conflict resolution
git cherry-pick COMMIT_HASH
# Resolve conflicts, then:
git add resolved-files
git cherry-pick --continue

# Abort cherry-pick
git cherry-pick --abort

Warning: Never rewrite history (rebase, reset --hard) on branches that others are using. These operations change commit SHAs and can cause serious collaboration issues.

Git Bisect for Bug Hunting

Bisect uses binary search to quickly find which commit introduced a bug. Incredibly efficient for large codebases.

Using Git Bisect

# Start bisect session
git bisect start
git bisect bad                 # Current commit has the bug
git bisect good v1.0.0         # This commit was good

# Git automatically checks out a commit in the middle
# Test the code and mark it:
git bisect good                # Current commit is good
git bisect bad                 # Current commit has the bug

# Git continues narrowing down until it finds the first bad commit

# End bisect session
git bisect reset

# Automated bisect with test script
git bisect start HEAD v1.0.0
git bisect run npm test        # Run tests automatically

# Complex test script
git bisect run ./test-script.sh

Example Test Script

#!/bin/bash
# test-script.sh

# Run your test suite
npm test

# Return codes:
# 0 - good commit
# 1 - bad commit
# 125 - skip this commit

if [ $? -eq 0 ]; then
  exit 0
else
  exit 1
fi

6. Git Hooks & Automation

Understanding Git Hooks

Git hooks are scripts that run automatically when certain Git events occur. They're perfect for automating checks, notifications, and enforcing standards.

Hook Locations

Hooks are stored in .git/hooks/ directory. Sample hooks are provided with .sample extension - remove the extension to activate.

Common Client-Side Hooks

# Pre-commit: Before commit is created
.git/hooks/pre-commit

# Prepare-commit-msg: Before commit message editor
.git/hooks/prepare-commit-msg

# Commit-msg: After commit message is created
.git/hooks/commit-msg

# Post-commit: After commit is completed
.git/hooks/post-commit

# Pre-push: Before pushing to remote
.git/hooks/pre-push

# Pre-rebase: Before rebasing
.git/hooks/pre-rebase

Practical Hook Examples

Implement hooks to automate code quality checks, enforce standards, and improve development workflow.

Pre-commit Hook for Code Quality

#!/bin/bash
# .git/hooks/pre-commit

echo "Running pre-commit checks..."

# Check for TODO comments in staged files
if git diff --cached --name-only | xargs grep -n "TODO"; then
  echo "Error: TODO comments found in staged files"
  exit 1
fi

# Run tests
echo "Running tests..."
npm test
if [ $? -ne 0 ]; then
  echo "Tests failed! Commit aborted."
  exit 1
fi

# Check code style
echo "Running linter..."
npm run lint
if [ $? -ne 0 ]; then
  echo "Linting failed! Commit aborted."
  exit 1
fi

# Check for large files
MAX_FILE_SIZE=5242880  # 5MB
for file in $(git diff --cached --name-only); do
  file_size=$(git show :$file | wc -c)
  if [ $file_size -gt $MAX_FILE_SIZE ]; then
    echo "Error: File $file is too large ($file_size bytes)"
    exit 1
  fi
done

echo "All checks passed! Proceeding with commit."

Commit-message Hook for Format Enforcement

#!/bin/bash
# .git/hooks/commit-msg

COMMIT_MSG_FILE=$1
COMMIT_MSG=$(cat $COMMIT_MSG_FILE)

# Commit message format: <type>: <description>
if ! echo "$COMMIT_MSG" | grep -qE "^(feat|fix|docs|style|refactor|test|chore|perf|ci): .{10,}"; then
  echo "Invalid commit message format!"
  echo "Format: <type>: <description> (min 10 chars)"
  echo "Valid types: feat, fix, docs, style, refactor, test, chore, perf, ci"
  echo "Your message: $COMMIT_MSG"
  exit 1
fi

# Check message length
FIRST_LINE=$(echo "$COMMIT_MSG" | head -1)
if [ ${#FIRST_LINE} -gt 72 ]; then
  echo "Commit message first line too long (max 72 characters)"
  exit 1
fi

Git Aliases for Productivity

Create shortcuts for frequently used Git commands to speed up your workflow and reduce typing.

Useful Git Aliases

# Add to ~/.gitconfig or project .git/config

[alias]
  # Shortcuts
  co = checkout
  br = branch
  ci = commit
  st = status
  df = diff
  lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
  
  # Enhanced commands
  undo = reset --soft HEAD~1
  amend = commit --amend --no-edit
  wipe = reset --hard HEAD
  cleanup = "!git fetch --prune && git branch --merged | grep -v '\*\|main\|master\|develop' | xargs -n 1 git branch -d"
  
  # Status shortcuts
  ss = status -sb
  ll = log --oneline -10
  
  # Branch management
  recent = for-each-ref --sort=-committerdate refs/heads/ --format='%(color:yellow)%(refname:short)%(color:reset) - %(contents:subject) %(color:green)(%(committerdate:relative))'
  gone = "!git fetch -p && git for-each-ref --format '%(refname:short) %(upstream:track)' | awk '$2 == "[gone]" {print $1}' | xargs -r git branch -D"
  
  # Stashing
  sp = stash pop
  sl = stash list
  sa = stash apply
  
  # File operations
  unstage = reset HEAD --
  discard = checkout --

Pro Tip: Use git config --global alias.co checkout to create aliases directly from command line, or edit ~/.gitconfig file directly.

7. Git Troubleshooting & Best Practices

Common Git Issues and Solutions

Even experienced developers encounter Git problems. Here are solutions to common issues.

Merge Conflicts

# Identify conflicted files
git status

# Use mergetool (configure your preferred tool)
git mergetool

# Manual resolution - look for:
# <<<<<<< HEAD
# your changes
# =======
# their changes  
# >>>>>>> branch-name

# Edit files to resolve, then:
git add resolved-file.txt
git commit

# Abort merge entirely
git merge --abort
git rebase --abort

Detached HEAD State

# If you see: "You are in 'detached HEAD' state"
git checkout -b temporary-branch  # Create branch from current state
git checkout main                 # Go back to main
git merge temporary-branch        # Merge changes if desired

# Or simply return to main without saving
git checkout main

Recovering Lost Commits

# Find lost commits
git reflog                        # Show all HEAD movements
git fsck --lost-found            # Find dangling commits

# Recover from reflog
git checkout -b recovered-branch COMMIT_HASH_FROM_REFLOG

# Recover deleted branch
git reflog | grep "branch-name"
git checkout -b restored-branch COMMIT_HASH

Best Practices for Teams

Establishing and following Git best practices ensures smooth collaboration and maintainable project history.

Commit Message Convention

Format: <type>: <subject>

Types:
- feat:     New feature
- fix:      Bug fix  
- docs:     Documentation
- style:    Formatting, missing semi-colons
- refactor: Code restructuring
- test:     Adding tests
- chore:    Maintenance tasks
- perf:     Performance improvements
- ci:       CI/CD changes

Examples:
feat: Add user authentication system
fix: Resolve login page crash on mobile
docs: Update API documentation
style: Format code with prettier

Branch Naming Convention

# Feature branches
feature/user-authentication
feature/payment-integration

# Bug fix branches  
bugfix/fix-login-issue
bugfix/resolve-crash-on-ios

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

# Release branches
release/v1.2.0
release/2023-11-update

# Chore branches
chore/update-dependencies
chore/ci-pipeline-fix

Security and Performance

Keep your repositories secure and performant with these advanced practices.

Security Considerations

# Remove sensitive data from history
git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch secrets.txt' \
  --prune-empty --tag-name-filter cat -- --all

# Update remote
git push origin --force --all

# Scan for secrets in history
# Use tools like:
# - git-secrets (AWS)
# - truffleHog
# - Gitleaks

# Large file storage (Git LFS)
git lfs install               # Setup LFS
git lfs track "*.psd"         # Track large files
git lfs track "*.mp4"
git lfs ls-files              # List tracked large files

# Performance optimization
git gc --aggressive           # Garbage collection
git prune                     # Remove unreachable objects

# Shallow clone for large repos
git clone --depth 1 https://github.com/user/repo.git

Git Workflow Cheat Sheet

Quick reference for common Git workflows and commands.

Daily Workflow

# Start working
git status
git add .
git commit -m "feat: add feature"
git push origin current-branch

# Sync with team
git fetch origin
git merge origin/main
# OR
git pull --rebase origin main

# Review changes
git log --oneline -10
git diff
git diff --staged

Feature Development

# New feature
git checkout -b feature/name
# Work, commit, push
git push -u origin feature/name
# Create PR, get review, merge

# Emergency fix
git stash
git checkout main
git pull origin main  
git checkout -b hotfix/issue
# Fix, commit, push, merge
git checkout original-branch
git stash pop

Conclusion

🎉 Congratulations on completing the Git Mastery Guide! You now have comprehensive knowledge of Git from basic commands to advanced workflows.

Key Takeaways

  • Commit often: Small, focused commits are easier to understand and manage
  • Use branches: Isolate work and reduce conflicts
  • Write good messages: Commit messages serve as project documentation
  • Learn to undo: Git provides many safety nets for mistakes
  • Follow team conventions: Consistency improves collaboration

Continue Learning

  • • Practice with real projects
  • • Explore Git internals (objects, references)
  • • Learn advanced rebase techniques
  • • Study different team workflows (GitFlow, Trunk-based)
  • • Contribute to open source projects

Remember: Git mastery comes with practice. The more you use these commands and workflows, the more natural they'll become. Don't be afraid to experiment in safe environments!