Real-World Pain Points When Using Git in the Terminal
Have you ever typed git log and just stared at a wall of text scrolling past with no idea what you’re looking for? Or maybe you’re mid-bug-fix and want to stage just a few specific lines in a file — not the whole thing — but git add -p throws up a messy diff and walks you through hunks one at a time with zero context?
I once spent nearly 20 minutes just tracking down which commit had deleted a function I needed. Ran git log --oneline, saw 200 commits, didn’t know where to start. Then git show abc1234, then git show def5678… bouncing back and forth the whole time.
And don’t get me started on that one time I had merge conflicts across 5 files simultaneously — opening each file, hunting for every <<<<<<< marker, fixing things by hand, then finally committing. It ate up an entire morning.
Why git log and git diff Are Hard to Use in Practice
Git is built around Unix philosophy — pipe the output of one command into another. Great for scripting, but when you’re doing real work, you need to interact: scroll up and down, jump between commits, see the diff right there without typing another command.
GUI tools like GitKraken or SourceTree solve this problem. But they require leaving the terminal — and for developers working on remote servers over SSH, that’s simply not a viable option.
I’ve been using tig for about 8 months now, and I’ve barely touched GitKraken since.
What Is tig?
tig (“git” spelled backwards) is a text-mode interface for Git — a TUI that runs entirely in the terminal yet feels interactive like a GUI. It lets you:
- Browse commit history as a scrollable, searchable tree
- View the diff for any commit right on the same screen
- Stage or unstage individual lines with a single keystroke
- View working tree status and staged files in a clear visual layout
- Navigate merge conflicts with distinct color coding
No leaving the terminal. No extra tools to install beyond tig itself.
Installing tig
tig is available in most popular package managers:
# Ubuntu / Debian
sudo apt install tig
# macOS (Homebrew)
brew install tig
# Fedora / RHEL / CentOS
sudo dnf install tig
# Arch Linux
sudo pacman -S tig
Verify the installation:
tig --version
# tig version 2.5.8
Browsing Commit History — Interactive, Not Just Read-Only
Run tig inside any git repo:
tig
The screen splits in two: the top half shows a commit list (like git log --graph but scrollable), and the bottom half shows the diff for the currently selected commit. Use the arrow keys or j/k to move around. The diff updates instantly — no extra commands needed.
Basic tig Keyboard Shortcuts
j / k— Move up/down through the commit listEnter— Open the detailed diff view for a commitq— Go back to the previous view / quit/— Search (type a keyword then press Enter)n / N— Jump to next / previous search resultR— Refresh the listh— Open the full help screen
View the log for a specific file:
tig -- src/main.py
Compare two branches:
tig main..feature/my-branch
Staging Line by Line — Forget git add -p
This is the feature I use the most. When you’ve changed a lot of things in one file but only want to commit part of it — say, a bug fix at the top while the bottom is unfinished experimental code — you need to stage at the hunk or line level.
Open the Status View:
tig status
Or press s while inside tig. The Status View shows:
- Changes to be committed — files/lines already staged
- Changed but not staged — not yet staged
- Untracked files — new files not yet tracked
Staging a Hunk (a Block of Code)
- Navigate to the file you want to stage under “Changed but not staged”
- Press
Enterto view that file’s diff - Move to the hunk you want to stage
- Press
uto stage it, or!to discard it
Staging a Single Line
- In the diff view, navigate to the specific line you want to stage
- Press
1to stage only that line
The key difference from git add -p: you can see the full file context when deciding what to stage, instead of being walked through hunks blindly one by one. Once you’re done staging, commit as usual:
git commit -m "fix: validate email before submitting form"
Resolving Merge Conflicts Right Inside tig
Merge conflicts across multiple files at once is one of the easiest situations to make mistakes in — especially when you’re in a hurry and not sure which version of the code is “correct.” Accidentally deleting a colleague’s code, or keeping the wrong old version of your own — either way, you’re in for more debugging time.
When you have merge conflicts, run tig status. Conflicted files will appear with the UU marker (both modified). Press Enter on a file to view its diff with clear color highlighting:
<<<<<<< HEAD
const timeout = 5000;
=======
const timeout = 3000;
>>>>>>> feature/faster-timeout
tig clearly highlights your side (HEAD) versus the incoming branch — much easier to read than raw text in vim or nano. Open the file in your editor, make your edits, then return to tig status: the file moves from UU to M. Press u to stage it right in tig, then:
git commit # Git auto-fills the merge commit message
Other Useful Views in tig
Blame View — See Who Wrote Each Line
tig blame src/auth.py
Shows each line of code alongside the commit that added or last modified it. When you’re debugging and asking “who changed this line, which commit, what was the message?” — this is the fastest view for that. Press Enter on any commit to see its full diff right away.
Tree View — Browse Files at a Specific Commit
In the log view, press t to browse the directory tree for the currently selected commit. You can navigate into any file and view its contents at that point in time — really handy when you need to recover code that was deleted.
Refs View — See All Branches and Tags
tig refs
Lists all local branches, remote branches, and tags. Press Enter on any branch to instantly view its log — no git checkout needed.
Integrating tig Into Your Daily Workflow
I’ve added aliases to ~/.bashrc to make things faster:
# Add to ~/.bashrc or ~/.zshrc
alias tl='tig'
alias ts='tig status'
alias tb='tig blame'
My actual workflow with tig:
- Finish editing code, type
tsto review all changes - Stage the important hunks, skip experimental code that isn’t ready
- Commit the staged portion with a clear message
- After a merge or rebase with conflicts, run
tsagain to navigate and fix each file - Need to find an old commit, run
tlthen/to search by message or filename
tig doesn’t fully replace git commands — git commit, git push, and git rebase still need to be typed directly. But it does replace the parts that require the most back-and-forth interaction: git log, git diff, git add -p, and git blame.
If you work on remote servers over SSH, or simply don’t want to memorize a dozen flags for git log, give tig a shot — 30 seconds to install, 10 minutes to get comfortable with the shortcuts, and you’ll save a noticeable amount of time going forward.
