Un stacked PR (PR encadenado) divide un cambio grande en varios pull requests pequeños que dependen unos de otros: el PR 2 parte de la rama del PR 1, el PR 3 parte del PR 2, y así sucesivamente. GitHub no tiene un concepto nativo de 'pila': se simula apuntando cada PR a la rama base correcta y manteniendo las ramas sincronizadas con rebase encadenado, algo que desde Git 2.38 se puede automatizar con un solo comando.
Qué es un stacked PR (y qué no es en GitHub)
Un stacked PR no es una función de GitHub: es un patrón de trabajo construido sobre ramas y git rebase. En lugar de abrir una única rama feature/checkout-v2 con 40 archivos modificados y esperar a que alguien encuentre una tarde libre para revisarla entera, la divides en piezas lógicas — por ejemplo 'modelo de datos', 'endpoint API', 'lógica de frontend' y 'tests e2e' — cada una en su propia rama y su propio PR. Cada PR apunta como base a la rama del PR anterior, no a main. El resultado es que un revisor puede aprobar y fusionar la pieza 1 mientras la pieza 4 todavía se está escribiendo, y cada PR se lee en minutos en vez de en horas. GitHub muestra esto de forma correcta en la comparación de diff cuando defines bien la rama base al abrir el PR, pero no ofrece ninguna vista agregada de 'pila' ni gestiona el reordenamiento por ti: eso lo haces tú, a mano o con una herramienta externa.
El error que nadie explica: el squash merge rompe la pila
Aquí está el fallo que casi ningún tutorial menciona y que explica por qué la mayoría de equipos que prueban stacked PRs los abandonan a la primera. Si tu repositorio tiene 'Squash and merge' como estrategia por defecto — la opción más habitual porque deja el historial de main limpio — al fusionar el PR 1, GitHub reescribe todos sus commits en uno solo con un hash nuevo. La rama del PR 2, que seguía apuntando a los commits originales del PR 1, pasa a tener una historia divergente respecto a main: los cambios 'ya fusionados' reaparecen como pendientes en el diff. El resultado visual es aterrador — un PR de 3 archivos que de repente muestra 40 archivos modificados — y es la razón número uno por la que a un equipo le 'explota' la pila y jura no volver a intentarlo. La solución no es evitar los stacked PRs: es no usar squash merge en ramas con hijos pendientes, o rebasear la rama hija sobre main justo después de cada fusión, antes de que nadie más toque nada.
El mecanismo que lo hace viable sin pagar una herramienta externa
El motivo por el que los stacked PRs eran una pesadilla hasta hace poco y ahora son manejables tiene nombre: git rebase --update-refs, incorporado en Git 2.38 (septiembre de 2022). Antes de esa versión, si rebasabas la rama base de la pila — por ejemplo tras incorporar cambios pedidos en la revisión del PR 1 — tenías que rebasear manualmente cada rama hija una por una, resolviendo los mismos conflictos varias veces si tocaban archivos compartidos. Con --update-refs, Git detecta qué otras ramas locales apuntan a commits dentro del rango que estás rebasando y mueve sus punteros junto con el tuyo en la misma operación. Es exactamente el mecanismo interno que usan herramientas de pago como Graphite o extensiones como git-spice: no hacen magia nueva, orquestan el mismo comando con una interfaz más cómoda encima. En la práctica el patrón se reduce a tres comandos: git checkout -b feature/paso-2 feature/paso-1 para arrancar cada rama hija desde la anterior (nunca desde main), gh pr create --base feature/paso-1 para fijar el eslabón correcto al abrir el PR, y git rebase main --update-refs seguido de git push --force-with-lease en cada rama afectada cuando la base se mueve.
Guía práctica paso a paso con gh CLI
Preparar y abrir la pila
- Divide el cambio en piezas que puedan revisarse y fusionarse de forma independiente (idealmente cada una compila y pasa tests por sí sola)
- Crea la primera rama desde main y abre el PR 1 normal con gh pr create
- Crea la segunda rama desde la primera (no desde main) y ábrela con gh pr create --base <rama-1>
- Repite el patrón para cada pieza siguiente, siempre apuntando a la rama inmediatamente anterior
- Etiqueta cada PR en el título con su posición ('1/4', '2/4'...) para que el revisor entienda el orden sin depender de ninguna herramienta
- Desactiva 'Squash and merge' como única opción en el repo, o pacta con el equipo usar 'Rebase and merge' para las ramas intermedias
Cuando cambia la base: el momento en que la mayoría se rinde
El punto de fricción real no es crear la pila, es mantenerla viva mientras llegan comentarios de revisión. Si un revisor pide un cambio en el PR 1 y ya existen PR 2 y PR 3 construidos encima, ese cambio tiene que propagarse hacia abajo antes de que nadie más revise nada, o los PR 3 y 4 estarán revisando código que ya no existe. El flujo correcto es: aplicas el cambio en la rama del PR 1, haces commit, y ejecutas git rebase feature/paso-1 --update-refs desde cualquier rama de la pila para que Git reordene toda la cadena en una sola pasada. Después haces push --force-with-lease en cada rama que se haya movido — GitHub actualiza los PR afectados automáticamente porque sigue el puntero de la rama, no un PR fijo. Esto solo funciona bien si el equipo tiene la disciplina de rebasear la pila el mismo día que llega el comentario: dejar una pila de 4 PRs reposando una semana sin actualizar es la forma más rápida de acabar resolviendo el mismo conflicto tres veces.
ritmo de revisión con máxima detección de defectos según el estudio de Cisco sobre code review (Cohen, 'Best Kept Secrets of Peer Code Review', SmartBear, 2006); por encima de ese volumen la efectividad para encontrar fallos cae con fuerza
- PR único de 1.200 líneas y 35 archivos: revisión pospuesta días, comentarios superficiales, un solo aprobador dispuesto a 'tragárselo entero'
- 4 PRs encadenados de 150-300 líneas cada uno: revisión el mismo día, comentarios específicos por pieza, posibilidad de fusionar lo ya aprobado sin esperar al resto
¿Necesitas Graphite, git-spice o similar, o te basta con git a secas?
Aquí conviene ser sincero: para un equipo de 2-4 desarrolladores que abre stacked PRs de forma ocasional, pagar por Graphite u otra herramienta dedicada suele ser gastar dinero en resolver un problema que git rebase --update-refs y unos alias de shell ya resuelven gratis. Estas herramientas aportan valor real en visualización de la pila, reordenación de PRs con un comando y sincronización automática tras cada merge — algo que se nota cuando la organización tiene decenas de desarrolladores abriendo pilas en paralelo cada día — pero para el volumen de trabajo de una PYME tecnológica española ese coste operativo y la curva de aprendizaje de una CLI adicional rara vez se amortizan. En Blurtek hemos preferido en más de un proyecto quedarnos con git plano y una convención de nombres de rama clara antes que introducir una dependencia más en el flujo de un equipo pequeño; la herramienta externa empieza a justificarse cuando el equipo crece o cuando la cadencia de PRs encadenados pasa de ser ocasional a ser el patrón por defecto de cada sprint.
Cuándo no merece la pena montar una pila de PRs
Los stacked PRs no son la respuesta a todo, y recomendarlos sin matices sería venderte una solución que no necesitas. Si tu equipo es de una o dos personas, si el cambio es realmente pequeño y no se puede dividir en piezas con sentido propio, o si estáis en fase de prototipo donde el código va a cambiar de forma radical en días, el coste de mantener ramas encadenadas sincronizadas supera con creces el beneficio de la revisión incremental. La señal de que sí compensa es otra: cuando ves que un PR lleva más de dos días abierto sin revisión porque 'es muy grande para mirarlo ahora', o cuando el mismo archivo de configuración se toca en tres features distintas que compiten por la misma rama base. Fuera de esos casos, un PR normal y una revisión rápida son más baratos que aprender a gestionar una pila.
¿Vuestro equipo arrastra PRs de días sin revisar o pilas de ramas que se rompen en cada rebase? En Blurtek ayudamos a equipos de desarrollo pequeños a definir un flujo de Git y de revisión de código que encaje con su tamaño real, sin imponer herramientas que no vais a amortizar.
Solicitar diagnóstico