# Fix Git Interactive Rebase Dropped Commit During Squash

You run an interactive rebase to squash several commits together:

bash
git rebase -i HEAD~5

You mark commits as squash or fixup, save and close the editor, but when the rebase completes, one of your commits is completely gone -- not squashed, not merged, just missing. git log shows no trace of it.

Understanding How Interactive Rebase Works

Interactive rebase replays commits onto a new base. The rebase todo list determines what happens to each commit:

bash
pick abc1234 Add user authentication
squash def5678 Fix login bug
pick 901abcd Add dashboard page
fixup 234def5 Fix typo in dashboard
pick 567890a Update dependencies

Commits marked squash are merged into the preceding pick. Commits marked fixup are merged without their message. Commits marked drop or deleted from the list are removed entirely.

The Common Mistake: Wrong Base Commit

If you use the wrong base, you may miss commits:

```bash # WRONG: HEAD~5 does not include your important commit git rebase -i HEAD~5

# CORRECT: Check the full log first git log --oneline -10 # Then choose the right base git rebase -i <commit-hash> ```

Recovering the Dropped Commit

The commit is NOT lost -- it is still in the reflog:

bash
git reflog

Look for your commit:

bash
abc1234 HEAD@{0}: rebase (finish): returning to refs/heads/main
def5678 HEAD@{1}: rebase: Fix login bug
901abcd HEAD@{2}: rebase: Add dashboard page
234def5 HEAD@{3}: commit: Fix typo in dashboard

The dropped commit still has its original hash. Recover it:

```bash # Cherry-pick the dropped commit git cherry-pick def5678

# Or create a branch pointing to it git branch recovered def5678 ```

The Squash Message Confusion

When you squash multiple commits, Git opens an editor to combine commit messages. If you accidentally delete a commit's message from the combined message file, the commit's changes are still included but the description is lost. This is different from the commit being dropped.

To verify the changes are present:

bash
git show HEAD
git diff HEAD~2..HEAD

Safe Interactive Rebase Workflow

Step 1: Create a Backup Branch

bash
git branch backup-before-rebase

If anything goes wrong, you can always return:

bash
git reset --hard backup-before-rebase

Step 2: Review the Todo List Carefully

When the editor opens with the rebase todo list:

bash
pick abc1234 Add user authentication
pick def5678 Fix login bug
pick 901abcd Add dashboard page
pick 234def5 Fix typo in dashboard
pick 567890a Update dependencies

Change to:

bash
pick abc1234 Add user authentication
fixup def5678 Fix login bug
pick 901abcd Add dashboard page
fixup 234def5 Fix typo in dashboard
pick 567890a Update dependencies

Verify every commit you want to keep has either pick, squash, or fixup. Any line removed or marked drop will be lost.

Step 3: Use --rebase-merges for Complex Histories

If your branch has merge commits, use --rebase-merges to preserve them:

bash
git rebase -i --rebase-merges HEAD~5

Without this flag, merge commits are flattened, which can lose commits that were only reachable through the merge.

Preventing Future Drops

Use autosquash

With autosquash, Git automatically reorders the todo list for you:

bash
git commit --fixup abc1234
git commit --fixup 901abcd
git rebase -i --autosquash HEAD~5

Git places fixup commits right after their target commits in the todo list, reducing manual editing errors.

Configure Your Editor for Safety

If using Vim as your Git editor, add a safeguard:

bash
git config --global core.editor "vim -c 'set nomodified'"

This prevents accidental modification of the todo file. Review carefully before saving.

Using Git Range-Diff

After the rebase, verify no commits were lost:

bash
git range-diff backup-before-rebase...HEAD

This shows a side-by-side comparison of the commit ranges, highlighting any commits that were dropped, modified, or added.