Debugging is a necessary aspect of making software, but you don’t have to spend hours looking for bugs, figuring out code modifications, and fixing mistakes. There are some of the Git commands that can cut down on the time you spend debugging by a lot and make you a better developer.
Here are 10 important Git commands that will change the way you debug and save you a lot of time, based on the most recent best practices from the developer community.
10 Git Commands
1. git bisect
– Binary Search for Bug Hunting
Git bisect helps find the commit that introduced a bug using a binary search algorithm, making it one of the most powerful debugging tools in your arsenal.
# Start the bisect process
git bisect start
# Mark the current commit as bad (contains the bug)
git bisect bad
# Mark a known good commit (before the bug existed)
git bisect good <commit-hash>
# Git will checkout a commit in the middle - test it
# Then mark it as good or bad
git bisect good # or git bisect bad
# Repeat until Git finds the problematic commit
git bisect reset # End the bisect session
Pro Tip: You can fully automate git bisect if you have a script that will exit 0 if the project is good or non-0 if the project is bad:
git bisect run ./test-script.sh
2. git blame
– Track Code Authorship and Changes
Git blame helps identify who made a specific change in the code and when, making it perfect for understanding problematic code sections.
# Basic blame command
git blame filename.py
# Show blame for specific lines
git blame -L 10,20 filename.py
# Ignore whitespace changes
git blame -w filename.py
# Follow code through file renames
git blame -C filename.py
Real-world usage: When you find a buggy function, use git blame
to see who wrote it and when, then check the commit message for context.
3. git reflog
– Your Safety Net for Recovery
Git reflog shows a history of all Git operations, including deleted commits and branch switches. It’s your ultimate recovery tool.
# Show recent Git operations
git reflog
# Show reflog for a specific branch
git reflog show branch-name
# Recover a "lost" commit
git checkout <commit-hash-from-reflog>
git checkout -b recovery-branch
Emergency scenario: Accidentally deleted a branch or reset to the wrong commit? git reflog
will show you exactly where you were and help you recover.
4. git log -S
– Search Through Code History
The pickaxe option (-S
) searches for commits that added or removed specific code, perfect for tracking when a function or variable was introduced or removed.
# Find commits that added/removed a specific string
git log -S "function_name"
# Search with regex
git log -G "regex_pattern"
# Show the actual changes
git log -S "function_name" -p
# Search in specific file types
git log -S "debug" -- "*.py"
Use case: Tracking when a particular API call was removed or when a specific bug was introduced.
5. git show
– Deep Dive into Commits
Examine specific commits in detail to understand exactly what changed and why.
# Show changes in a specific commit
git show <commit-hash>
# Show only the files that changed
git show --name-only <commit-hash>
# Show changes for a specific file in a commit
git show <commit-hash>:filename.py
# Show the commit message and stats
git show --stat <commit-hash>
Debugging workflow: Use this after git bisect
identifies the problematic commit to understand exactly what broke.
6. git diff
– Compare and Contrast
Master different diff variations to spot problems quickly.
# Compare working directory with staging area
git diff
# Compare staging area with last commit
git diff --cached
# Compare two commits
git diff commit1..commit2
# Compare specific files between commits
git diff HEAD~1 HEAD filename.py
# Word-level diff for better readability
git diff --word-diff
Pro tip: Use git diff --name-only
to quickly see which files changed without the detailed diff output.
7. git cherry-pick
– Surgical Code Application
Apply specific commits from one branch to another without merging entire branches.
# Apply a specific commit to current branch
git cherry-pick <commit-hash>
# Cherry-pick multiple commits
git cherry-pick commit1 commit2 commit3
# Cherry-pick a range of commits
git cherry-pick start-commit..end-commit
# Cherry-pick without committing (for review)
git cherry-pick --no-commit <commit-hash>
Debugging scenario: Found a fix in another branch but don’t want to merge everything? Cherry-pick just the fix.
8. git stash
– Temporary Storage for Context Switching
Save your work temporarily without committing, essential for debugging different scenarios.
# Stash current changes
git stash
# Stash with a descriptive message
git stash push -m "debugging user login issue"
# List all stashes
git stash list
# Apply the latest stash
git stash pop
# Apply a specific stash
git stash apply stash@{2}
# Show stash contents
git stash show -p stash@{0}
Workflow: Stash your current debugging attempts, switch to a clean state to test something else, then return to your stashed work.
9. git reset
– Undo Operations with Precision
Reset allows you to undo commits and changes at different levels.
# Soft reset - keep changes in staging area
git reset --soft HEAD~1
# Mixed reset (default) - keep changes in working directory
git reset HEAD~1
# Hard reset - discard all changes (dangerous!)
git reset --hard HEAD~1
# Reset specific files
git reset HEAD filename.py
Safety first: Always use git reflog
to check your history before hard resets, and consider creating a backup branch.
10. git grep
– Search Across Your Entire Codebase
Find text patterns across your entire Git repository, including historical versions.
# Search for text in current working tree
git grep "TODO"
# Search in a specific commit
git grep "function_name" <commit-hash>
# Case-insensitive search
git grep -i "error"
# Show line numbers
git grep -n "console.log"
# Search for whole words only
git grep -w "debug"
# Search and show context
git grep -C 3 "error_handler"
Power move: Combine with other commands like git grep "deprecated" $(git rev-list --all)
to search through your entire repository history.
Debugging Workflow: Putting It All Together
Here’s a real-world debugging workflow using these commands:
- Identify the problem area with
git grep
or by examining error logs - Use
git blame
to see who last modified the problematic code - Check recent changes with
git log -p
for the file or function - If the bug was recently introduced, use
git bisect
to find the exact commit - Examine the problematic commit with
git show
- Test potential fixes using
git stash
to save attempts - Apply fixes from other branches with
git cherry-pick
- Use
git reflog
if you need to recover from any mistakes
Advanced Tips for Power Users
- Set up aliases for commonly used debugging commands:
git config --global alias.find-merge 'log --oneline --merges' git config --global alias.who 'blame -w -C -C -C'
- Use Git hooks to run tests automatically and catch bugs early
- Combine commands with shell pipes for powerful searches:
git log --oneline | grep -i "fix\|bug" | head -10
Conclusion
With these 10 Git commands, debugging goes from being a frustrating waste of time to a quick and organized procedure. If you use git log to look at the commit history, git bisect to find the commits that might have caused the bug, and git blame to look at the lines where the problem happens, you’ll spend less time looking for bugs and more time developing great code.
Keep in mind that the best way to debug using Git is to practice. You will quickly be able to solve problems in minutes instead of hours if you start using these instructions every day. You and your peers will be grateful for the Git debugging abilities you learn now.
The developer community is always coming up with new ways to use these commands, so keep trying out different combinations of them to find the ones that work best for your individual debugging situations.