- Stacked pull requests, que dividen cambios grandes en capas pequeñas y revisables, se están habilitando gradualmente como vista previa pública para todos los repositorios
- Cada PR apunta a la capa inmediatamente inferior, lo que permite que los miembros del equipo hagan una revisión independiente en paralelo sobre diffs acotados
- Al fusionar el PR más reciente, también se aplican de una vez las capas inferiores que aún no se hayan fusionado; si solo se fusiona una parte, los PR superiores se rebasean automáticamente y cambian de destino
- Se mantienen la revisión de PR existente, las comprobaciones obligatorias, la protección de ramas y los requisitos de fusión, y los stacks pueden manejarse desde GitHub.com, CLI, la app móvil y GitHub Copilot
- La vista previa pública se expandirá a todos los repositorios a lo largo de varios días, y el soporte para Merge queue se irá habilitando gradualmente durante las semanas siguientes
Estructura de PR apilados para cambios pequeños
- Los cambios grandes se dividen en varios PR pequeños y enfocados, y cada PR se organiza como una capa de cambios con un orden definido
- Después de crear la rama y el PR del primer cambio, se agregan más ramas y PR encima, y cada PR apunta a la capa inmediatamente inferior
- Reduce la incomodidad de revisar un único PR enorme o tener que seguir haciendo rebase manualmente a varias ramas
- El equipo de Next.js comentó que pudo lanzar funciones grandes manteniendo pequeños los cambios individuales, lo que facilitó la revisión de PR
Creación del stack y entorno de trabajo
- La extensión de CLI se instala con el siguiente comando
gh extension install github/gh-stack
- Los stacks pueden crearse y administrarse desde GitHub.com, GitHub CLI y la app móvil de GitHub
- En agentes de codificación como GitHub Copilot puede usarse la skill
gh-stack
Revisión independiente por capa
- Al abrir un PR dentro del stack, puede revisarse solo el diff de esa capa en lugar del cambio completo
- En el mapa del stack, en la parte superior del PR, puede verse dónde se ubica el cambio actual dentro del trabajo total
- Los miembros del equipo pueden revisar distintas capas en paralelo, por lo que el trabajo posterior no queda bloqueado hasta que termine la revisión
- Las reglas existentes de protección de ramas pueden combinarse con la revisión por capa para controlar la calidad en cada etapa
- TED señaló que, tras aumentar la productividad de desarrollo con la adopción de IA, los PR más grandes se convirtieron en un cuello de botella para la revisión, y que dividir los cambios en pequeñas unidades lógicas según el orden de dependencias mejoró la velocidad y la precisión de las revisiones
Fusión de todo o parte del stack
- Al fusionar el PR más reciente que ya está listo, se aplican de una sola vez ese PR y todas las capas inferiores que aún no se hayan fusionado
- También puede fusionarse primero solo una parte del stack, eligiendo una o más capas inferiores
- Los PR superiores permanecen abiertos
- Se rebasean automáticamente según los cambios ya fusionados y también cambia la rama de destino
- La protección de ramas, las comprobaciones obligatorias y los requisitos de fusión existentes siguen aplicándose para controlar los cambios que entran a
main
- Puede fusionarse selectivamente todo el stack, una sola capa o solo algunas capas
Vista previa pública y calendario de soporte
- Stacked pull requests se desplegará gradualmente como vista previa pública para todos los repositorios a lo largo de varios días
- El soporte para Merge queue se habilitará de forma gradual durante las semanas siguientes
- La guía detallada de uso está disponible en la documentación de stacked pull requests, y reciben comentarios en stacks discussion
1 comentarios
Opiniones de Hacker News
He usado la vista previa por un tiempo, y me sorprende que estén ampliando el alcance cuando todavía hay muchos problemas sin resolver.
Por ejemplo, fusionar todo el stack está completamente roto en varias situaciones: https://github.com/github/gh-stack/discussions/212
Se puede fusionar de a uno, pero si usas squash merge junto con revisiones obligatorias, hay que volver a aprobar cada PR del stack, con lo que se pierde la mayor ventaja de los PR apilados.
gh stackreduce un poco el trabajo manual, pero igual hay que entender exactamentegit rebase. Si la rama local no está sincronizada con la remota, elgh stack rebaseque sugiere la UI también falla, y la herramienta no explica la causa.En cambio, me gusta la UI de stacks porque es simple y aun así muestra lo suficiente la relación entre PR. Solo hace más cómodo el flujo de trabajo, suponiendo que ya tienes una razón para apilar PR; no es una herramienta que aporte una funcionalidad nueva.
Internamente, CPRMC (Create Pull Request Merge Commit) determina si un PR está listo para fusionarse verificando desde si hay conflictos hasta si lo aprobado coincide con el commit que realmente se va a crear.
Para hacer squash merge de varios PR, hay que calcular commits squash consecutivos y luego volver a conectarlos con las reglas y las revisiones. El primer PR es relativamente fácil, pero desde el segundo se complica porque el commit ancestro fue squasheado y ya no existe en la rama en su forma original; las situaciones con varios padres son todavía mucho más difíciles.
Actualmente el 99% de las fusiones de stacks tiene éxito, pero elevar mucho más ese porcentaje es la máxima prioridad del equipo.
mergingsin más indicaciones.Pensé que podía ser una falla parcial del sistema de PR y hasta revisé la página de estado de GitHub, pero era un bug de la propia función de PR apilados.
El equipo de GitHub Stacked PRs ahora lo abrió más ampliamente para que cualquiera pueda crear stacks: https://gh.io/stacks
Les interesa especialmente recibir feedback sobre la UI y la CLI, y también tienen preparadas muchas actualizaciones para mejorar la experiencia de uso de PR.
Es uno de los lanzamientos más grandes en la historia de GitHub, ya que abarca casi todos los servicios, desde Actions y reglas de protección hasta la CLI y la app móvil, así que también pueden responder preguntas sobre decisiones de diseño y funcionamiento interno.
Como ya uso una UI local propia para ver las dependencias de los PR apilados como un árbol y gestionar el estado de revisión y CI de cada PR, me gustaría que la UI web de GitHub también tuviera un árbol e indicadores de estado.
En la UI web no parece estar soportada la función de fusionar solo el PR de más abajo del stack; podemos compartir nuestro flujo de trabajo y código existente, así que espero que también se incorpore a las herramientas nativas de GitHub.
Para que sea útil en repositorios públicos parece una función importante, así que me sorprende que no se ofreciera antes de la vista previa pública.
En lugar de una UI adecuada para revisar, aplicar y corregir por commit, quisiera saber si hubo alguna reflexión particular para ignorar el flujo de trabajo de series de parches de las listas de correo, que es el origen de este enfoque, y optar en la práctica por “series de series de parches”.
Es uno de los cambios más grandes aplicados a GitHub en años.
Con la introducción de un flujo de trabajo apilado en una de las plataformas de hosting de código más grandes del mundo, muchos desarrolladores podrían conocer una forma de trabajar cuya existencia ni siquiera sabían.
Si la premisa de que los stacks producen mejor software es correcta, también podría ayudar de verdad a muchos desarrolladores.
Me pregunto cuál es la ventaja de estos PR apilados frente a revisar commits bien organizados commit por commit.
El problema más grande es que los grandes PR generados por IA necesitan una forma de revisión aparte. Solo el orden en que se muestran los diffs —por ejemplo, definiciones de funciones, sitios de llamada y luego pruebas— puede cambiar mucho qué tan fáciles son de leer.
Así como la programación literaria entrelaza código y prosa, quizá haga falta un diff literario o PR literario que combine diferencias y explicación, pero todavía no encontré herramientas parecidas.
Como el PR o diff, que es la unidad de revisión, se mantiene como un cambio acotado, la discusión se concentra en ese cambio, y aunque la funcionalidad crezca el PR en sí no se vuelve enorme.
Además, cada parte del stack se puede asignar a distintas personas. Si separas revisores —un equipo externo, compañeros del mismo equipo, el equipo que usa el cambio— no queda ambiguo qué está aprobando cada uno.
Sería aún mejor si las revisiones de GitHub introdujeran ID de cambio (change ID) para conservar los comentarios incluso después de un rebase.
Tener que rebasear y corregir los PR posteriores es igual que arreglar commits posteriores en un único PR enorme, pero en vez de pegar commits temporales de corrección al azar sobre todo el cambio, se vuelve más fácil mantener juntos los commits del cambio base.
La discusión sobre el cambio base también queda reunida, y si muestras todo el stack por adelantado, el revisor puede entender la dirección final mientras el trabajo sigue avanzando de forma asíncrona.
Usan los commits como puntos de guardado de un juego, dejan mensajes como
fix bugodo worky luego no los ordenan congit rebase -i; si no activas el squash merge obligatorio, el historial se llena de commits basura.Para estos desarrolladores, el PR es el commit, y los PR apilados finalmente les permiten usar una estructura parecida a varios commits que componen un solo cambio.
Los diffs fusionados se pueden rebasear sobre el HEAD actual, y en equipos que soportan esto normalmente no se gestionan ramas directamente, sino que se trabaja desde trunk y se hace rebase cada vez que entran cambios.
Si las primeras 4 partes de una funcionalidad están listas y la quinta tiene problemas, no hace falta bloquear todo.
Me pregunto cuándo se dará soporte a los casos en que los PR con dependencias forman una estructura de árbol en vez de un historial lineal.
Cuando usaba cambios apilados en Google, estos casos eran comunes, y con el aumento de agentes de codificación en paralelo parece que ocurrirán aún más seguido.
Me pregunto si el botón para cambiar de menú es un emoji de pila de pancakes (U+1F95E) por la función de stacks.
La expresión juguetona en sí está bien, pero era una UI que generaba fuertes dudas sobre qué se estaba viendo.
Lo mostraremos solo unas horas y luego volveremos a un ícono normal.
Usé la CLI
gh stackdesde que escuché la noticia por primera vez, y la herramienta en sí era muy buena, pero la UI web a la que accedí tras recibir aprobación para la preview quedó muy por debajo de mis expectativas.Incluso antes de la aprobación, la CLI facilitaba automatizar la división del trabajo en varios PR atómicos, pero al hacer push aparecían como PR independientes sin conexión entre sí.
Después de la aprobación es casi lo mismo: lo único es que en un pequeño desplegable de navegación en la parte superior aparecen otros PR del mismo stack, así que no hay un cambio significativo en la UI.
Desde el desplegable se pueden ejecutar algunas funciones de la CLI, pero se siente más como una comodidad secundaria, similar a editar archivos desde la web; en el flujo real de desarrollo, la CLI o un plugin del IDE serán el centro.
Me pregunto por qué se retrasó tanto la disponibilidad general por una UI opcional de este nivel, si la CLI de stacks ya estaba disponible de forma general desde el anuncio.
También planeamos incluir una vista que siempre reconozca el stack y lo muestre de forma persistente para poder moverse entre cada capa sin tantos clics.
Me gusta que jujutsu, al actualizar una rama, también rebase automáticamente las otras ramas que se desprendieron de ella.
Cuando divido el trabajo para que sea más fácil de revisar, a menudo cambio a
jj, y funciona bien incluso al usarlo junto con una copia hecha con Git en el mismo directorio de trabajo.jj absorbtambién es excelente.Mueve los cambios al cambio relacionado más cercano, así que permite manejar fácilmente correcciones que afectan a varios PR.
Después de usar Graphite, se volvió muy difícil volver a GitHub sin stacks.
Espero que el soporte de GitHub haga que los flujos de trabajo con PR apilados se vuelvan comunes y ofrezca una alternativa sencilla a los PR enormes.
git-spice.Es open source, fácil de usar y potente; Graphite me pareció demasiado complejo para las funciones que ofrece.
Entendía que apilar PR era útil en dos situaciones.
Primero, cuando abarcan varios repositorios relacionados y no se pueden unir en un solo PR; segundo, cuando se apilan PR posteriores sobre la misma rama mientras se revisa el primer PR, para canalizar el trabajo.
Pero esta función no parece cumplir ninguna de las dos, sino más bien otra forma de apilar commits en un único PR.
Normalmente se crean commits atómicos y con sentido, y se usa rebase para construir un flujo fácil de entender para el revisor; el revisor también puede revisar por commit si quiere.
Me pregunto cuál es el beneficio único que se está perdiendo con este enfoque.