
The Ultimate Developer's Guide to Git Commands
Master Git from beginner to expert with practical examples, real-world scenarios, and pro tips
In modern software development, Git is as essential as the code itself. It’s the industry-standard Version Control System (VCS) that allows developers to track changes, collaborate seamlessly, and manage complex projects without fear of losing work. Whether you’re a beginner just starting your coding journey or a seasoned pro, mastering the core Git commands is a fundamental skill.
This comprehensive guide provides everything you need to know about Git commands, organized into logical sections with real-world examples, common pitfalls, and expert tips to help you build a solid foundation and advance to mastery.
Table of Contents
- 1. Setting Up Your Project
- 2. The Core Workflow: Staging and Committing
- 3. Branching: Parallel Universes for Your Code
- 4. Collaboration: Working with Remote Repositories
- 5. Oops! How to Undo Mistakes
- 6. Advanced Git Techniques
- 7. Lesser-known Git Commands
- 8. Git Best Practices & Workflows
- 9. Troubleshooting Common Issues
- 10. Frequently Asked Questions (FAQ)
- 11. References
1. Setting Up Your Project
These are the first commands you’ll ever use. They either create a new version-controlled project from scratch or make a local copy of an existing one.
Core Setup Commands
Command | Description | Example |
---|---|---|
git init | Initializes a new Git repository in your current directory. Creates a hidden .git subdirectory with all necessary metadata. | git init my-project |
git clone [url] | Creates a local copy of a remote repository. Most common way to start working on existing projects. | git clone https://github.com/user/repo.git |
git config | Sets personal configuration details. Use --global for system-wide settings. | git config --global user.name "Your Name" |
Real-World Setup Scenarios
Scenario 1: Starting a New Project from Scratch
# Create and navigate to your project directory
mkdir my-awesome-app
cd my-awesome-app
# Initialize Git repository
git init
# Create initial files
echo "# My Awesome App" > README.md
echo "node_modules/" > .gitignore
# Make your first commit
git add .
git commit -m "Initial commit: Add README and gitignore"
Scenario 2: Contributing to an Open Source Project
# Fork the repository on GitHub, then clone your fork
git clone https://github.com/yourusername/open-source-project.git
cd open-source-project
# Add the original repository as upstream for staying in sync
git remote add upstream https://github.com/original-author/open-source-project.git
# Verify your remotes
git remote -v
# origin https://github.com/yourusername/open-source-project.git (fetch)
# origin https://github.com/yourusername/open-source-project.git (push)
# upstream https://github.com/original-author/open-source-project.git (fetch)
# upstream https://github.com/original-author/open-source-project.git (push)
Scenario 3: Setting Up Git for the First Time
# Essential global configurations
git config --global user.name "John Doe"
git config --global user.email "[email protected]"
git config --global init.defaultBranch main
# Helpful configurations
git config --global core.editor "code --wait" # Use VS Code as editor
git config --global merge.tool "code --wait" # Use VS Code for merge conflicts
git config --global color.ui auto # Enable colored output
git config --global pull.rebase true # Always rebase on pull
# View all configurations
git config --list --global
Pro Tips for Setup
- Always create a
.gitignore
file before your first commit to avoid tracking unnecessary files - Use SSH keys for GitHub/GitLab to avoid password prompts:
git clone [email protected]:user/repo.git
- Set up aliases for common commands:
git config --global alias.st status
2. The Core Workflow: Staging and Committing
This is the day-to-day cycle of saving your work. Understanding the three areas (working directory, staging area, repository) is crucial for Git mastery.
The Three Areas of Git
Working Directory → Staging Area → Repository
(git add) (git commit)
Core Workflow Commands
Command | Description | Example |
---|---|---|
git status | Shows current state: modified files, staged changes, untracked files. Your main dashboard. | git status --short |
git add [file] | Stages file changes for the next commit. Use . to stage all changes. | git add src/main.js |
git diff | Shows unstaged changes. Use --staged to see staged changes. | git diff --staged |
git commit -m "message" | Creates a permanent snapshot with a descriptive message. | git commit -m "Fix login bug" |
Real-World Workflow Examples
Scenario 1: Feature Development Workflow
# Check current status
git status
# On branch feature/user-authentication
# Changes not staged for commit:
# modified: src/auth.js
# modified: src/login.js
# Untracked files:
# src/auth-utils.js
# Review what you've changed
git diff src/auth.js
# Stage specific files
git add src/auth.js src/auth-utils.js
# Check what's staged
git diff --staged
# Make a commit with a descriptive message
git commit -m "Add password hashing to authentication system
- Implement bcrypt for secure password storage
- Add utility functions for password validation
- Update login flow to use hashed passwords"
# Continue working...
echo "console.log('Debug info');" >> src/login.js
# Quick add and commit for small changes
git add src/login.js
git commit -m "Add debug logging to login process"
Scenario 2: Selective Staging (Interactive)
# You've made changes to multiple parts of a file but want to commit them separately
git add -p src/large-file.js
# Git will show you each change and ask:
# Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]?
# y - yes, stage this hunk
# n - no, don't stage this hunk
# s - split the hunk into smaller hunks
# e - manually edit the hunk
# This allows you to create focused, logical commits
Scenario 3: Fixing Commit Messages
# Oops, typo in the last commit message
git commit --amend -m "Fix user authentication bug (not 'auhtentication')"
# Add forgotten file to the last commit
git add forgotten-file.js
git commit --amend --no-edit # Keep the same message
Advanced Staging Techniques
Stashing Partial Work
# You're in the middle of a feature but need to fix a urgent bug
git stash -m "WIP: user profile feature - half complete"
# Switch to main branch, fix bug, then come back
git checkout main
# ... fix bug and commit ...
git checkout feature/user-profile
# Restore your work
git stash pop
Using .gitignore Effectively
# Create comprehensive .gitignore
cat > .gitignore << EOF
# Dependencies
node_modules/
*.log
# Build outputs
dist/
build/
# Environment variables
.env
.env.local
# IDE files
.vscode/
.idea/
*.swp
# OS files
.DS_Store
Thumbs.db
EOF
Commit Message Best Practices
Good Commit Messages:
git commit -m "Fix memory leak in image processing pipeline"
git commit -m "Add user authentication endpoints
- POST /api/auth/login
- POST /api/auth/register
- GET /api/auth/profile
- Includes JWT token validation"
Bad Commit Messages:
git commit -m "fix stuff"
git commit -m "changes"
git commit -m "asdf"
3. Branching: Parallel Universes for Your Code
Branches are Git’s killer feature, allowing you to create independent lines of development. Master branching to unlock Git’s full potential.
Core Branching Commands
Command | Description | Example |
---|---|---|
git branch | Lists branches. Create new branch with name. | git branch feature/shopping-cart |
git checkout [branch] | Switches to specified branch. Use -b to create and switch. | git checkout -b hotfix/payment-bug |
git merge [branch] | Combines branch into current branch. Creates merge commit. | git merge feature/user-auth |
git rebase [branch] | Rewrites history by replaying commits on top of another branch. | git rebase main |
git switch [branch] | Modern alternative to checkout for switching branches. | git switch feature/new-ui |
Real-World Branching Scenarios
Scenario 1: Feature Branch Workflow
# Start from main branch
git checkout main
git pull origin main
# Create and switch to feature branch
git checkout -b feature/shopping-cart
# Work on your feature
echo "Shopping cart functionality" > cart.js
git add cart.js
git commit -m "Add shopping cart base functionality"
echo "Add to cart method" >> cart.js
git add cart.js
git commit -m "Implement add to cart functionality"
# Push feature branch to remote
git push -u origin feature/shopping-cart
# When feature is complete, merge back to main
git checkout main
git merge feature/shopping-cart
# Clean up
git branch -d feature/shopping-cart
git push origin --delete feature/shopping-cart
Scenario 2: Hotfix Workflow
# Critical bug found in production!
git checkout main
git checkout -b hotfix/critical-security-fix
# Make the fix
echo "Security patch applied" > security-fix.js
git add security-fix.js
git commit -m "Fix critical XSS vulnerability in user input validation"
# Merge hotfix to main
git checkout main
git merge hotfix/critical-security-fix
# Also merge to development branch
git checkout develop
git merge hotfix/critical-security-fix
# Deploy to production
git tag v1.2.1
git push origin main --tags
Scenario 3: Interactive Rebase for Clean History
# You have messy commit history on your feature branch
git log --oneline
# a1b2c3d Fix typo in variable name
# d4e5f6g Add user validation
# g7h8i9j Fix validation logic
# j0k1l2m Add user validation (again)
# m3n4o5p Initial user validation attempt
# Clean it up with interactive rebase
git rebase -i HEAD~5
# Your editor opens with:
# pick m3n4o5p Initial user validation attempt
# pick j0k1l2m Add user validation (again)
# pick g7h8i9j Fix validation logic
# pick d4e5f6g Add user validation
# pick a1b2c3d Fix typo in variable name
# Change to:
# pick m3n4o5p Initial user validation attempt
# squash j0k1l2m Add user validation (again)
# squash g7h8i9j Fix validation logic
# squash d4e5f6g Add user validation
# squash a1b2c3d Fix typo in variable name
# Result: Clean single commit with all the work
Branching Strategies
Git Flow
# Main branches
main # Production-ready code
develop # Integration branch for features
# Supporting branches
feature/ # New features (branch from develop)
release/ # Preparing new production release
hotfix/ # Quick fixes to production
# Example Git Flow workflow
git checkout develop
git checkout -b feature/new-dashboard
# ... work on feature ...
git checkout develop
git merge feature/new-dashboard
GitHub Flow (Simpler)
# Only main branch + feature branches
main # Always deployable
feature/new-feature # Work happens here
# Workflow
git checkout main
git checkout -b feature/new-dashboard
# ... work and commit ...
git push origin feature/new-dashboard
# Create pull request on GitHub
# After review and approval, merge to main
Advanced Branching Techniques
Cherry-picking Specific Commits
# You want just one commit from another branch
git cherry-pick a1b2c3d
# Cherry-pick multiple commits
git cherry-pick a1b2c3d..e5f6g7h
# Cherry-pick with custom message
git cherry-pick a1b2c3d --edit
Branch Comparison
# See what's in feature branch that's not in main
git log main..feature/shopping-cart
# See what's in main that's not in feature branch
git log feature/shopping-cart..main
# Compare two branches
git diff main...feature/shopping-cart
4. Collaboration: Working with Remote Repositories
Git’s distributed nature shines when working with teams. Master remote operations to collaborate effectively.
Core Collaboration Commands
Command | Description | Example |
---|---|---|
git remote add [alias] [url] | Links local repo to remote repository. | git remote add origin https://github.com/user/repo.git |
git fetch [alias] | Downloads remote changes without merging them. | git fetch origin |
git pull | Fetches and merges remote changes into current branch. | git pull origin main |
git push [alias] [branch] | Uploads local commits to remote repository. | git push origin feature-branch |
Real-World Collaboration Scenarios
Scenario 1: Daily Team Collaboration
# Start your day by syncing with team changes
git checkout main
git pull origin main
# Create your feature branch
git checkout -b feature/user-notifications
# Work on your feature throughout the day
echo "Notification system" > notifications.js
git add notifications.js
git commit -m "Add basic notification structure"
# Before lunch, push your progress
git push -u origin feature/user-notifications
# After lunch, a teammate updated main branch
# Sync your feature branch with latest main
git fetch origin
git rebase origin/main
# If conflicts occur during rebase:
# 1. Fix conflicts in files
# 2. git add fixed-files
# 3. git rebase --continue
# Push your updated branch (force push needed after rebase)
git push --force-with-lease origin feature/user-notifications
# When feature is complete, create pull request
# After review and approval, clean up
git checkout main
git pull origin main
git branch -d feature/user-notifications
Scenario 2: Contributing to Open Source
# Fork repository on GitHub first, then:
git clone https://github.com/yourusername/awesome-project.git
cd awesome-project
# Add upstream remote to stay in sync
git remote add upstream https://github.com/maintainer/awesome-project.git
# Create feature branch
git checkout -b fix/documentation-typos
# Make your changes
echo "Fixed typos in README" > README.md
git add README.md
git commit -m "Fix typos in installation instructions"
# Before submitting PR, sync with upstream
git fetch upstream
git rebase upstream/main
# Push to your fork
git push origin fix/documentation-typos
# Create pull request on GitHub
# After it's merged, clean up
git checkout main
git pull upstream main
git push origin main
git branch -d fix/documentation-typos
Scenario 3: Handling Merge Conflicts in Team Environment
# You and a teammate modified the same file
git pull origin main
# Auto-merging src/app.js
# CONFLICT (content): Merge conflict in src/app.js
# Automatic merge failed; fix conflicts and then commit the result.
# Check which files have conflicts
git status
# You have unmerged paths.
# (fix conflicts and run "git commit")
# Unmerged paths:
# (use "git add <file>..." to mark resolution)
# both modified: src/app.js
# Open the file and look for conflict markers
cat src/app.js
# <<<<<<< HEAD
# function getUserData() {
# return userData.profile;
# }
# =======
# function getUserData() {
# return userData.profileInfo;
# }
# >>>>>>> origin/main
# Resolve by choosing the correct version or combining both
echo 'function getUserData() {
return userData.profile;
}' > src/app.js
# Mark as resolved and commit
git add src/app.js
git commit -m "Resolve merge conflict in getUserData function"
Advanced Remote Operations
Working with Multiple Remotes
# Add multiple remotes (common in fork scenarios)
git remote add origin https://github.com/yourusername/project.git
git remote add upstream https://github.com/original/project.git
git remote add staging https://github.com/company/project-staging.git
# Push to different remotes
git push origin feature/new-auth # Your fork
git push staging feature/new-auth # Staging environment
git push upstream feature/new-auth # Original repo (if you have access)
# Fetch from specific remote
git fetch upstream
git fetch origin
# Track different branches from different remotes
git checkout -b feature/from-upstream upstream/experimental
Advanced Push and Pull Strategies
# Force push safely (won't overwrite others' work)
git push --force-with-lease origin feature-branch
# Push all branches
git push origin --all
# Push tags
git push origin --tags
git push origin v1.2.0
# Pull with rebase to avoid merge commits
git pull --rebase origin main
# Fetch all remotes
git fetch --all
# Prune deleted remote branches
git fetch --prune origin
git remote prune origin
Team Workflows and Best Practices
Pull Request Workflow
# 1. Create feature branch
git checkout -b feature/payment-integration
# 2. Make commits with good messages
git commit -m "Add Stripe payment integration
- Configure Stripe SDK
- Add payment form component
- Implement payment processing logic
- Add error handling for failed payments"
# 3. Push and create PR
git push origin feature/payment-integration
# Create PR on GitHub/GitLab
# 4. Address review feedback
git add modified-files
git commit -m "Address PR feedback: improve error messages"
git push origin feature/payment-integration
# 5. After approval and merge, clean up
git checkout main
git pull origin main
git branch -d feature/payment-integration
5. Oops! How to Undo Mistakes
Everyone makes mistakes. Git provides powerful tools to fix them safely, but you need to know which tool to use when.
Core Undo Commands
Command | Description | When to Use |
---|---|---|
git log | Shows commit history with hashes, authors, dates, messages. | Understanding what happened |
git reset [file] | Unstages file but keeps changes in working directory. | Unstaging accidentally added files |
git reset --hard [commit] | Discards all changes and resets to specific commit. | DANGEROUS: Only for local branches |
git revert [commit] | Creates new commit that undoes a previous commit. | Safe way to undo on shared branches |
git stash | Temporarily saves unstaged changes. | Quick context switching |
Real-World Undo Scenarios
Scenario 1: “I Added the Wrong Files!”
# You accidentally staged sensitive files
echo "password=123456" > .env
echo "# My app" > README.md
git add .
git status
# Changes to be committed:
# new file: .env
# new file: README.md
# Remove .env from staging but keep README.md
git reset .env
# Or remove everything from staging
git reset
# Add .env to .gitignore to prevent future accidents
echo ".env" >> .gitignore
git add .gitignore README.md
git commit -m "Add README and gitignore"
Scenario 2: “My Last Commit Message is Wrong!”
# You committed with a typo
git commit -m "Fix authtentication bug"
# Fix the commit message (only if not pushed yet!)
git commit --amend -m "Fix authentication bug"
# Or add files you forgot to include
echo "console.log('debug');" > debug.js
git add debug.js
git commit --amend --no-edit # Keep same message
Scenario 3: “I Need to Completely Undo My Last Commit!”
# If you haven't pushed yet:
# Option 1: Keep changes but undo commit
git reset --soft HEAD~1
# Your files still have the changes, but commit is gone
# Option 2: Completely remove changes and commit
git reset --hard HEAD~1
# ⚠️ WARNING: This deletes your work!
# If you already pushed:
# Use revert to create a new commit that undoes the previous one
git revert HEAD
git push origin main
Scenario 4: “I Want to Undo Multiple Commits!”
# View recent commits
git log --oneline -5
# a1b2c3d (HEAD -> main) Broken feature attempt
# d4e5f6g Add incomplete user auth
# g7h8i9j Good commit we want to keep
# j0k1l2m Another good commit
# m3n4o5p Initial commit
# Go back 2 commits (to g7h8i9j)
git reset --hard g7h8i9j
# If already pushed, use multiple reverts instead
git revert a1b2c3d
git revert d4e5f6g
git push origin main
Scenario 5: “I Deleted Important Changes by Accident!”
# Use reflog to find lost commits
git reflog
# a1b2c3d HEAD@{0}: reset: moving to HEAD~2
# d4e5f6g HEAD@{1}: commit: Important feature I lost
# g7h8i9j HEAD@{2}: commit: Previous commit
# Recover the lost commit
git checkout d4e5f6g
# You're in detached HEAD state, create a branch
git checkout -b recover-lost-work
# Or directly reset to the lost commit
git reset --hard d4e5f6g
Advanced Undo Techniques
Interactive Rebase for History Cleanup
# Clean up last 3 commits
git rebase -i HEAD~3
# In the editor:
# pick a1b2c3d First commit
# edit d4e5f6g Second commit - need to modify this
# squash g7h8i9j Third commit - merge into second
# Git will stop at the 'edit' commit
# Make your changes
git add modified-file.js
git commit --amend -m "Improved second commit message"
git rebase --continue
Selective File Restoration
# Restore a file from a specific commit
git checkout a1b2c3d -- src/important-file.js
# Restore file from staging area (undo git add)
git checkout -- src/file.js
# Restore all files from a commit
git checkout a1b2c3d .
Advanced Stashing
# Stash with a message
git stash save "WIP: working on user authentication"
# Stash only staged changes
git stash --staged
# Stash including untracked files
git stash -u
# List all stashes
git stash list
# stash@{0}: WIP: working on user authentication
# stash@{1}: On main: quick fix
# Apply specific stash
git stash apply stash@{1}
# Pop stash (apply and remove)
git stash pop
# Drop a stash
git stash drop stash@{1}
When to Use Each Undo Method
Use git reset
when:
- Changes are local (not pushed)
- You want to modify recent commits
- You need to unstage files
Use git revert
when:
- Changes are already pushed
- Working on shared branches
- You want to keep history intact
Use git rebase
when:
- Cleaning up local feature branch
- Combining multiple commits
- Changing commit order
Use git reflog
when:
- You’ve lost commits
- Need to recover from mistakes
- Want to see all recent HEAD movements
6. Advanced Git Techniques
Take your Git skills to the next level with these powerful techniques used by experienced developers.
Git Hooks: Automating Your Workflow
Git hooks are scripts that run automatically at certain points in the Git workflow.
Pre-commit Hook Example
# Create pre-commit hook to run tests
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/sh
# Run tests before every commit
echo "Running tests before commit..."
npm test
if [ $? -ne 0 ]; then
echo "Tests failed! Commit aborted."
exit 1
fi
echo "All tests passed! Proceeding with commit."
EOF
chmod +x .git/hooks/pre-commit
Commit-msg Hook for Enforcing Message Format
# Enforce commit message format
cat > .git/hooks/commit-msg << 'EOF'
#!/bin/sh
# Enforce commit message format: "type: description"
commit_regex='^(feat|fix|docs|style|refactor|test|chore): .{10,}'
if ! grep -qE "$commit_regex" "$1"; then
echo "Invalid commit message format!"
echo "Format: type: description (at least 10 chars)"
echo "Types: feat, fix, docs, style, refactor, test, chore"
exit 1
fi
EOF
chmod +x .git/hooks/commit-msg
Git Aliases: Supercharge Your Productivity
# Essential aliases
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.cm commit
git config --global alias.cp cherry-pick
# Advanced aliases
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual '!gitk'
git config --global alias.tree 'log --graph --pretty=oneline --abbrev-commit'
# Complex aliases
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
# Now you can use:
git st # instead of git status
git co main # instead of git checkout main
git lg # beautiful log output
Submodules: Managing Dependencies
# Add a submodule
git submodule add https://github.com/user/library.git libs/library
# This creates:
# - .gitmodules file
# - libs/library directory with the external repo
# Clone a repo with submodules
git clone --recursive https://github.com/user/main-project.git
# Or if you already cloned:
git submodule init
git submodule update
# Update submodules to latest version
git submodule update --remote
# Work inside a submodule
cd libs/library
git checkout main
git pull
cd ../..
git add libs/library
git commit -m "Update library submodule"
Worktrees: Multiple Branches Simultaneously
# List existing worktrees
git worktree list
# Create worktree for different branch
git worktree add ../project-hotfix hotfix/critical-bug
# Now you have:
# ~/project/ (main branch)
# ~/project-hotfix/ (hotfix branch)
# Work in the hotfix directory
cd ../project-hotfix
# Make fixes, commit, etc.
# Remove worktree when done
git worktree remove ../project-hotfix
Git Subtrees: Alternative to Submodules
# Add external project as subtree
git subtree add --prefix=libs/external-lib \
https://github.com/user/external-lib.git main --squash
# Pull updates from external project
git subtree pull --prefix=libs/external-lib \
https://github.com/user/external-lib.git main --squash
# Push changes back to external project
git subtree push --prefix=libs/external-lib \
https://github.com/user/external-lib.git feature-branch
7. Lesser-known Git Commands
Here are powerful, lesser-known Git commands that can give you more control over your repository.
1. git bisect
: The Automatic Bug Hunter
This command performs an automatic binary search on your commit history to find the exact commit that introduced a bug.
Real-World Example: Finding a Performance Regression
# You know the app was fast at v2.1.0 but is slow now
git bisect start
# Mark current state as bad (has the bug)
git bisect bad
# Mark a known good state
git bisect good v2.1.0
# Git checks out a commit in the middle
# Test your application (run performance tests, etc.)
# If the commit is good:
git bisect good
# If the commit is bad:
git bisect bad
# Keep testing until Git finds the exact commit
# Git will output: "a1b2c3d is the first bad commit"
# When done, reset to original state
git bisect reset
# You can even automate the testing:
git bisect run npm test # Runs npm test for each commit
2. git reflog
: Your Safety Net
The reflog is a record of every place the HEAD of your branches has been - your ultimate recovery tool.
Real-World Recovery Scenarios
# Scenario: You accidentally deleted a branch
git branch -D important-feature # Oops!
# Find the lost branch in reflog
git reflog
# a1b2c3d HEAD@{0}: checkout: moving from important-feature to main
# d4e5f6g HEAD@{1}: commit: Complete important feature
# g7h8i9j HEAD@{2}: commit: Add feature skeleton
# Recover the branch
git checkout -b important-feature-recovered d4e5f6g
# Scenario: Botched interactive rebase
git reflog
# Find the state before the rebase
git reset --hard HEAD@{5}
3. git worktree
: Multiple Branches Simultaneously
Work on multiple branches at the same time in different directories.
Real-World Example: Review and Development
# You're working on a feature but need to review a PR
git worktree add ../project-pr-review pr-branch-name
# Directory structure:
# ~/project/ (your feature work)
# ~/project-pr-review/ (PR review)
# You can now:
# - Test the PR in one terminal
# - Continue feature development in another
# - Compare approaches side by side
# Cleanup when done
git worktree remove ../project-pr-review
4. git shortlog
: Perfect for Release Notes
# Generate contributor summary
git shortlog -s -n
# 25 Alice Johnson
# 18 Bob Smith
# 12 Charlie Brown
# 8 Diana Prince
# Generate release notes grouped by author
git shortlog v1.2.0..HEAD
# Alice Johnson (3):
# Add user authentication system
# Fix memory leak in image processing
# Update API documentation
#
# Bob Smith (2):
# Implement dark mode theme
# Add mobile responsive design
# Generate changelog for specific date range
git shortlog --since="2024-01-01" --until="2024-12-31"
5. git blame -C
: Find the True Origin of Code
Enhanced blame that tracks code movement and copying.
Real-World Example: Tracking Refactored Code
# Regular blame shows who last touched each line
git blame src/auth.js
# Enhanced blame tracks moved/copied code
git blame -C src/auth.js
# Shows original author even if code was moved from another file
# Even more thorough detection
git blame -C -C -C src/auth.js
# Detects code copied from any commit in any file
# Useful for understanding the true history of complex refactoring
6. git log
Power User Techniques
# Beautiful graph visualization
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'
# Find commits that added or removed specific text
git log -S "function calculateTotal" --source --all
# Show commits that modified a specific function
git log -L :functionName:src/app.js
# Find merge commits
git log --merges --oneline
# Show commits by specific author in date range
git log --author="Alice" --since="2024-01-01" --until="2024-12-31"
# Show only commits that affect specific files
git log --oneline -- src/auth.js src/login.js
# Show commit stats
git log --stat --oneline -5
7. git clean
: Safely Remove Untracked Files
# See what would be deleted (dry run)
git clean -n
# Remove untracked files
git clean -f
# Remove untracked files and directories
git clean -fd
# Remove ignored files too (be careful!)
git clean -fx
# Interactive mode - choose what to delete
git clean -i
8. git show
: Inspect Commits in Detail
# Show last commit with changes
git show
# Show specific commit
git show a1b2c3d
# Show only files changed in commit
git show --name-only a1b2c3d
# Show commit stats
git show --stat a1b2c3d
# Show specific file from specific commit
git show a1b2c3d:src/app.js
8. Git Best Practices & Workflows
Master these workflows and practices used by successful development teams.
Commit Message Conventions
Conventional Commits Format:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Examples:
git commit -m "feat(auth): add OAuth2 login integration
- Add Google OAuth2 provider
- Implement JWT token validation
- Add user session management
Closes #123"
git commit -m "fix(api): resolve memory leak in file upload
The file upload endpoint wasn't properly closing file streams,
causing memory usage to grow over time.
Fixes #456"
git commit -m "docs: update installation guide for Docker setup"
git commit -m "refactor(utils): extract validation logic into separate module"
Commit Types:
feat
: New featuresfix
: Bug fixesdocs
: Documentation changesstyle
: Code style changes (formatting, semicolons, etc.)refactor
: Code refactoring without functionality changestest
: Adding or updating testschore
: Build process or auxiliary tool changes
Branch Naming Conventions
# Feature branches
feature/user-authentication
feature/payment-integration
feature/dark-mode-theme
# Bug fix branches
fix/login-redirect-issue
fix/memory-leak-upload
hotfix/security-vulnerability
# Release branches
release/v2.1.0
release/2024-q1
# Experimental branches
experiment/new-ui-framework
spike/performance-optimization
Git Flow vs GitHub Flow
Git Flow (Complex Projects)
# Long-lived branches
main # Production code
develop # Integration branch
release/* # Preparing releases
hotfix/* # Critical fixes
feature/* # New features
# Workflow example
git checkout develop
git checkout -b feature/user-dashboard
# ... work on feature ...
git checkout develop
git merge feature/user-dashboard
git checkout -b release/v2.0.0
# ... prepare release ...
git checkout main
git merge release/v2.0.0
git tag v2.0.0
GitHub Flow (Simpler Projects)
# Only main branch + feature branches
main # Always deployable
feature/* # All work happens here
# Workflow
git checkout main
git pull origin main
git checkout -b feature/new-feature
# ... work and commit ...
git push origin feature/new-feature
# Create Pull Request
# After review: merge to main
# Deploy main branch
Code Review Best Practices
Before Creating a Pull Request:
# Self-review your changes
git diff main...feature/your-branch
# Run tests locally
npm test
# Check for large files or sensitive data
git log --stat
# Rebase to clean up history
git rebase -i HEAD~3
# Write descriptive PR description
Pull Request Template Example:
## Description
Brief description of changes and why they were made.
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] Unit tests pass
- [ ] Integration tests pass
- [ ] Manual testing completed
## Screenshots (if applicable)
[Add screenshots here]
## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Documentation updated
- [ ] No breaking changes (or marked as such)
Repository Organization
Effective .gitignore Strategy:
# Language specific
*.log
*.tmp
node_modules/
__pycache__/
*.pyc
target/
bin/
obj/
# IDE files
.vscode/
.idea/
*.swp
*.swo
*~
# OS files
.DS_Store
Thumbs.db
desktop.ini
# Environment and secrets
.env
.env.local
.env.production
config/secrets.yml
*.key
*.pem
# Build outputs
dist/
build/
*.min.js
*.min.css
# Dependencies
vendor/
composer.phar
Gemfile.lock
yarn.lock (or keep it, team decision)
Repository Structure Example:
project/
├── .github/
│ ├── workflows/ # GitHub Actions
│ ├── ISSUE_TEMPLATE/ # Issue templates
│ └── PULL_REQUEST_TEMPLATE.md
├── docs/ # Documentation
├── src/ # Source code
├── tests/ # Test files
├── scripts/ # Build/deployment scripts
├── .gitignore
├── README.md
└── CONTRIBUTING.md
9. Troubleshooting Common Issues
Real-world problems and their solutions that every developer encounters.
Issue 1: “I Can’t Push - Rejected Updates”
Problem:
git push origin main
# To https://github.com/user/repo.git
# ! [rejected] main -> main (fetch first)
# error: failed to push some refs
Solutions:
# Option 1: Pull and merge (creates merge commit)
git pull origin main
git push origin main
# Option 2: Pull with rebase (cleaner history)
git pull --rebase origin main
git push origin main
# Option 3: Force push (DANGEROUS - only if you're sure)
git push --force-with-lease origin main
Issue 2: “Merge Conflicts Everywhere!”
Problem:
git merge feature-branch
# Auto-merging src/app.js
# CONFLICT (content): Merge conflict in src/app.js
# CONFLICT (content): Merge conflict in src/utils.js
Step-by-step Resolution:
# 1. See which files have conflicts
git status
# 2. For each conflicted file, edit and resolve
# Look for these markers:
# <<<<<<< HEAD
# Your changes
# =======
# Their changes
# >>>>>>> feature-branch
# 3. After resolving all conflicts:
git add src/app.js src/utils.js
git commit -m "Resolve merge conflicts"
# Pro tip: Use a merge tool
git config --global merge.tool vimdiff # or 'code --wait'
git mergetool
Issue 3: “I Committed to Wrong Branch”
Problem:
# You're on main but should have been on feature branch
git branch
# * main
# feature/user-auth
echo "new feature" > feature.js
git add feature.js
git commit -m "Add new feature" # Oops! This should be on feature branch
Solutions:
# Option 1: Move commit to correct branch (if not pushed)
git checkout feature/user-auth
git cherry-pick main
git checkout main
git reset --hard HEAD~1
# Option 2: Create new branch from current state
git branch feature/new-feature
git reset --hard HEAD~1
# Option 3: If already pushed, revert on main and recreate on feature branch
git revert HEAD
git push origin main
git checkout -b feature/new-feature HEAD~1
Issue 4: “My Repository is Too Large”
Problem:
# Repository is slow to clone/push due to large files
du -sh .git
# 2.5GB .git
Solutions:
# Find large files in history
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sed -n 's/^blob //p' | sort --numeric-sort --key=2 | tail -10
# Use BFG Repo-Cleaner to remove large files from history
java -jar bfg.jar --strip-blobs-bigger-than 10M my-repo.git
cd my-repo.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
# Use Git LFS for large files going forward
git lfs install
git lfs track "*.zip"
git lfs track "*.mp4"
git add .gitattributes
Issue 5: “Accidentally Committed Secrets”
Problem:
# Committed API keys or passwords
git log --oneline
# a1b2c3d Add database config with passwords # Oops!
Immediate Action:
# If not pushed yet:
git reset --soft HEAD~1
# Remove secrets from files
# Add files to .gitignore
echo "config/database.yml" >> .gitignore
git add .
git commit -m "Add database config (secrets removed)"
# If already pushed:
# 1. Change all exposed secrets immediately
# 2. Use BFG Repo-Cleaner to remove from history
# 3. Force push (notify team first!)
Issue 6: “Detached HEAD State”
Problem:
git checkout a1b2c3d
# You are in 'detached HEAD' state...
Solutions:
# If you made changes you want to keep:
git checkout -b new-branch-name
# If you want to go back to a branch:
git checkout main
# If you made commits in detached state:
git branch temp-branch # Create branch from current state
git checkout main
git merge temp-branch # Or cherry-pick specific commits
Performance Optimization Tips
Speed up Git operations:
# Enable parallel processing
git config --global core.preloadindex true
git config --global core.fscache true
git config --global gc.auto 256
# Use shallow clones for large repositories
git clone --depth 1 https://github.com/large/repository.git
# Configure Git to use more memory
git config --global pack.windowMemory 100m
git config --global pack.packSizeLimit 100m
# Clean up repository regularly
git gc --aggressive --prune=now
10. Frequently Asked Questions (FAQ)
Repository Basics
Q: What is the .git
directory?
A: The .git
folder is Git’s database containing all repository metadata: commit history, branch information, remote URLs, hooks, and configuration. Never manually edit these files.
Q: Can I rename the default branch from ‘master’ to ‘main’?
A: Yes!
# For new repositories
git config --global init.defaultBranch main
# For existing repository
git branch -m master main
git push -u origin main
git push origin --delete master
Workflow Questions
Q: What’s the difference between git fetch
and git pull
?
A:git fetch
: Downloads remote changes but doesn’t merge them. Safe for inspecting changes.
git pull
: Downloads AND merges remote changes. Equivalent to fetch
+ merge
.
# Safer workflow
git fetch origin
git diff main origin/main # Review changes
git merge origin/main # Merge when ready
# vs.
git pull origin main # Downloads and merges immediately
Q: Should I use merge
or rebase
?
A: Depends on your workflow:
- Merge: Preserves exact history, creates merge commits. Good for shared branches.
- Rebase: Creates linear history, no merge commits. Good for feature branches before sharing.
# Merge preserves context
git merge feature-branch # Clear that feature was developed separately
# Rebase creates linear history
git rebase main # Looks like feature was developed on latest main
Q: How do I undo my last commit?
A: Depends on whether you’ve pushed:
# Not pushed yet - keep changes
git reset --soft HEAD~1
# Not pushed yet - discard changes
git reset --hard HEAD~1
# Already pushed - create reverting commit
git revert HEAD
git push origin main
Collaboration Issues
Q: How do I resolve merge conflicts?
A: Step by step process:
git status
to see conflicted files- Edit files to resolve conflicts (remove
<<<<<<<
,=======
,>>>>>>>
markers) git add
resolved filesgit commit
to complete merge
# Example conflict resolution
cat src/app.js
# <<<<<<< HEAD
# const API_URL = 'https://api.prod.com';
# =======
# const API_URL = 'https://api.dev.com';
# >>>>>>> feature-branch
# Resolve by choosing or combining
echo "const API_URL = process.env.API_URL;" > src/app.js
git add src/app.js
git commit -m "Resolve API URL conflict using environment variable"
Q: My teammate force-pushed and broke everything. How do I recover?
A:
# Find the commit before force-push in reflog
git reflog
git reset --hard HEAD@{5} # Or whatever commit was good
# Or restore from your last known good state
git reset --hard origin/main@{yesterday}
# Prevention: Use --force-with-lease instead of --force
git push --force-with-lease origin feature-branch
Advanced Scenarios
Q: How do I split a large commit into smaller ones?
A:
# Reset the commit but keep changes
git reset --soft HEAD~1
# Use interactive add to stage parts
git add -p file.js # Stage hunks selectively
git commit -m "First part of the change"
git add remaining-files
git commit -m "Second part of the change"
Q: How do I change the author of a commit?
A:
# For the last commit
git commit --amend --author="New Author <[email protected]>"
# For older commits, use interactive rebase
git rebase -i HEAD~3
# Change 'pick' to 'edit' for commits to modify
# When Git stops at each commit:
git commit --amend --author="New Author <[email protected]>"
git rebase --continue
Q: Can I recover a deleted branch?
A: Yes, using reflog:
# Find the branch in reflog
git reflog | grep branch-name
# Or check all branch movements
git reflog --all --grep="branch-name"
# Recreate branch from found commit
git checkout -b recovered-branch a1b2c3d
Q: How do I ignore files that are already tracked?
A:
# Remove from tracking but keep local file
git rm --cached file-to-ignore.txt
echo "file-to-ignore.txt" >> .gitignore
git commit -m "Stop tracking file-to-ignore.txt"
# For directories
git rm -r --cached directory-to-ignore/
echo "directory-to-ignore/" >> .gitignore
git commit -m "Stop tracking directory-to-ignore"
Repository Management
Q: How do I completely remove a file from Git history?
A: Use BFG Repo-Cleaner (safer than git filter-branch
):
# Download BFG Repo-Cleaner
# Remove file from all history
java -jar bfg.jar --delete-files passwords.txt my-repo.git
# Clean up
cd my-repo.git
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git push --force-with-lease
Q: My repository is huge. How do I reduce its size?
A:
# Find large objects
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sed -n 's/^blob //p' | sort --numeric-sort --key=2
# Use shallow clone
git clone --depth 1 <url>
# Clean up aggressively
git gc --aggressive --prune=now
# Use Git LFS for large files
git lfs install
git lfs track "*.zip"
11. References
Official Documentation
-
Pro Git Book - The definitive Git reference
-
Git Reference Manual - Complete command reference
-
Git Tutorials - Official Git tutorials
Interactive Learning
-
Learn Git Branching - Visual, interactive Git tutorial
-
GitHub Git Handbook - GitHub’s Git guide
-
Atlassian Git Tutorials - Comprehensive Git workflow guides
Advanced Resources
-
A successful Git branching model - Git Flow methodology
-
Conventional Commits - Commit message specification
-
GitHub Flow - Simplified Git workflow
Tools and Extensions
-
GitKraken - Visual Git client
-
Sourcetree - Free Git GUI
-
Git LFS - Large File Storage extension
-
BFG Repo-Cleaner - Repository cleaning tool
Command Line Enhancements
-
Oh My Zsh Git Plugin - Git aliases and shortcuts
-
Git Prompt - Show Git status in terminal prompt
-
Tig - Text-based Git repository browser
Quick Reference Card
Essential Daily Commands
git status # Check repository state
git add . # Stage all changes
git commit -m "msg" # Commit with message
git push origin main # Push to remote
git pull origin main # Pull from remote
Branch Management
git branch # List branches
git checkout -b new # Create and switch branch
git merge branch # Merge branch into current
git branch -d branch # Delete merged branch
Undo Operations
git reset file # Unstage file
git checkout -- file # Discard file changes
git reset --soft HEAD~1 # Undo last commit, keep changes
git revert HEAD # Create commit that undoes last commit
Information Commands
git log --oneline # Compact commit history
git diff # Show unstaged changes
git diff --staged # Show staged changes
git blame file # Show who changed each line
This guide covers Git from beginner to advanced levels. Bookmark it, practice the examples, and refer back as you encounter new situations. Happy coding!