Modifying History

Back

Loading concept...

🎬 Git Time Travel: Rewriting Your Story

Imagine you’re writing a book. You’ve written several chapters, but you realize:

  • Chapter 3 should come after Chapter 5
  • Some chapters have spelling mistakes
  • You want to combine two short chapters into one

In regular writing, you’d erase and rewrite. In Git, you can do the same thing with your code history!

This is called Modifying History — and it’s like having a magical eraser that lets you clean up your story before showing it to the world.


🌳 What is Rebasing?

The Simple Analogy

Think of your Git history like a family tree:

Grandpa (main branch)
    ↓
   Dad
    ↓
 You (feature branch)

Rebasing is like saying: “I want to pretend I was born from a different parent.”

The Problem Rebasing Solves

You started working on a feature. Meanwhile, your teammate added new code to main.

Before rebase:

main:    A → B → C (teammate's new work)
              ↓
feature:      D → E (your work)

Your work is based on old code (B). You want it based on new code ©.

After rebase:

main:    A → B → C
                  ↓
feature:          D' → E' (your work, now based on C!)

How to Rebase

# On your feature branch
git checkout feature

# Rebase onto main
git rebase main

What happens:

  1. Git “picks up” your commits (D, E)
  2. Moves to latest main ©
  3. “Replays” your commits on top

🎯 Key Point: Your commits get new IDs (D becomes D’, E becomes E’). They’re the same changes, but with new “birth certificates.”


🎮 Interactive Rebasing: The Ultimate Control

What is Interactive Rebasing?

Regular rebasing just moves commits. Interactive rebasing lets you:

  • ✏️ Edit commit messages
  • 🗑️ Delete commits
  • 📦 Combine commits together
  • 🔀 Reorder commits

It’s like having a video editor for your Git history!

How to Use It

# Edit the last 3 commits
git rebase -i HEAD~3

This opens a text editor showing:

pick abc1234 Add login button
pick def5678 Fix typo in login
pick ghi9012 Style login button

The Magic Words

Command What It Does Example
pick Keep this commit Use it as-is
reword Change message Fix a typo in commit text
edit Stop and edit Change the actual code
squash Combine with previous Merge two commits
fixup Combine, drop message Merge silently
drop Delete commit Remove entirely

Example: Combining Commits

Your history looks messy:

pick abc1234 Add login
pick def5678 oops forgot semicolon
pick ghi9012 fixed another typo

Change to:

pick abc1234 Add login
fixup def5678 oops forgot semicolon
fixup ghi9012 fixed another typo

Result: One clean commit: “Add login” ✨


⚔️ Rebase vs Merge: The Great Debate

The Birthday Party Analogy

Merge is like taking a group photo:

“Here’s everyone who came to the party, exactly as it happened.”

Rebase is like arranging people in a neat line:

“Let me organize this to look cleaner.”

Visual Comparison

Merge creates a “merge commit”:

    A → B → C
         ↘   ↘
    D → E → F → M (merge commit)

Rebase creates a straight line:

A → B → C → D' → E' → F'

When to Use Each

Situation Use This Why
Public/shared branch Merge Others have your commits
Private/local branch Rebase Clean history, no one affected
Want to preserve history Merge Shows exactly what happened
Want clean history Rebase Linear, easy to read

The Golden Rule

⚠️ Never rebase commits that others have already pulled!

Rebasing changes commit IDs. If someone has your old commits, they’ll have conflicts with your new ones.


🎯 Rebase Onto: Surgical Precision

The Problem

You started a feature from the wrong branch:

main:     A → B
               ↓
develop:       C → D
                    ↓
feature:            E → F (oops, wanted this from main!)

The Solution

git rebase --onto lets you move commits to a different base:

git rebase --onto main develop feature

Translation: “Take feature’s commits that came after develop, and put them on main instead.”

Result:

main:     A → B
               ↓
               E' → F' (now based on main!)

develop:  A → B → C → D

Breaking Down the Command

git rebase --onto <new-base> <old-base> <branch>
Part Meaning
<new-base> Where you want commits to go
<old-base> Where commits currently start from
<branch> The branch with commits to move

🍒 Cherry-Picking: One Commit at a Time

What is Cherry-Picking?

Imagine a bowl of cherries (commits). You don’t want all of them — just a few specific ones.

Cherry-picking = grabbing one specific commit and putting it somewhere else.

When to Use It

  • Bug fix exists on one branch, needed on another
  • Accidentally committed to wrong branch
  • Want specific changes without merging everything

How to Cherry-Pick

# Find the commit you want
git log --oneline
# Output: abc1234 Fix critical bug

# Switch to target branch
git checkout main

# Pick that specific commit
git cherry-pick abc1234

Result: The fix is now on main too!

Cherry-Picking Multiple Commits

# Pick several commits
git cherry-pick abc1234 def5678

# Pick a range of commits
git cherry-pick abc1234..ghi9012

Handling Conflicts

If there’s a conflict:

# Fix the conflict in your editor
git add .

# Continue the cherry-pick
git cherry-pick --continue

# Or abort if you change your mind
git cherry-pick --abort

🛡️ Rewriting History Safely

The Danger Zone

Rewriting history can cause serious problems if done wrong:

  • Teammates can’t pull your changes
  • Commits can be lost forever
  • Confusion and frustration

Safety Rules

  1. Only rewrite unpushed commits

    # Check what's not pushed yet
    git log origin/main..HEAD
    
  2. Create a backup branch first

    git branch backup-before-rebase
    
  3. Use --force-with-lease instead of --force

    # Safe force push (fails if someone else pushed)
    git push --force-with-lease
    
    # NOT this (dangerous, overwrites everything)
    # git push --force
    

The Reflog: Your Safety Net

Did something go wrong? Git remembers everything:

# See all recent actions
git reflog

# Output:
# abc1234 HEAD@{0}: rebase finished
# def5678 HEAD@{1}: rebase: Add login
# ghi9012 HEAD@{2}: rebase started
# xyz7890 HEAD@{3}: commit: Original commit (before rebase!)

# Go back to before the rebase
git reset --hard xyz7890

💡 Tip: The reflog keeps entries for 90 days. You can almost always undo mistakes!

Safe History Rewriting Checklist

graph TD A["Want to rewrite history?"] --> B{Are commits pushed?} B -->|No| C["✅ Safe to rewrite"] B -->|Yes| D{Do others have them?} D -->|No| E["⚠️ Use force-with-lease"] D -->|Yes| F[❌ Don't rewrite! Use revert instead]

🎯 Quick Reference

Task Command
Simple rebase git rebase main
Interactive rebase git rebase -i HEAD~3
Rebase onto git rebase --onto new old branch
Cherry-pick git cherry-pick <commit>
Safe force push git push --force-with-lease
Undo with reflog git reflog then git reset --hard <ref>
Abort any rebase git rebase --abort

🎬 Putting It All Together

Think of these tools as your history editing studio:

  • Rebase = Move your work to a new foundation
  • Interactive Rebase = Edit, combine, reorder commits
  • Rebase Onto = Surgically transplant commits
  • Cherry-Pick = Copy specific commits anywhere
  • Reflog = Your undo button for everything

The Journey

graph TD A["Messy History"] --> B["Rebase: Clean foundation"] B --> C["Interactive Rebase: Polish commits"] C --> D["Cherry-Pick: Move specific fixes"] D --> E["Clean, Professional History!"]

Remember: Your local history is your draft. Clean it up before sharing!

🚀 You’ve got this! These tools might seem scary at first, but they’re just ways to tell a cleaner story. Start with simple rebases, then try interactive mode. Soon you’ll be editing history like a pro!

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.