Skip to content
This page has been auto-translated and may contain errors.View in English

El flujo de solicitud de cambios

docs.scrimba.com

Has estado trabajando en una función en tu propia rama, y está lista. El proyecto es compartido: otras personas también hacen commits en él, así que no envías directamente a main con los dedos cruzados. Quieres que el cambio sea revisado, discutido si es necesario, y fusionado de una manera que todo el equipo pueda ver. Todo ese camino, desde una rama en tu máquina hasta que el código llegue a main, es el flujo de solicitud de cambios, y es cómo casi todos los equipos en GitHub introducen cambios. La parte de Git utiliza solo comandos de capítulos anteriores, una rama, un commit y un envío:

bash
$ git switch -c add-five-day-forecast
Switched to a new branch 'add-five-day-forecast'
$ git add src/forecast.js
$ git commit -m "Add five-day forecast panel"
$ git push -u origin add-five-day-forecast
Branch 'add-five-day-forecast' set up to track 'origin/add-five-day-forecast'.

Ese envío coloca tu rama en GitHub. Nada se ha fusionado aún, y ni siquiera se ha propuesto nada para revisión. El siguiente paso, abrir la solicitud de cambios, ocurre en el sitio web de GitHub.

Qué sucede cuando abres una solicitud de cambios

En GitHub, después de un envío como el anterior, normalmente verás un banner ofreciendo comparar tu rama nueva contra main. Haz clic en él, escribe un título y una breve descripción de qué cambió y por qué, y abre la página que crea. Esa página es una solicitud de cambios, a menudo abreviada como PR: una solicitud para fusionar una rama en otra, con una conversación continua adjunta.

Una solicitud de cambios propone una fusión y espera aprobación. Alguien, quizás tú, quizás un compañero de equipo, lee el cambio, deja comentarios, y solo lo fusiona una vez que se ve bien. Hasta que eso suceda, tu rama y main permanecen exactamente como estaban antes de abrir la página.

No tienes que esperar hasta que una función esté terminada para abrir la PR. Muchos equipos abren una temprano y la marcan como borrador, lo que señala "aún no lista para revisión" mientras aún les da a los revisores un lugar para comentar sobre la dirección antes de que el trabajo esté hecho. Una buena descripción enlaza cualquier problema relacionado y dice qué probaste, así el revisor no tiene que reconstruir eso solo del diff.

GitHub mantiene una ref para cada solicitud de cambios en el remoto, incluso antes de agregar la rama de la PR a tu propio repositorio: refs/pull/<number>/head. Obtén (fetch) esto directamente para revisar la PR de un compañero en tu máquina, sin agregar primero su fork como remoto.

bash
$ git fetch origin pull/42/head:pr-42
From github.com:carlos-mendez/weather-app
 * [new ref]         refs/pull/42/head -> pr-42
$ git switch pr-42
Switched to branch 'pr-42'

Ahora pr-42 es una rama local real construida a partir de la solicitud de cambios número 42, lista para ejecutar y probar antes de dejar un solo comentario.

JunoQué sucede cuando abres una solicitud de cambios Una solicitud de cambios es una solicitud para fusionar tu rama en otra, abierta en GitHub después de que haces un envío. Alguien revisa el cambio primero, y solo entonces se fusiona. El bucle diario es rama, envío, abrir una solicitud de cambios, obtener revisión, fusionar.
JunoQué sucede cuando abres una solicitud de cambios Una PR propone una fusión y mantiene la conversación alrededor de ella, y puedes abrir una temprano como borrador para obtener retroalimentación antes de que el trabajo esté terminado. Escribe la descripción como si un revisor realmente la fuera a leer: qué cambió, por qué, y qué probaste.
JunoQué sucede cuando abres una solicitud de cambios GitHub mantiene una ref oculta para cada solicitud de cambios, refs/pull/<number>/head, así que puedes obtener la PR de un compañero directamente en tu máquina con git fetch origin pull/42/head:pr-42 en lugar de agregar su fork como remoto. Prueba el cambio localmente antes de dejar tu primer comentario.

Fork vs rama

Abrir una solicitud de cambios desde una rama funciona cuando tienes acceso de escritura al repositorio, que es el caso normal en los proyectos de tu propio equipo. Contribuir a un proyecto al que no tienes acceso de escritura requiere un paso extra: un fork, tu propia copia del repositorio bajo tu propia cuenta de GitHub.

Creas ramas y haces commits dentro de tu fork exactamente como lo harías en un proyecto que posees, envías a tu fork, y luego abres la solicitud de cambios desde la rama de tu fork de vuelta al repositorio original. GitHub compara entre los dos repositorios de la misma manera que compara dos ramas dentro de un repositorio, así que el flujo de revisión y fusión se ve idéntico de cualquier forma.

Si planeas enviar más de una PR a un proyecto que has hecho fork, vale la pena agregar el repositorio original como un segundo remoto, normalmente llamado upstream, mientras que origin sigue apuntando a tu propio fork. Ejecuta git fetch upstream y fusiona upstream/main en tu rama para ponerte al día con un proyecto que ha avanzado desde que lo hiciste fork, usando los mismos pasos que el capítulo Remotos y GitHub cubre para cualquier remoto.

JunoFork vs rama Crea ramas directamente cuando tienes acceso de escritura a un repositorio, los proyectos de tu propio equipo. Haz fork cuando no lo tienes: un fork es tu propia copia del repositorio de otra persona, y creas ramas y haces envíos dentro de esa copia antes de abrir la solicitud de cambios de vuelta al original.
JunoFork vs rama Un fork es una copia completa de un repositorio bajo tu cuenta, utilizado para contribuir donde no tienes acceso de escritura. Creas ramas, haces commits y envíos dentro de tu fork como normalmente, y GitHub compara la rama de tu fork contra el repositorio original de la misma manera que compara dos ramas dentro de un proyecto.
JunoFork vs rama Mantén dos remotos en un proyecto hecho fork: origin para tu propio fork, upstream para el repositorio original, así puedes obtener y fusionar sus cambios conforme avanza. La PR en sí aún compara la rama de tu fork contra la rama base del repositorio original.

Haciendo que tu solicitud de cambios pase revisión

Una vez que una PR está abierta, se convierte en una conversación continua sobre el diff. Un revisor lee el cambio, deja comentarios en líneas específicas, y aprueba o solicita cambios. Cuando se solicitan cambios, sigue haciendo commits y envíos a la misma rama: cada envío actualiza la misma PR en lugar de crear una nueva. Una vez que un revisor aprueba y cualquier verificación requerida pasa, la PR está lista para fusionarse.

GitHub rastrea una revisión como uno de tres estados: aprobado, cambios solicitados, o comentado (retroalimentación sin un veredicto de ninguna forma). Responde a los comentarios conforme los diriges y marca la conversación resuelta para que un revisor pueda ver de un vistazo qué queda. Si envías una corrección para un comentario específico, ayuda decirlo en tu mensaje de commit o una respuesta, ya que un revisor que trabaja en una PR larga está buscando exactamente eso.

Cuántas aprobaciones necesita una PR, y si cada hilo de comentario tiene que ser marcado resuelto antes de que se desbloquee el botón de fusión, es normalmente una regla adjunta a la rama base en sí en un proyecto bien dirigido.

JunoHaciendo que tu solicitud de cambios pase revisión Un revisor comenta en tu solicitud de cambios y puede solicitar cambios. Haz commit y envía más trabajo a la misma rama para abordarlo, y la PR se actualiza automáticamente. La fusión ocurre una vez que alguien aprueba.
JunoHaciendo que tu solicitud de cambios pase revisión Las revisiones se ubican en uno de tres estados: aprobado, cambios solicitados, o comentado. Envía correcciones a la misma rama para actualizar la PR, responde a comentarios conforme los resuelves, y mantén al revisor orientado en un hilo largo.
JunoHaciendo que tu solicitud de cambios pase revisión Los estados de revisión determinan si se desbloquea el botón de fusión, pero la barra exacta, cuántas aprobaciones, si cada hilo de comentario debe ser resuelto, es normalmente una regla adjunta a la rama base en sí en un proyecto bien dirigido.

Por qué una solicitud de cambios no se fusionará

A veces el botón de fusión en una PR está atenuado, y GitHub muestra un mensaje en su lugar: "Esta rama tiene conflictos que deben resolverse" o "Esta rama está desactualizada con respecto a la rama base." Ambos mensajes describen un estado normal y solucionable: main ha avanzado desde que creaste la rama, normalmente porque la PR de otro se fusionó mientras tanto, y tu rama necesita ponerse al día antes de que GitHub pueda combinar las dos limpiamente. Esto sucede en cualquier proyecto con más de un contribuidor, así que espéralo en lugar de temerlo.

Soluciónalo localmente de la misma manera que traerías cualquiera de dos ramas juntas:

bash
$ git switch add-five-day-forecast
$ git fetch origin
From github.com:carlos-mendez/weather-app
   9f8e7d6..b7c9e21  main       -> origin/main
$ git merge origin/main

Si nada se superpone, la fusión se completa por sí sola y haces un envío, y la PR se actualiza y el botón se desbloquea. Si las mismas líneas cambiaron en ambos lados, Git marca el conflicto en el archivo para que lo resuelvas exactamente como se cubre en Fusión y conflictos: abre el archivo, edita los marcadores de conflicto al resultado que quieres, luego git add y git commit para terminar la fusión, y envía de nuevo.

Una solicitud de cambios atascada necesita ponerse al día o resolver su conflicto.

En una PR que permanece abierta por más de un día o dos, vale la pena fusionar main en tu rama de vez en cuando en lugar de esperar a que el botón se bloquee. Una rama que está un día atrasada normalmente se fusiona sin conflicto en absoluto; una que está tres semanas atrasada tiene mucha más superficie para que dos cambios choquen en las mismas líneas. El botón "Update branch" propio de GitHub en la página de PR hace esta misma fusión por ti cuando no hay nada que resolver manualmente.

Algunos equipos rehacen una rama de función en main en lugar de fusionarla, para mantener el historial eventual lineal en lugar de mostrar un commit de fusión para cada PR. Ese compromiso es el mismo cubierto en Fusión y conflictos: rehacer rescribe los commits de tu rama, que es seguro siempre que seas el único con copias de ellos, así que una rama de función sola que solo vive en tu máquina y su PR es un candidato razonable. Rehacer una rama que otras personas ya han obtienen e incorporado no lo es, ya que rescribe el historial en el que confían.

JunoPor qué una solicitud de cambios no se fusionará Un botón de fusión atenuado significa que tu rama está atrás de main o tiene un conflicto con ella. Nada está roto. Cambia a tu rama, obtén, y fusiona main, resolviendo cualquier conflicto de la misma manera que lo harías en cualquier lugar, luego envía de nuevo.
JunoPor qué una solicitud de cambios no se fusionará Fusiona main en una rama de larga ejecución de vez en cuando en lugar de esperar a que GitHub bloquee el botón de fusión. Las capturas más pequeñas y frecuentes significan conflictos más pequeños, y el botón "Update branch" de GitHub puede hacer el caso sin conflicto por ti.
JunoPor qué una solicitud de cambios no se fusionará Fusionar o rehacer tu rama en main ambos solucionan una PR atascada, y una rama de función sola es segura para rehacer ya que nadie más tiene una copia de sus commits. Una vez que otras personas han obtenido una rama, adhiérete a fusionarla en lugar de eso.

Qué es una solicitud de cambios, bajo el capó

Una solicitud de cambios no es un objeto de Git, y no hay un comando git que la cree. Git y GitHub no son la misma cosa: Git solo sabe sobre commits, ramas, y otras refs (una ref es un nombre que apunta a un commit). GitHub construye toda la página de PR, los comentarios, y el botón de fusión encima de dos refs que compara: tu rama (el head) y la rama en la que estás fusionando (la base, normalmente main). Esa comparación es por qué abres una solicitud de cambios en el sitio web de GitHub (o a través de la herramienta de línea de comandos de GitHub o API), y nunca con un comando plano git.

Porque una PR vive en GitHub, separada del historial del repositorio, sus comentarios y conversación de revisión no viajan con los commits. Si alguna vez mueves un proyecto a un host diferente, cada commit viene contigo sin cambios, pero las solicitudes de cambios y sus discusiones se quedan atrás en GitHub, ya que nunca fueron parte de los datos de Git en el primer lugar.

GitHub calcula el diff de una PR encontrando la base de fusión, el commit más reciente que tanto la ref head como la ref base comparten, y comparando el head contra ese punto en lugar de contra lo que main se ve como ahora. Cada envío a la rama agrega una nueva versión a la misma PR en lugar de crear una nueva comparación. Protección de rama es la capa de política sentada encima de todo esto: una regla que tú (u tu organización) adjuntas a una rama, más a menudo main, que puede requerir verificaciones de estado aprobadas, requerir un conjunto de revisiones de aprobación, y bloquear envíos directos así que cada cambio es forzado a través de una solicitud de cambios. Git en sí no aplica nada de esto. Te dejará hacer envío directo a main desde tu terminal hasta que la regla de GitHub rechace la solicitud.

JunoQué es una solicitud de cambios, bajo el capó Una solicitud de cambios es una función de GitHub superpuesta en Git: Git rastrea commits y ramas, y GitHub agrega la página de PR y el botón de fusión comparando dos de ellos. Mantener Git y GitHub separados en tu cabeza explica mucho de lo que de otro modo parece magia.
JunoQué es una solicitud de cambios, bajo el capó Una PR compara tu rama contra una rama base y vive completamente en GitHub, así que sus comentarios e historial de revisión no se mueven si el repositorio alguna vez cambia de host. Los commits en sí son la única parte que es realmente Git.
JunoQué es una solicitud de cambios, bajo el capó Una PR es GitHub comparando una ref head contra una ref base desde su base de fusión compartida, actualizado con cada envío. La protección de rama es la política aplicada encima, requiriendo verificaciones o revisiones antes de fusión. Git en sí no aplica nada de esto: te dejará hacer envío directo a main hasta que la regla de GitHub lo detenga.