Stacked pull requests: cómo crear y revisar una pila en GitHub
Los pull requests apilados (stacked pull requests) dividen un cambio grande en capas pequeñas. Vemos el soporte nativo de GitHub y cómo revisar código en una pila.
Resumen. Los pull requests apilados (stacked pull requests) dividen un cambio grande en pull requests pequeños que se apoyan unos en otros. GitHub lanzó la función en vista previa pública el 30 de julio de 2026 y la puso en disponibilidad general el 6 de octubre de 2026. El 14 de octubre de 2026 leímos los anuncios de GitHub, su documentación y la guía de la extensión gh stack. A eso le sumamos lo que aprendimos al montar una pila a mano en nuestro propio repositorio, antes de que llegara el soporte nativo.
- Cada capa es un pull request distinto. El de abajo apunta a la rama troncal y cada uno de los demás, a la rama del que tiene debajo; todos muestran solo el diff de su propia capa.
- Las reglas de la rama troncal rigen en cada capa. Las aprobaciones obligatorias, las comprobaciones obligatorias y CODEOWNERS se aplican aunque el pull request no apunte directamente a
main. - El merge se hace de abajo arriba. El pull request que eliges entra junto con los de debajo en una sola operación; a los que quedan encima se les hace rebase automáticamente y pasan a apuntar a la rama troncal.
- Fíjate en qué commit se ejecutó cada comprobación. En la pila que montamos a mano, las comprobaciones en verde eran de un commit antiguo; después de un rebase, compara ese commit con la punta de la rama.
Qué es una pila y para qué sirve
Cuando abres una funcionalidad grande en un solo pull request, quien la revisa ve cientos de líneas de golpe. Los pull requests apilados (stacked pull requests) dividen ese mismo trabajo en una serie ordenada de pull requests pequeños. Esa serie se llama pila (stack), y cada pull request que contiene, capa (layer).
Según la definición de GitHub, una pila está formada por dos o más pull requests del mismo repositorio. El de abajo apunta a la rama troncal de la pila (trunk); suele ser main, aunque también puede ser una rama de versión. Cada pull request siguiente apunta a la rama del que tiene debajo. La rama a la que apunta un pull request es su base.

Cada pull request muestra solo el diff de su capa: la diferencia entre su rama y la de debajo. El orden sigue una regla: el código del que depende una capa está en la misma rama o en una más baja. Los tipos compartidos y el esquema de la base de datos van abajo; los endpoints de la API y la interfaz que los usan, arriba.
Esto tiene dos ventajas. Según la documentación de GitHub, un pull request pequeño se revisa antes y es menos probable que se lea por encima, que se quede desfasado o que acabe en conflicto. Además, si tu siguiente cambio depende de un trabajo que aún no tiene merge, no tienes que esperar: abres un pull request nuevo encima. Si el código lo escribe un agente de IA, el orden sale solo: una capa por tarea.
Encadenar ramas a mano no es nuevo; lo nuevo es que GitHub reconozca la cadena. La función entró en vista previa pública el 30 de julio de 2026 y pasó a disponibilidad general el 6 de octubre de 2026; según el anuncio, está en todos los planes de github.com.
Lo que hace la función lo contamos a partir de la propia documentación de GitHub, tal como la leímos el 14 de octubre de 2026. Nosotros hacemos diffox, una herramienta que revisa pull requests; antes de que llegara el soporte nativo, montamos una pila a mano en nuestro propio repositorio. Lo que aprendimos allí está más abajo, en una sección aparte.
Cómo crear una pila en GitHub
Para la línea de comandos está la extensión gh stack de GitHub CLI. Crea las ramas en el orden correcto, hace rebase y push, abre los pull requests y los enlaza como una pila. Una pila de tres capas se monta así:
gh extension install github/gh-stack
gh stack init auth-layer # primera rama, sobre la rama troncal
git add .
git commit -m "Capa de autenticación"
gh stack add api-endpoints # segunda rama, sobre la primera
git add .
git commit -m "Endpoints de la API"
gh stack add frontend # tercera rama
git add .
git commit -m "Interfaz"
gh stack submit # hace push, abre los pull requests y los enlaza en la pila
gh stack view # muestra las ramas, los pull requests y su estadogh stack submit abre cada pull request con la base correcta: la primera rama apunta a main, y cada una de las siguientes, a la de debajo. Si tu rama troncal no es main, escribe gh stack init --base release auth-layer. La extensión no es obligatoria; puedes montar la misma pila de otras formas:
- La interfaz web. Abre el primer pull request como siempre. Pon como base del segundo la rama del primero y elige la opción «Create stack». Si ya tienes pull requests abiertos cuyas bases forman una cadena, GitHub lo reconoce y muestra un aviso que propone convertirlos en una pila.
- Un agente de programación.
gh skill install github/gh-stackinstala la habilidad (skill) que enseña al agente a trabajar congh stack; GitHub pone Copilot como ejemplo. - Otras herramientas. Si gestionas tus ramas con Jujutsu, Sapling o git-town, el comando
gh stack linkabre esas mismas ramas como pila en GitHub.
En la página de un pull request que forma parte de una pila aparece el mapa de la pila (stack map). El mapa muestra cada pull request de la pila y su estado, y te lleva con un clic a la capa que quieras; la rama troncal está abajo del todo.
Cómo funcionan la protección de ramas y la CI en una pila
El punto débil de la cadena montada a mano eran las reglas. Las capas de arriba no apuntan a main, sino a una rama de funcionalidad; y la documentación de GitHub dice que, sin el soporte nativo, las reglas de protección de rama y las comprobaciones de CI a menudo solo se disparan en el pull request de más abajo.
En la pila nativa, cada pull request se evalúa con las reglas de la rama troncal de la pila, apunte directamente a la rama que apunte. La página de referencia enumera cuatro reglas: las aprobaciones de revisión obligatorias, las comprobaciones de estado obligatorias, CODEOWNERS y el code scanning.
GitHub Actions sigue la misma lógica. Un workflow que se dispara con el evento pull_request hacia main se ejecuta para cada pull request de la pila; no tienes que cambiar el archivo del workflow.
Eso sí, vigila el consumo de CI: como el workflow se ejecuta una vez por pull request, una pila grande lo multiplica. Para que puedas limitar los trabajos caros a ciertas capas, las expresiones del workflow tienen acceso a la información de la pila, según la documentación: bajo github.event.pull_request.stack están el tamaño de la pila (size) y la posición del pull request (position). Si los dos son iguales, estás en la capa de más arriba.
Cómo hacer merge de una pila
El merge de una pila se hace de abajo arriba. Puedes hacer merge de varios a la vez, siempre que vayan seguidos y empiecen por el pull request más bajo que aún no tenga merge. Un pull request del medio no admite merge por sí solo: los que tiene debajo entran con él.

Según la documentación, para hacer merge de un pull request se exigen tres condiciones: él mismo cumple todos los requisitos de protección de la rama troncal, cada pull request de debajo también los cumple, y el historial entre las ramas es lineal. Si llegó un commit nuevo a una de las ramas de abajo o la rama troncal avanzó, el historial deja de ser lineal. Entonces aparece en el cuadro de merge el botón «Rebase stack»; su equivalente en la línea de comandos es gh stack rebase y, después, gh stack push.
Se admiten los tres métodos de merge: merge commit, squash y rebase. Con squash, cada pull request queda como un solo commit en la rama troncal: tres pull requests, tres commits. Después del merge, al siguiente pull request se le hace rebase automáticamente y pasa a apuntar directamente a la rama troncal. Las ramas locales las actualiza gh stack sync --prune: avanza la rama troncal, coloca encima las ramas restantes y borra las ramas locales que ya tienen merge.
En los repositorios que usan merge queue (cola de merge), los pull requests de la pila entran en la cola en el orden correcto. Si uno sale de la cola, también salen los que tiene encima.
Al montar la pila a mano, nos atascamos en tres puntos
Antes del soporte nativo, en agosto de 2026, montamos a mano una pila de dos capas en nuestro propio repositorio. Nuestro repositorio hace merge con squash. Después del merge del pull request de abajo, tuvimos que hacer tres cosas a mano para el de arriba.

La primera fue el rebase. El squash convierte los commits de la rama de abajo en un único commit nuevo; los commits antiguos no forman parte del historial de la rama troncal. Como la rama de arriba seguía llevando esos commits, un merge directo con la rama troncal dio conflicto. Lo resolvió git rebase --onto, que traslada solo los commits propios del pull request de arriba. La segunda fue la base: el pull request de arriba siguió apuntando a la rama de abajo, y la cambiamos a mano a la rama troncal.
La tercera fue silenciosa. Ni el force-push ni el cambio de base lanzaron la CI para la punta nueva, la del rebase. Las marcas verdes de la página eran de comprobaciones que se habían ejecutado en la punta anterior. Lo que lanzó la CI fue cerrar el pull request y volver a abrirlo.
# al pull request de abajo se le hizo merge con squash; estás en la rama de arriba
git fetch origin
git rebase --onto origin/main <punta-antigua-de-la-rama-de-abajo>
git push --force-with-lease
# cambia la base del pull request de arriba a la rama troncal
gh pr edit 123 --base main
# ¿el commit en el que corrieron las comprobaciones es la punta de la rama?
gh pr view 123 --json headRefOid
gh run list --branch api-endpoints --json headSha,workflowName,conclusionCaímos en una trampa parecida en otro pull request. Cuando el pull request entró en conflicto con su base, GitHub no creó el merge commit sobre el que se ejecutan los workflows, y diez de las once comprobaciones no llegaron a empezar. Aun así, la página decía «All checks have passed · 1 successful check», porque la única comprobación que se ejecutó no necesitaba ese commit. La regla está escrita en la documentación de GitHub: en un pull request con conflictos, los workflows de pull_request no se ejecutan.
Qué hace ahora GitHub por ti
Si ponemos la documentación de GitHub junto a esos pasos, el cuadro queda así.
| Aspecto | Cadena de ramas montada a mano | Pila nativa de GitHub |
|---|---|---|
| La rama de arriba tras el merge de la capa de abajo | Rebase a mano; después de squash hace falta git rebase --onto | Rebase automático |
| La base del pull request de arriba | Se cambia a mano a la rama troncal | Vuelve sola a la rama troncal |
| Reglas de protección de rama y CI | A menudo solo se disparan en el pull request de más abajo | Se evalúan en cada capa según la rama troncal |
| Comprobaciones después del rebase | En nuestro caso no se volvieron a ejecutar; se veía el resultado del commit antiguo | Se vuelven a lanzar después de «Rebase stack» y de gh stack push |
En la columna «Cadena de ramas montada a mano», el rebase, la base y las comprobaciones son nuestra propia experiencia; la fila de las reglas viene de la documentación de GitHub. Columna «Pila nativa de GitHub»: documentación de GitHub, 14 de octubre de 2026.
Según la documentación, el rebase y la base son ahora tarea de GitHub. Sobre squash, la propia documentación de gh stack cuenta lo que vimos nosotros: después de squash, los commits antiguos no están en el historial de la rama troncal; gh stack sync reconoce ese caso y hace el rebase con --onto.
Sobre las comprobaciones, la documentación recoge dos casos de forma explícita: después del botón «Rebase stack» y después de gh stack push, la CI se vuelve a lanzar. Para el rebase automático que llega tras un merge parcial no encontramos nada equivalente en la documentación el 14 de octubre de 2026. Por eso conviene mirar estas cuatro cosas antes de hacer merge de una capa de arriba.

Cómo revisar una pila
Con una pila ya no revisas un diff grande, sino varios pequeños, cada uno respecto a la capa de debajo. Para quien revisa, esto cambia tres cosas.
- Empieza por abajo. La recomendación de GitHub es pedir la revisión desde abajo si las capas están muy ligadas entre sí: un error en la de abajo se arrastra a todas las ramas de encima. Si las capas las revisan personas distintas, también se puede avanzar en paralelo.
- No busques el código de la capa de abajo en el diff de la de arriba. Si una función que llama la tercera capa se definió en la primera, no aparece en el diff y tampoco está aún en
main. La definición está en la propia rama que revisas; el mapa de la pila te lleva al pull request de esa capa. - Escribe el hallazgo en la capa a la que pertenece. Según la documentación, la corrección se hace en la rama a la que pertenece el cambio y después se hace rebase de las ramas de encima. Si el diff no cambió, el rebase no descarta las aprobaciones que ya había.
gh stack checkout auth-layer # la capa a la que pertenece la corrección
git add .
git commit -m "Gestiona el caso del token caducado"
gh stack rebase --upstack # coloca las ramas de encima sobre este commit
gh stack push # envía las ramas con --force-with-leaseEstas reglas valen igual para una persona que para una herramienta de revisión con IA: las dos leen el diff de la capa. Aprobar una capa no es aprobar las de debajo; cada pull request lleva su propia aprobación obligatoria y sus propias comprobaciones.
No todo cambio necesita una pila
La pila es para trabajos que se apoyan unos en otros y son demasiado grandes para revisarlos de una sentada. En estos casos encaja mejor un solo pull request o varios pull requests independientes:
- Si el cambio es pequeño. Partir un diff que se lee de una sentada obliga a quien revisa a abrir páginas de más.
- Si los trabajos no dependen unos de otros. Una pila es una única cadena lineal: cada rama tiene una debajo y, como mucho, una encima. Una corrección sin relación es un pull request aparte.
- Si la contribución viene de un fork. Todas las ramas deben estar en el mismo repositorio; no se admiten pilas entre forks.
- Si la CI es cara. Cada capa ejecuta sus propias comprobaciones; limita primero los trabajos caros a ciertas capas.
En la documentación que leímos el 14 de octubre de 2026 hay tres límites más. GitHub Desktop no admite pilas. Las herramientas que hacen el merge a través de la API tienen que pasarse a la API de merge asíncrona. Sobre el auto-merge, dos páginas dicen cosas distintas: la documentación de merge dice que no se admite en pilas, y el anuncio del 6 de octubre, que se activará en las próximas semanas.
diffox revisa el diff del pull request que se le da. En una pila, cada capa es un pull request distinto, así que cada una se revisa por separado y los hallazgos se escriben en el pull request de esa capa.
Preguntas frecuentes
¿Qué es un stacked pull request?
Los stacked pull requests (pull requests apilados) son una forma de dividir un cambio grande en pull requests pequeños que se apoyan unos en otros. El pull request de abajo apunta a la rama troncal, casi siempre main; cada uno de los siguientes apunta a la rama del que tiene debajo. Cada uno muestra solo el diff de su capa y se revisa por separado.
¿Cómo se crea un stacked pull request en GitHub?
En la línea de comandos, instala la extensión con gh extension install github/gh-stack. gh stack init crea la primera rama y gh stack add, las que van encima; gh stack submit abre los pull requests y los enlaza en la pila. En la interfaz web basta con poner la rama del primer pull request como base del segundo y elegir la opción «Create stack». Todas las ramas deben estar en el mismo repositorio.
¿Qué es gh stack?
gh stack es la extensión de GitHub CLI que publica GitHub para gestionar pilas. Crea las ramas en el orden correcto, hace rebase en cadena, hace push, abre los pull requests y te permite moverte entre capas. No es obligatoria; la pila también se monta desde la interfaz web.
¿Los stacked pull requests siguen en public preview?
No. GitHub anunció la función en public preview (vista previa pública) el 30 de julio de 2026 y la puso en disponibilidad general el 6 de octubre de 2026. Según el anuncio, se puede usar en todos los planes de github.com y llegará en una próxima versión de GitHub Enterprise Server.
¿Qué pasa con los pull requests de arriba cuando se hace merge del de abajo?
Según la documentación de GitHub, siguen abiertos; al siguiente se le hace rebase automáticamente y pasa a apuntar directamente a la rama troncal. Se admiten los tres métodos de merge, squash incluido. Tus ramas locales las actualiza gh stack sync, que reconoce lo que deja un squash y hace el rebase con --onto.
¿Cómo funcionan la CI y las reglas de protección de rama en los stacked pull requests?
Cada pull request de la pila se evalúa con las reglas de la rama troncal de la pila, apunte directamente a la rama que apunte: las aprobaciones obligatorias, las comprobaciones obligatorias y CODEOWNERS se aplican en cada capa. Los workflows de pull_request que apuntan a main se ejecutan para cada capa. Para hacer merge de una capa, todas las capas de debajo también tienen que cumplir las condiciones.
¿diffox revisa los pull requests apilados?
diffox revisa el diff del pull request que se le da. Como cada capa de la pila es un pull request distinto, cada capa se revisa con su propio diff. No hace nada especial con la pila, y tampoco hace falta ningún ajuste.