En esta entrada, la tercera de una serie de tres, explicamos qué es un pull request y cómo funciona en github.
Recordamos brevemente qué es lo que nuestros usuarios aalbagarcia y aprendegit-user1 hicieron en las dos entradas anteriores:
- El usuario aalbagarcia crea un repositorio en github: https://github.com/aprendegit/fork
- El usuario aprendegit-user1 crea un fork (bifurcación) para trabajar en él: https://github.com/aprendegit-user1/fork
- Los dos usuarios realizan modificaciones cada uno en su repositorio, cada uno de ellos hace un commit y posteriormente un push. Cada uno sube los cambios a su correspondiente repositorio
- El usuario aprendegit-user1 configura un repositorio remoto adicional (upstream) e incorpora, haciendo un merge, los cambios en el código que hizo aalbagarcia. Después de hacer el merge, aprendegit-user1 hace un push para actualizar su repositorio remoto.
Lo último que nos falta por hacer es que el usuario aalbagarcia, que es el propietario del repositorio inicial (https://github.com/aprendegit/fork), incorpore el trabajo del usuario aprendegit-user1 que se encuentra en el fork https://github.com/aprendegit-user1/fork.
¿Qué es un pull request?
Un pull request es una petición que el propietario de un fork de un repositorio hace al propietario del repositorio original para que este último incorpore los commits que están en el fork. En el caso que nos ocupa, el usuario aprendegit-user1 le enviará la petición a aalbagarcia para que este último incorpore los commits que tiene en su fork.
Lo primero que hará el usuario aprendegit-user1 será crear una rama que apuntará al último commit que ha hecho y que contiene las modificaciones a la página de inicio. El procedimiento es el de siempre:
- Se selecciona a la izquierda la rama master y se hace clic sobre el último commit de la rama
- Se hace click sobre el icono «Branch»
- Se introduce el nombre de la rama, en este maso mycommits
- Se hace clic sobre «Create Branch»
Si se usa la línea de comandos, la secuencia sería:
$ git checkout master Switched to branch 'master' $ git checkout -b mycommits Switched to a new branch 'mycommits'
Una vez creada la rama, el usuario aprendegit-user1 hace push de la rama «mycommits» a su fork:
- Se selecciona la rama mycommits a la izquierda asegurándonos de que esta queda como rama activa haciendo doble clic sobre ella
- Se selecciona el último commit de la rama
- Se hace clic sobre el icono Push de la bara de herramientas
- En el desplegable, se selecciona en la columna «Push?» la rama mycommits y se marca en la columna de la derecha (Track) la rama local como tracking branch.
- Se hace clic sobre OK.
$ git checkout mycommits $ git push -u origin mycommits Total 0 (delta 0), reused 0 (delta 0) To git@github-aprendegit-user1:aprendegit-user1/fork * [new branch] mycommits -> mycommits Branch mycommits set up to track remote branch mycommits from origin.
Al terminar, el estado del repositorio es el siguiente:
Solicitando el pull request
En este momento, el usuario aprendegit-user1 accede a su cuenta de github y abre en su navegador la página de su fork https://github.com/aprendegit-user1/fork.
Una vez hemos accedido, cambiamos a la rama mycommits como se indica en la siguiente captura:
Una vez se ha cambiado a la rama mycommits, aprendegit-user1 hace clic sobre el botón «Pull Request»
Esta es la pantalla que se presenta a aprendegit-user1:
En la parte superior, aprendegit-user1 selecciona la rama que contiene los commits que aalbagarcia (el destinatario del pull request) debe incorporar en su repositorio. En la parte de abajo se ven tres pestañas en las que se puede:
- Poner un título y descripción al pull request
- Ver los commits que aalbagarcia incorporará al repositorio si acepta el pull request (pestaña Commits)
- Ver un diff que los cambios que se incluyen en los commits (pestaña Files Changed)
Es una buena práctica poner un título y descripción que reflejen el motivo del commit. Estos pull requests los ven todos los colaboradores del proyecto (si el proyecto es público lo ve todo el mundo) Así que aunque aalbagarcia y aprendegit-user1 hayan hablado por teléfono acerca de este pull request, el resto del mundo seguramente no ha escuchado la conversación. Pensando en el resto del equipo, aprendegit-user1 incluye un mensaje descriptivo de qué contiene el pull request. Cuando termina, hace clic sobre el botón «Send Pull Request». Esta es la pantalla a la que aprendegit-user1 llega después de enviarlo:
La captura es bastante sencilla de entender. Vemos el título y descripción introducidos por aprendegit-user1, los commits y una interfaz para intercambiar comentarios con el equipo.
Aunque en pequeño, se nos indica qué es lo que tendríamos que hacer para añadir commits a este pull request: enviar más commits a la rama «mycommits» del fork de aprendegit-user1.
¿Porqué podemos necesitar añadir más commits? Imagínate que el equipo revisa el pull request y se determina que todavía queda trabajo pendiente de hacer. ¿Cómo se procede? aprendegit-user1 continúa el trabajo en la rama rama «mycommits» de su fork y cuando termina lo sube a su repositorio remoto. El pull request se actualiza y todo el equipo puede ver el nuevo código. Esto lo veremos en detalle en otro artículo, de momento, seguimos con el proceso.
Aceptando el pull request
Cuando aprendegit-user1 envía el pull request, Github envía al propietario un email avisándole de que tiene un pull request listo para revisar. En este caso, el usuario aalbagarcia recibe el email, accede a su cuenta de Github y va a su repositorio https://github.com/aprendegit/fork:
En esta pantalla, seleccionamos la pestaña «Pull Requests» y accedemos a una interfaz que nos muestra todos los que tenemos. Dado que este es el primero, en este listado seleccionamos el único que hay:
Cuando aalbagarcia selecciona «Añadiendo logotipo», accede a una pantalla muy parecida a la que hemos visto con el usuario aprendegit-user1. En la siguiente captura indico cuáles son las diferencias:
Las diferencias son:
- Existe un botón «Merge pull request» que el propietario aalbagarcia utilizará para incorporar los commits al repositorio
- Existe un botón «Close» que el propietario utiliza para cerrar el pull request sin incorporar los cambios
Una vez revisado el código y confirmado que todo está bien, aalbagarcia hace clic sobre el botón «Merge Pull Request». En ese momento Github le pedirá que introduzca un comentario para el merge commit. Una vez introducido, aalbagarcia hace clic sobre el botón «Commit merge» y ya está, Github automáticamente cierra el pull request. También envía un email a los dos interesados (aalbagarcia y aprendegit-user1) avisándoles de que se han incorporado los cambios en el repositorio.
Si volvéis a la página de commits del repositorio en github (https://github.com/aprendegit/fork/commits/master) veréis que tras hacer el pull request, aparece un nuevo commit en el repositorio:
¿Cómo quedan los repositorios de aalbagarcia y aprendegit-user1?
En este momento, el repositorio remoto de aalbagarcia ya contiene el merge commit que se ha creado a través del pull request. La pregunta es ¿el de aprendegit-user1 también? ¿verán estos nuevos commits los dos usuarios?
…la respuesta es que, efectivamente, no lo verán hasta que hagan un fetch en sus respetivos repositorios. Tras hacer los dos usuarios un fetch de todos sus repositorios remotos (recuerda que aprendegit-user1 tiene 2 remotos, origin y upstream) así quedan sus respectivas copias de trabajo:
Para terminar:
- aalbagarcia tiene que hacer un merge de la rama origin/master a la rama master
- aprendegit-user1 tiene que hacer un merge de la rama upstream/master a la rama master y después hacer un push de su rama master
Una vez hecho esto, los repositorios quedan de la siguiente manera:
Y como podéis ver, están sincronizados.
¿Quieres hace un pull request?
Si quieres hacer tú mismo el proceso para ver cómo funciona, ve al repositorio https://github.com/aprendegit/fork, haz un fork y envíanos las modificaciones siguiendo los pasos que hemos seguido en esta serie de artículos. Si tienes alguna duda no dudes en preguntarnos.
Seguiremos hablando de pull requests, aunque eso ya será en otros artículos.
Pingback: Mantener tu fork al día | Aprende GIT
Pingback: Uso avanzado de referencias: github y pull requests | Aprende GIT
Como no veo comentarios, por mi parte decir que se ha entendido todo perfectamente, una explicación muy clara, gracias.
¡Gracias! me alegro de que te haya servido de ayuda.
Muchas gracias por compartir tu experiencia y tiempo con este tutorial, me fue muy fácil seguirlo está bien explicado y me sirvió para hacer mi primer pull request a un repo al que quería compartir un cambio, gracias saludos sigue así
Hola Sandino:
Gracias por tu comentario. Me alegra mucho que el artículo te haya ayudado.
Un saludo,
Alfonso
Pues yo no entendí mucho, imagino porque soy nuevo en Git y no me familiarizo aun con los terminos:
«fork», «bifurcacion», «pull request», «checkout»
Hola Luis:
Si acabas de llegar al mundo de git y te lees de primeras este artículo, es normal que no entiendas mucho. Te recomiendo que le eches un vistazo a la presentación de introducción a git que hicimos Israel y yo hace poco, la puedes ver en esta entrada: https://aprendegit.com/primera-reunion-del-grupo-de-usuarios-de-git/
Creo que te va a resultar más asequible 😉
Luis, tienes razón en este comentario. Es problema de cómo está escrito el artículo. Con tanto extranjerismo crudo es muy difícil leerlo. Está lleno de faltas.
Invito a la revisión de este artículo, por ejemplo:
Un pull request es una petición que el propietario de un fork de un repositorio hace al propietario del repositorio original para que este último incorpore los commits que están en el fork.
Sustituir por:
Una petición de extración o «pull request» es una petición que el propietario de una bifurcación ( fork – en cursiva-) hace al propietario del repositorio original para que este último incorpore la confirmación del conjunto de cambios que están en la bifurcación (fork).
Así el artículo tendría mucha más calidad.
Saludos.
Hola de nuevo SVA:
Como te he respondido en otro commentario tuyo al respecto, de nuevo gracias por recordarme lo complicado que es hablar de este tema en Español. A raiz de tus comentarios, he estado leyendo al respecto en la RAE ya que efectivamente, mis textos están llenos de extranjerismos.
En todos los años que llevo trabajando con git con compañeros del metal en español, absolutamente a nadie, jamás, le he escuchado decir «petición de extracción» o «confirmación de cambios». Si usase ese vocabulario entre mis compañeros no sabrían de qué estoy hablando, te lo aseguro. Pocas veces he escuchado el uso de bifurcación en lugar de fork, que a mi es un término que me parece tremendamente confuso en castellano ya que puede confundirse un fork traducido como bifurcación con una bifurcación como tal en un grafo consecuencia del uso de ramas. Si en un curso en el que hablo de forks en lugar de usar el extranjerismo usase el término bifurcación, la confusión que generaría en las personas a las que estoy intentando enseñar sería tremenda.
Asi que, siendo práctico, y estando totalmente de acuerdo contigo en que el español es muy rico y que debemos usarlo siempre que podamos, seguiré usando los extranjerismos para que el resto de interlocutores me entienda sin ambigüedades.
Commo te he comentado antes, gracias a tus comentarios he estado liyendo un poco sobre este tema. Encontré en la RAE este documento (https://www.rae.es/dpd/ayuda/tratamiento-de-los-extranjerismos) que dice lo siguiente:
Creo que los extranjerismos relacionados con git cumplen el punto 2: están muy extendidos y/o no es fácil encontrar términos en castellano equivalentes. Por ejemplo «petición de extracción» o «confirmación de cambios», son términos que a mi juicio no significan lo mismo que los correspondientes términos en inglés. Por ello, seguiré usando los extranjerismos.
De nuevo, te agradezco tus comentarios ya que me has ayudado a profundizar en un tema sobre el que nunca me había detenido a pensarlo mínimament. Si algún día coincidimos en algún evento, sería genial continuar esta conversación en persona.
Un cordial saludo,
Alfonso
Hola,
Primero que nada muy útil el tutorial.
Particularmente en mi proyecto, tendría que tener una funcionalidad puntual
y consiste en que los pull request los pueda validar mas de un usuario. esto es posible?
Básicamente lo que solicita el cliente, es un usuario de ellos que simplemente tenga la función de validar los pull request y confirmar los cambios.
Esto se puede manejar?
Gracias.
Saludos.
Hola Lucas:
En primer lugar, gracias por tus comentarios.
Sobre lo que planteas, creo que no lo vas a poder conseguir con la versión estándar de github. Si miras aquí https://help.github.com/articles/permission-levels-for-an-organization-repository, lo máximo que podrías crear es un usuario administrador de vuestro repositorio que tenga permiso de escritura lo que le permitiría, entre otras cosas, aprobar / rechazar pull requests. Sin embargo, este podría hacer todas las operaciones de escritura que tienes en ese enlace.
También puedes echar un vistazo a la documentación de bitbucket: https://confluence.atlassian.com/display/BITBUCKET/Repository+privacy,+permissions,+and+more
aunque echando un vistazo rápido me ha parecido que vas a tener qué implementar una solución parecida a la de github que te he puesto arriba.
Otra solución que puedes mirar el gitlab, aunque he estado mirando en los permisos que facilita y no indica al respecto (https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/permissions/permissions.md)
Tendrías que mirar si la versión Github Enterprise o Stash (de bitbucket) os permite hacer lo que estás planteando.
Otra consulta.
Nosotros en el proyecto utilizamos eclipse y tenemos el remoto en la red interna del cliente.
Como se gestionan los pull request para ver las modificaciones.
Se puede ver los cambios y demas desde el mismo eclipse? hay algún programa que cumpla la función de la interfaz del servidor gitHub?
Gracias.
Saludos.
Hola Lucas:
El servidor del cliente ¿qué tipo de servidor es? ¿cómo os conectáis a el para hacer los push/pull? ¿Usan gitlab, github enterprise, stash, teamforge o ssh puro y duro?
Con respecto a la última pregunta «¿hay algún programa que cumpla la función de la interfaz del servidor gitHub?»: la solución que te recomendaría que mirases es gitlab.
Hola alfonso,
Primero agradecerte por estos tutoriales tan buenos que haz montado en esta página. Tengo un problema, estoy intentando hacer otro pull request desde la rama «mycommits» que se creo en este ejemplo y no puedo, al agregar otro archivo a mi repositorio local siguiendo los pasos :
git add «miFichero»
Luego
git commit -m «Nuevo commit»
Luego
git push origin master
Y por último quisiera hacer otro pull request hacia el repositorio original pero con la misma rama(mycommits)
pero me aparece un mensaje diciéndome que no hay nada para enviar.
git push -u origin mycommits
Entonces, he creado otra rama para poder hacer otro pull request y si me funciono. Ahi está mi duda :
Es necesario crear ramas para cada commit que se pretender enviar al repositorio original?
Saludos
Hola Miguel Ángel:
Gracias por el feedback y por tu comentario.
Primera pregunta
Tengo la impresión de que estás haciendo push de la rama que no es. Según me cuentas has hecho los commits a la rama «mycommits», sin embargo, el comando push que estás utilizando es
# git push origin master
Para enviar un pull request de la rama «mycommits» debes subir esa rama a github lo que significa de debes hacer push de esa rama:
# git checkout mycommits
# git push origin mycommits
(si quieres crear a la vez un tracking brach puedes utilizar el comando git push -u origin
mastersmycommits)Segunda pregunta
Si ya hiciste un pull request de la rama «mycommits» y ese pull request está abierto… no creo que sea buena idea hacer otro pull request de esa misma rama, dependiendo de la situación puede que no tenga sentido. Lo que se suele hacer en estos casos es enviar los commits nuevos a tu rama remota «mycommits». Github automáticamente los detecta y los pone en el pull request que ya estaba creado. De esta forma se puede hacer code review e ir mejorando el código antes de incorporarlo.
Si me envías un pull request al repositorio «fork» que he creado, verás que no te aceptaré el pull request hasta que hagas exactamente lo que me estás preguntando (si miras en el repo mío verás varios pull request que no están cerrados por que no me enviaron un segundo commit 😉 ).
Sobre lo que comentas de que al hacer «git push origin mycommits» te dice que no hay nada que enviar ¿en qué rama estás? ¿es «mycommits» la rama activa»? si es así, comprueba que los commits los hiciste en esa rama y no en otra por error (suele ser uno de los motivos más habituales de ese mensaje que te está saliendo).
Un saludo,
Alfonso
¡¡Muchas gracias!! Visto así con ejemplos es mucho más sencillo de entender.
¡Un saludo!
¡De nada¡ Me alegro de que te lo hayas entendido.
Un saludo
Pingback: Colaborando con el software libre, CakePHP | proavan
Entiendo la idea de crear un fork para colaborar con otro proyecto pero me podrías explicar en que se diferencia de clonar el proyecto, crear un branch, hacer los cambios en este branch y luego hacer un pull request para que el propietario del proyecto original haga un merge e incorpore los cambios al proyecto?
Es decir, ¿Por qué hacerlo con un fork y no con un branch?
Gracias. Muy aclarador, no es fácil con tantos términos.
Entiendo que el hecho de crear el repositorio Upstream desde el cual pedir el Pull Request es para que en el repositorio original no aparezcan todos los commits «viejos» del usuario, no? Es decir, para mandar una copia limpia con un solo commit (si no hay más cambios luego).
Saludos.
Genial, no se como he perdido todo mi tiempo estos ultimos años usando SVN. Muchas gracias, gran aporte
Gracias por el aporte, me ha ayudado mucho!
Muchas gracias por el aporte, muy claro y sumamente útil.
Pingback: Mejora tu código en 5 pasos - Testeando Software
Pingback: ¿Cómo puede ayudarnos Github con sus nuevas funcionalidad para trabajar en equipo? | Esther Claravalls
Pingback: ¿Cómo puede ayudarnos Github con sus nuevas funcionalidades a trabajar en equipo? – Educacion IT
Pingback: Aprendiendo a aprender – Ciencia Moe
Pingback: Librerías Arduino | Aprendiendo Arduino
Pingback: Prácticas profesionales Open Source
Muchas gracias. Maravillosa explicación.
Muy buen tutorial, ,me ha dejado muchas cosas claras a pesar que soy nuevo en GIT, lo que no me cuadra es de donde sale la rama «upstream». Muchas gracias de antemano.
Esta serie al parecer es inmortal. Más de 5 años después puedo decirte que me has ayudado mucho. Gracias.
Yo empecé a trabajar en una empresa de informática pequeña y me tomaron sin saber nada de versionado. Con mucho esfuerzo aprendi. Lo primero que te marea es tantos terminos nuevos.
Hola, cuando le doy «send pull request» me dice que «Merging is blocked The base branch restricts merging to authorized users. Learn more about protected branches.» Qué debo hacer? Le debo dar en «Close pull request» o debo esperar a que los dueños del repo origial aprueben el pull? o quedó mal hecho el pull request? Muchas graicas, bastante explicativo el post.
Pingback: ¿Qué hay de nuevo en Visual Studio 2019? | campusMVP.es
Muy bien explicado.
Muchas gracias por la explicación 🙂
hola, muchas gracias por el tutotial.
pero me queda una duda: cual es la diferencia entre hacer un merge request y un pull request? este ultimo es solo asociable a los fork?
gracias!
Hola Clau:
No hay ninguna diferencia, es sólo una diferencia de nombre. Gitlab lo llama «merge request» y github / bitbucket lo llaman «pull request».
Y en respuesta a tu segunda pregunta, no, no es obligatorio usar forks para hacer un pull request.
Por favor, tratar de no usar tanto extranjerismo crudo, que el artículo de esta forma da hasta repelús
[Un pull request es una petición que el propietario de un fork de un repositorio]
Para empezar, el extranjerismo crudo se escribe en cursiva, y hay que tratar de evitarlo siempre que sea posible.
Si se quiere hacer referencia a una función en inglés escribirle en cursiva y a partir de ahí seguir con bifurcación etc. que tenemos un español muy rico.
Gracias por su atención.
hola SVA:
Lamento que el artículo te de repelús, la verdad es que esta serie de artículos sobre pull requests es la que mejores comentarios ha recibido de todo el blog. Gracias por enseñarme que el extranjerismo se escribe en cursiva, lo tendré en cuenta cuando escriba en el futuro.
Un saludo,
Alfonso
Aquí en 2022 y pandemia en el mundo, ¿Qué aplicación visual usas para la gestión de GitHub?
Hola Jose Israel:
La verdad es que para la gestión GitHub utilizo la web como aplicación visual, aunque siempre que puedo utilizo el comando gh (https://cli.github.com/) Hubo una temporada que probé GitHub Desktop, hace unos años ya (https://desktop.github.com/) pero no me enganchó y no la he usado casi.