Viewing History and Differences

Viewing History and Differences

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 staged
  • M (second column) = Modified but not staged
  • A = New file staged (Added)
  • D = Deleted and staged
  • D = Deleted but not staged
  • ?? = Untracked file
  • MM = 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 gitk in 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.