Viewing History and Changes
Introduction
One of Git's greatest strengths is its ability to show you exactly what changed, when it changed, and who changed it. Whether you're debugging a problem, understanding a codebase, or reviewing your own work, Git provides powerful tools to explore your project's history and current state.
This lesson covers three essential commands that will become part of your daily Git workflow: git status for seeing what's happening right now, git diff for examining specific changes, and git log for exploring your project's history.
git status: Your Current Snapshot
The git status command is your dashboard—it shows the current state of your working directory and staging area. You'll use this command constantly, often multiple times per minute while working.
Basic Usage
git status
This command displays:
- Which branch you're currently on
- Whether your branch is ahead of or behind a remote branch
- Files that are staged for commit
- Files that are modified but not staged
- Files that are untracked
Reading Status Output
Here's a typical status output:
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: index.html
new file: about.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes)
modified: styles.css
deleted: old-page.html
Untracked files:
(use "git add <file>..." to include in what will be committed)
script.js
images/
Interpreting this output:
Staged Changes - index.html (modified) and about.html (new) are ready to be committed. These will be included in your next commit.
Unstaged Changes - styles.css was modified and old-page.html was deleted, but these changes aren't staged yet. They won't be included in the next commit unless you stage them first.
Untracked Files - script.js and the images/ directory are brand new and Git isn't tracking them yet.
Short Status Format
For a more compact view, use the short format:
git status -s
Output looks like:
M index.html
A about.html
M styles.css
D old-page.html
?? script.js
?? images/
Reading the short format:
The first column shows the staging area status, the second column shows the working directory status.
M(first column) = Modified and stagedM(second column) = Modified but not stagedA= New file staged (Added)D= Deleted and stagedD= Deleted but not staged??= Untracked fileMM= Modified, staged, then modified again
When to Use git status
Run git status frequently:
- Before staging files (to see what changed)
- Before committing (to verify what will be committed)
- After pulling from remote (to see if there are conflicts)
- When you're confused about the repository state
- Before switching branches
Think of git status as checking your mirrors before changing lanes—it's a quick safety check that prevents mistakes.
git diff: Examining Changes
While git status tells you which files changed, git diff shows you what changed inside those files. It displays line-by-line differences between different states of your files.
Viewing Unstaged Changes
To see changes in your working directory that aren't staged yet:
git diff
This compares your working directory to the staging area (or to the last commit if nothing is staged).
Example output:
diff --git a/index.html b/index.html
index 3b18e51..d8a6d8f 100644
--- a/index.html
+++ b/index.html
@@ -3,7 +3,8 @@
<head>
<title>My Website</title>
</head>
<body>
- <h1>Welcome</h1>
+ <h1>Welcome to My Website</h1>
+ <p>This is the homepage.</p>
</body>
</html>
Understanding the output:
- Lines starting with
-(shown in red in the terminal) were removed - Lines starting with
+(shown in green) were added - Lines without
+or-provide context @@ -3,7 +3,8 @@shows line numbers (this change is around line 3)
Viewing Staged Changes
To see what you've staged for the next commit:
git diff --staged
Or equivalently:
git diff --cached
This shows the difference between the staging area and the last commit—exactly what will go into your next commit.
Comparing Specific Files
To see changes in just one file:
git diff index.html
Or for staged changes in one file:
git diff --staged index.html
This is useful when you've changed many files but want to focus on one.
Comparing Commits
You can compare any two commits to see what changed between them.
Compare current state to a specific commit:
git diff a3f2e9b
Compare two specific commits:
git diff a3f2e9b d8c5f1a
Compare current state to three commits ago:
git diff HEAD~3
Comparing Branches
See differences between branches:
git diff main feature-branch
This shows what's different in feature-branch compared to main.
Useful git diff Options
Word-level differences (instead of line-level):
git diff --word-diff
Useful for prose or documentation where you changed a few words in a long paragraph.
Statistics only (summary of changes):
git diff --stat
Shows which files changed and how many lines were added/removed:
index.html | 3 ++-
styles.css | 12 ++++++++++++
script.js | 5 -----
3 files changed, 14 insertions(+), 6 deletions(-)
Ignore whitespace changes:
git diff -w
Helpful when reformatting code but wanting to see actual logic changes.
Practical git diff Workflow
Before staging:
git diff # Review all changes
git diff filename.js # Focus on one file
git add filename.js # Stage it
Before committing:
git diff --staged # Review what will be committed
git commit -m "message" # Commit if satisfied
This workflow helps catch mistakes before they're permanently recorded in history.
git log: Exploring Project History
The git log command displays your commit history. It's like reading your project's diary, showing you the story of how your code evolved.
Basic Log Output
git log
Shows commits in reverse chronological order (newest first):
commit d8c5f1a3b2e4f8c9d0e1a2b3c4d5e6f7g8h9i0j1
Author: Your Name <your.email@example.com>
Date: Mon Oct 20 14:30:22 2025 -0400
Add contact form validation
commit a3f2e9b7c5d8f1a2b4c6d9e3f7a0b2c4d6e8f0a1
Author: Your Name <your.email@example.com>
Date: Mon Oct 20 10:15:33 2025 -0400
Create contact page structure
commit 7f1a3d5b8e2c9f4a6d0b3e7c1a5d8b2e4f6a9c3
Author: Your Name <your.email@example.com>
Date: Sun Oct 19 16:45:18 2025 -0400
Initial commit with homepage
Each entry shows:
- The commit hash (unique identifier)
- The author's name and email
- The date and time
- The commit message
Condensed Log Formats
One line per commit:
git log --oneline
Output:
d8c5f1a Add contact form validation
a3f2e9b Create contact page structure
7f1a3d5 Initial commit with homepage
Much easier to scan when you have many commits. The short hash (first 7 characters) is shown instead of the full hash.
Last N commits:
git log -5
Shows only the five most recent commits. Useful for quick checks.
Commits since a date:
git log --since="2 weeks ago"
git log --since="2025-10-01"
Commits by author:
git log --author="Your Name"
Helpful when multiple people work on a project.
Visual Log Formats
Show branch structure:
git log --graph --oneline
Output:
* d8c5f1a Add contact form validation
* a3f2e9b Create contact page structure
* 7f1a3d5 Merge branch 'feature-contact'
|\
| * 4b2e8f9 Add contact form
| * 9c3a6d1 Style contact page
|/
* 2e5b8c4 Initial commit
The graph shows branching and merging, making your project's evolution visual.
Show files changed in each commit:
git log --stat
Output includes:
commit d8c5f1a3b2e4f8c9d0e1a2b3c4d5e6f7g8h9i0j1
Author: Your Name <your.email@example.com>
Date: Mon Oct 20 14:30:22 2025 -0400
Add contact form validation
contact.html | 15 +++++++++++++++
script.js | 8 ++++++++
2 files changed, 23 insertions(+)
Shows which files were affected and how many lines changed.
Show actual changes (patches):
git log -p
This shows the full diff for each commit—exactly what changed in the code. Very detailed but powerful for understanding changes.
Limit patches to specific files:
git log -p filename.js
See the complete history of changes to one file.
Searching Commit History
Search commit messages:
git log --grep="bug fix"
Finds all commits with "bug fix" in the message.
Search code changes:
git log -S"function login"
Finds commits that added or removed the text "function login" from the code. Incredibly useful for tracking when specific code was introduced.
Search by file:
git log -- path/to/file.js
Shows all commits that modified a specific file.
Formatting Log Output
Git allows custom formatting for log output:
git log --pretty=format:"%h - %an, %ar : %s"
Output:
d8c5f1a - Your Name, 2 hours ago : Add contact form validation
a3f2e9b - Your Name, 6 hours ago : Create contact page structure
Common format placeholders:
%h= abbreviated commit hash%H= full commit hash%an= author name%ae= author email%ar= author date, relative (e.g., "2 hours ago")%ad= author date%s= commit message subject%b= commit message body
Viewing Specific Commits
Show details of one commit:
git show d8c5f1a
Displays the commit message and full diff for that commit.
Show just the message:
git show -s d8c5f1a
Show specific file from a commit:
git show d8c5f1a:path/to/file.js
Displays the contents of that file as it existed in that commit.
Following File History Through Renames
If a file was renamed, normal log might not show its full history:
git log --follow filename.js
The --follow flag tracks the file through renames, showing its complete history.
Practical Workflows
Daily Development Check
Start your day by checking what happened:
git log --oneline -10 # Last 10 commits
git status # Current state
git diff # Any uncommitted changes
Before Pushing Code
Review what you're about to share:
git log origin/main..HEAD # Commits you're about to push
git diff origin/main # All changes vs. remote
Investigating a Bug
Find when a bug was introduced:
git log -p -S"buggy code" # When was this code added?
git log --since="1 week ago" -- buggy-file.js # Recent changes to file
Understanding Someone's Changes
Review what a colleague did:
git log --author="Colleague Name" --since="1 week ago"
git show commit-hash # Details of specific commit
Preparing for Code Review
See what changed in your branch:
git log main..feature-branch --oneline
git diff main...feature-branch
Combining Commands Effectively
These commands work best together:
Workflow 1: Before Committing
git status # What will be committed?
git diff --staged # Review staged changes
git commit -m "message" # Commit if satisfied
Workflow 2: Understanding Changes
git log --oneline -10 # Recent commits
git show commit-hash # Details of interesting commit
git diff commit-hash~1 commit-hash # Compare with parent
Workflow 3: Tracking Down Issues
git log -p -- problematic-file.js # Full history of file
git blame problematic-file.js # Who changed each line?
git show commit-hash # Details of suspicious commit
Advanced Tips
Creating Aliases
Save typing by creating shortcuts in your Git config:
git config --global alias.lg "log --graph --oneline --all --decorate"
git config --global alias.st "status -s"
git config --global alias.last "log -1 HEAD"
Now you can type git lg instead of the long command.
Using External Tools
Many developers prefer graphical tools for viewing history:
- gitk: Built-in graphical log viewer (run
gitkin repository) - Git GUI clients: GitHub Desktop, GitKraken, SourceTree
- IDE integration: VS Code, IntelliJ, Visual Studio
These tools visualize branches, commits, and diffs more intuitively than the command line.
Performance with Large Repositories
For repositories with thousands of commits:
git log --oneline -n 50 # Limit number of commits
git log --since="1 month ago" # Limit time range
git log -- specific-file.js # Limit to one file
These limits make commands run faster in large projects.
Common Questions
How far back does history go?
Git stores your complete history from the first commit. Nothing is lost unless you explicitly delete it.
Can I see deleted files?
Yes! Use git log --diff-filter=D --summary to find deleted files, then use git show commit-hash:path/to/file to view their contents.
How do I find who changed a specific line?
Use git blame filename to see who last modified each line. We'll cover this in detail in a future lesson.
What if commit messages are unclear?
This highlights the importance of writing good commit messages. If messages are vague, you'll need to use git show or git diff to understand what actually changed.
How do I search for when a bug was introduced?
Use git log -S"suspicious code" to find when specific code appeared, or use git bisect (covered in a future lesson) to binary search through history.
Best Practices
Check status before and after operations - Always know where you are before making changes.
Review diffs before committing - Use git diff --staged to catch mistakes before they're permanent.
Write searchable commit messages - Use keywords that you'll remember when searching later.
Use oneline log for scanning - Save detailed inspection for commits that interest you.
Leverage aliases - Create shortcuts for commands you use frequently.
Combine with other tools - Don't rely solely on command line—graphical tools complement these commands well.
Summary
These three commands form the foundation of navigating your Git repository:
git status shows you where you are right now—which files changed, what's staged, and what's untracked.
git diff shows you exactly what changed—the specific lines added, removed, or modified.
git log shows you where you've been—your project's complete history and evolution.
Mastering these commands transforms Git from a mysterious black box into a transparent system where you always know what's happening and why. You can confidently make changes knowing you can always review them, understand them, and if necessary, undo them.
In the next lesson, we'll explore branches—Git's killer feature that lets you work on multiple versions of your project simultaneously. The history viewing skills you've learned here will be essential for understanding how branches work and merge together.