Módulo 10: Rebase Interactivo

02. Fundamentos de Rebase Interactivo

Descripción de la cápsula

En esta cápsula dominarás los fundamentos de git rebase -i, el comando más poderoso para history rewriting. Aprenderás cómo funciona el editor interactivo, qué comandos están disponibles, y cuándo usar cada uno. Este es el foundation para todas las técnicas avanzadas de rebase.

Entender rebase interactivo es esencial para mantener historial profesional.


¿Qué es git rebase -i?

Definición:

git rebase -i (interactive)
> Opens editor showing commits
> You choose action for each commit
> Git rewrites history accordingly

Basic syntax:

git rebase -i HEAD~N       # Last N commits
git rebase -i <commit>     # Since specific commit
git rebase -i main         # Since main branch

El editor interactivo

Iniciar rebase:

git rebase -i HEAD~5

Git opens editor:

pick a1b2c3d feat: Add user authentication
pick d4e5f6g WIP: Work in progress
pick g7h8i9j feat: Add dashboard
pick j1k2l3m Fix typo
pick m4n5o6p Add tests

# Rebase abc123..m4n5o6p onto abc123 (5 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.

Comandos disponibles

1. pick (p) - Use commit as-is

pick a1b2c3d feat: Add feature

Default action
Keeps commit unchanged

2. reword (r) - Edit message

reword a1b2c3d feat: Add feature

Git pauses to edit commit message
Commit content unchanged
Good for fixing typos in messages

Example:

# Before
reword a1b2c3d feat: Add featur  # Typo

# Git opens editor
# Change to: "feat: Add feature"
# Save and exit

3. edit (e) - Stop to amend

edit a1b2c3d feat: Add feature

Git pauses at this commit
You can modify files
Amend the commit
Continue rebase

Example:

# Git pauses
# Make changes
git add .
git commit --amend
git rebase --continue

4. squash (s) - Combine with previous

pick a1b2c3d feat: Add feature
squash d4e5f6g WIP: Work in progress

Combines d4e5f6g into a1b2c3d
Keeps both commit messages
Git opens editor to edit combined message

5. fixup (f) - Combine, discard message

pick a1b2c3d feat: Add feature
fixup d4e5f6g Fix typo

Combines d4e5f6g into a1b2c3d
Keeps only a1b2c3d message
Discards d4e5f6g message
No editor opens (automatic)

6. drop (d) - Remove commit

drop a1b2c3d Debug commit

Removes commit from history
As if it never existed

7. exec (x) - Run command

pick a1b2c3d feat: Add feature
exec npm test

Runs command after commit
Useful for testing each commit
Rebase stops if command fails

Workflow completo

Step 1: Iniciar rebase

# Work on feature branch
git log --oneline -5
# a1b2c3d feat: Add feature
# d4e5f6g WIP
# g7h8i9j Fix typo
# j1k2l3m WIP again
# m4n5o6p Actually works

# Start interactive rebase
git rebase -i HEAD~5

Step 2: Editor abre

pick a1b2c3d feat: Add feature
pick d4e5f6g WIP
pick g7h8i9j Fix typo
pick j1k2l3m WIP again
pick m4n5o6p Actually works

Step 3: Choose actions

pick a1b2c3d feat: Add feature
squash d4e5f6g WIP
squash g7h8i9j Fix typo
squash j1k2l3m WIP again
squash m4n5o6p Actually works

Step 4: Save and exit

Git processes your instructions


Step 5: Edit combined message

# This is a combination of 5 commits.
# This is the 1st commit message:

feat: Add feature

# This is the commit message #2:

WIP

# This is the commit message #3:

Fix typo

# ... etc

# Edit to:

feat: Add complete feature implementation

Implements user feature with validation and tests.

Step 6: Complete

# Git completes rebase
git log --oneline -1
# abc123 feat: Add complete feature implementation

# 5 commits → 1 clean commit

Casos de uso comunes

Caso 1: Limpiar WIP commits

Before:

git log --oneline -4
a1b2c3d feat: Add auth
d4e5f6g WIP
g7h8i9j WIP
j1k2l3m Fixed it

Rebase:

git rebase -i HEAD~4

# In editor:
pick a1b2c3d feat: Add auth
fixup d4e5f6g WIP
fixup g7h8i9j WIP
fixup j1k2l3m Fixed it

After:

git log --oneline -1
abc123 feat: Add auth

Caso 2: Fix commit message

Before:

git log --oneline -1
a1b2c3d feat: Add featur  # Typo

Rebase:

git rebase -i HEAD~1

# In editor:
reword a1b2c3d feat: Add featur

# Git opens editor:
# Change to: "feat: Add feature"

After:

git log --oneline -1
abc123 feat: Add feature

Caso 3: Remove debug commit

Before:

git log --oneline -3
a1b2c3d feat: Add feature
d4e5f6g Debug logging
g7h8i9j feat: Add tests

Rebase:

git rebase -i HEAD~3

# In editor:
pick a1b2c3d feat: Add feature
drop d4e5f6g Debug logging
pick g7h8i9j feat: Add tests

After:

git log --oneline -2
abc123 feat: Add feature
def456 feat: Add tests

Rebase interactivo con conflicts

Si hay conflicts:

git rebase -i HEAD~5

# ... make changes ...

# Git stops:
Auto-merging file.js
CONFLICT (content): Merge conflict in file.js
error: could not apply abc123... feat: Add feature

# Resolve conflict
# Edit file.js

# Stage resolution
git add file.js

# Continue rebase
git rebase --continue

# If more conflicts, repeat
# If too complex, abort:
git rebase --abort

Best practices

Keep sessions small:

✅ Rebase 3-10 commits
⚠️ Rebase 10-20 commits (careful)
❌ Rebase 50+ commits (too risky)

Test after rebase:

git rebase -i HEAD~5
# ... complete rebase ...

# Test!
npm test
npm run lint

# If broken:
git reflog
git reset --hard HEAD@{1}

Use descriptive commit messages:

✅ feat: Add user authentication
❌ WIP
❌ Fix
❌ Update

Troubleshooting

Problem 1: Accidentally deleted line

Symptom:

You removed a line in editor
Commit disappeared

Solution:

# Abort rebase
git rebase --abort

# Try again, be careful
git rebase -i HEAD~5

Problem 2: Editor confused

Symptom:

Editor shows weird format
Can't save properly

Solution:

# Set better editor
git config --global core.editor "code --wait"

# Or vim
git config --global core.editor "vim"

# Or nano
git config --global core.editor "nano"

Problem 3: Rebase stuck

Symptom:

git status shows "rebase in progress"
Not sure what to do

Solution:

# Check status
git status

# Continue (if resolved conflicts)
git rebase --continue

# Skip current commit (careful!)
git rebase --skip

# Abort (start over)
git rebase --abort

Problem 4: Lost work

Symptom:

Rebase went wrong
Commits disappeared

Solution:

# Use reflog to find old state
git reflog

# Output:
# abc123 HEAD@{0}: rebase -i (finish)
# def456 HEAD@{1}: rebase -i (start)

# Reset to before rebase
git reset --hard HEAD@{1}

# Your work is back!

Exercises

Exercise 1: Basic squash

Ver solución
# Setup
mkdir rebase-demo
cd rebase-demo
git init

# Create commits
echo "v1" > file.txt && git add . && git commit -m "feat: v1"
echo "v2" >> file.txt && git add . && git commit -m "WIP"
echo "v3" >> file.txt && git add . && git commit -m "WIP again"

git log --oneline
# 3 commits

# Rebase
git rebase -i HEAD~3

# In editor, change to:
# pick <commit1> feat: v1
# squash <commit2> WIP
# squash <commit3> WIP again

# Save, edit message to: "feat: Complete v1 implementation"

# Result
git log --oneline
# 1 commit: "feat: Complete v1 implementation"

Exercise 2: Reword message

Ver solución
# Setup
git init
echo "content" > file.txt
git add .
git commit -m "feat: Add featur"  # Typo

# Fix typo
git rebase -i HEAD~1

# In editor:
# reword <commit> feat: Add featur

# Git opens editor, change to:
# "feat: Add feature"

# Verify
git log --oneline
# Message fixed

Exercise 3: Drop debug commit

Ver solución
# Setup
git init
echo "v1" > file.txt && git add . && git commit -m "feat: Add feature"
echo "console.log('debug')" > debug.js && git add . && git commit -m "Debug"
echo "v2" >> file.txt && git add . && git commit -m "feat: Add tests"

git log --oneline
# 3 commits

# Remove debug commit
git rebase -i HEAD~3

# In editor:
# pick <commit1> feat: Add feature
# drop <commit2> Debug
# pick <commit3> feat: Add tests

# Result
git log --oneline
# 2 commits, debug gone

Resumen

En esta cápsula aprendiste:

git rebase -i básico
Editor interactivo y su formato
7 comandos principales (pick, reword, edit, squash, fixup, drop, exec)
Workflow completo paso a paso
Casos de uso comunes
Troubleshooting problemas básicos

Siguiente cápsula: Squash y Fixup en detalle


Recursos adicionales

  1. git rebase -i - Official docs
  2. Rewriting History - Pro Git book
  3. Interactive Rebase - Atlassian guide

Tiempo estimado: 20 minutos

Siguiente: 03. Squash y Fixup