CodeWithAbdessamad

Rewriting History

Rewriting History

Rewriting history is a powerful but nuanced capability in Git that lets you refine your commit history after the fact. While it might seem risky at first glance, it’s an essential skill for maintaining clean, professional workflows—especially when you realize a commit was flawed, want to fix a merge, or need to streamline your branch history. In this section, we’ll dive into two critical tools for history manipulation: git rebase and git amend. Both are designed to help you maintain a smooth, linear history without introducing messy merge commits.


Git Rebase

git rebase is Git’s most powerful tool for rewriting history by applying your commits on top of a different branch’s history. Instead of creating a merge commit (as git merge does), rebase walks through your commits and re-applies them sequentially on top of the target branch’s latest commit. This results in a cleaner, linear history that’s easier to understand and maintain.

Why Rebase Matters

Rebasing solves common pain points:

  • Avoids “merge commits” in your history (which clutter the timeline)
  • Simplifies debugging by making each commit’s changes independent
  • Helps with collaboration by ensuring your branch aligns with the latest shared state

⚠️ Critical Note: Rebasing changes your history. If you’ve pushed commits to a shared branch, rebasing after pushing can cause conflicts with others. Always rebase locally before pushing!

How to Rebase: Step-by-Step

Let’s walk through a practical example. Start with a simple branch:

<code class="language-bash">git init
<p>echo "Initial file" > file.txt</p>
<p>git add file.txt</p>
<p>git commit -m "Initial commit"</p>
<p>git checkout -b feature</p>
<p>echo "Feature change" >> file.txt</p>
<p>git add file.txt</p>
<p>git commit -m "Add feature change"</code>

Now we’ll rebase this branch onto the main branch’s history:

<code class="language-bash"># Switch to main branch (assumes it exists)
<p>git checkout main</p>
<h1>Create a new commit on main for demonstration</h1>
<p>echo "Main update" > file.txt</p>
<p>git add file.txt</p>
<p>git commit -m "Main update"</p>

<h1>Switch back to feature branch and rebase</h1>
<p>git checkout feature</p>
<p>git rebase main</code>

What happened?

  • Git replayed your feature commits on top of main’s latest commit (Main update)
  • The history becomes linear: Initial commit → Main update → Feature change
  • No merge commit appears in the history

Real-World Example: Fixing a Broken Workflow

Imagine you accidentally committed a sensitive file to your feature branch. You want to fix it without creating a merge commit:

<code class="language-bash">git checkout feature
<h1>Remove the sensitive file (e.g., .env)</h1>
<p>rm .env</p>
<p>git add .</p>
<p>git commit -m "Fix: Remove sensitive file"  # This is the new commit</p>
<p>git rebase main  # Reapply on top of main</code>

This approach keeps your history clean while avoiding the need for a merge commit.

When to Avoid Rebase

  • Never rebase a shared branch that others have pushed to (it breaks collaboration)
  • Avoid rebase if you have large files (e.g., binary assets) that might cause conflicts
  • Don’t rebase after pushing to a shared branch (use git revert instead)

💡 Pro Tip: For collaborative workflows, use git rebase -i (interactive rebase) to edit commit messages or squash multiple commits into one.


Git Amend

git amend is a lightweight tool for fixing the last commit without creating a new commit. It’s perfect for small corrections—like fixing a typo in your commit message or adding a small change to a commit you just made.

Why Amend Matters

Amending is ideal when:

  • You realize a commit message was incorrect
  • You need to add a small change to the last commit (e.g., a missing file)
  • You want to avoid cluttering your history with multiple small commits

How to Amend: Step-by-Step

Let’s fix a common scenario: you just committed a file but forgot to add it to the staging area.

<code class="language-bash"># Initial commit (staging the file)
<p>git add file.txt</p>
<p>git commit -m "Initial commit"</p>
<h1>Oops! Forgot to add file.txt? Let's fix it.</h1>
<p>git add file.txt  # Re-add the file</p>
<p>git commit --amend  # Amend the last commit</code>

What happened?

  • Git rewrites the last commit to include file.txt
  • The commit message remains unchanged (unless you specify it)

Real-World Example: Correcting a Commit Message

Suppose your commit message was too vague:

<code class="language-bash">git commit -m "Add feature change"  # Original commit
<p>git commit --amend -m "Add feature change: Fix typo in user input"  # Amend</code>

This keeps your history clean while improving clarity.

When to Use Amend

  • Only for the last commit (amend won’t help with earlier commits)
  • Use sparingly—overuse can make history hard to track
  • Never amend after pushing to a shared branch (use git revert instead)

Best Practice: Always amend before pushing. This ensures your shared branch has a clean, well-documented history.


Summary

Rewriting history with git rebase and git amend is a foundational skill for professional Git workflows. git rebase gives you control over your entire branch history by replaying commits on top of a target branch—ideal for creating clean, linear histories. git amend lets you fix the last commit without creating new history, perfect for small corrections. Remember: always rebase locally before pushing, and never amend after pushing to shared branches. These tools empower you to maintain precision and clarity in your version history—without sacrificing collaboration or workflow. 🛠️