Aquí es donde Git deja de ser una herramienta personal. Un pull request es la forma en que millones de personas mejoran proyectos que no son suyos, y también es la forma en que trabaja cualquier equipo por dentro 🤝
Y la palabra asusta más que la cosa. Traducida es: "te dejé unos cambios listos, ¿te los llevas?".
Fork y clone no son lo mismo
| Fork | Clone | |
|---|---|---|
| Dónde queda la copia | En tu cuenta de GitHub | En tu computadora |
| Es de | GitHub, no de Git | Git |
| Puedes subir cambios | Sí, es tuya | Solo si tienes permiso en el original |
| Para qué | Proponer cambios en algo ajeno | Trabajar en tu máquina |
El orden real es: fork primero, clone después. Clonas tu copia, no la original 🍴
Los cuatro pasos, con la parte de Git ejecutada
El fork es un botón en GitHub. Todo lo demás es esto, y lo vamos a hacer con el servidor de práctica del capítulo 12: uno hace de proyecto original y otro de tu bifurcación.
mkdir original cd original git init -q printf 'ciudad,monto\nLima,1200\nArequipa,890\n' > ventas.csv printf '# Ventas por ciudad\n' > README.md git add . git commit -q -m "Primera version del reporte de ventas" cd .. git clone -q --bare original original-servidor.git git clone -q --bare original mi-fork.git git clone -q mi-fork.git mi-copia cd mi-copia git remote add upstream ../original-servidor.git git remote -v
origin /home/miss-yera/mi-fork.git (fetch) origin /home/miss-yera/mi-fork.git (push) upstream ../original-servidor.git (fetch) upstream ../original-servidor.git (push)
Dos remotos y esto es la costumbre del mundo entero: origin es
tu bifurcación, donde sí puedes subir, y upstream es el proyecto
original, de donde traes las novedades 🔀
Una rama por propuesta
Este es el paso que la gente se salta y el que más problemas causa después:
git switch -q -c agrega-cusco printf 'Cusco,760\n' >> ventas.csv git add ventas.csv git commit -q -m "Se agregan las ventas de Cusco" git branch git log --oneline
* agrega-cusco main ef5f2ea Se agregan las ventas de Cusco b566789 Primera version del reporte de ventas
El nombre de la rama importa porque va a ser el título por defecto de tu
propuesta. agrega-cusco se entiende; cambios o
arreglo2 no 🏷️
Subirla a tu bifurcación
git push -q -u origin agrega-cusco git ls-remote --heads origin
ef5f2eae2ffecc668ba6580b0ab2be76c29de0ef refs/heads/agrega-cusco b56678907174a8d5cecfb72ae67a3e90a2f1beb6 refs/heads/main
Ahí está tu rama en tu copia de GitHub. Al entrar a la web te va a salir sola una barra amarilla que dice "Compare & pull request". Ese es el único clic obligatorio del capítulo 🖱️
Qué escribir en la propuesta
Tres cosas, cortas:
- Qué cambia, en una frase.
- Por qué, sobre todo si no es obvio.
- Cómo comprobarlo, si hace falta ejecutar algo.
Y si el proyecto tiene un archivo CONTRIBUTING.md, léelo antes.
Ahí está lo que quien mantiene el proyecto ya se cansó de repetir.
Ver exactamente lo que estás proponiendo
Antes de abrir el pull request conviene mirar tu propio cambio con los ojos de quien lo va a revisar:
git diff main..agrega-cusco git log --oneline main..agrega-cusco
diff --git a/ventas.csv b/ventas.csv index 0c80877..7a40551 100644 --- a/ventas.csv +++ b/ventas.csv @@ -1,3 +1,4 @@ ciudad,monto Lima,1200 Arequipa,890 +Cusco,760 ef5f2ea Se agregan las ventas de Cusco
Eso, exactamente eso, es lo que va a ver la otra persona. Si ahí aparece algo que no querías mandar, ahora es el momento 👀
Cuando el original avanza mientras esperas
Los pull requests tardan. Mientras tanto el proyecto sigue, y hay que traer lo nuevo para que tu propuesta no envejezca:
cd ../original printf 'Trujillo,1450\n' >> ventas.csv git add ventas.csv git commit -q -m "Entran las ventas de Trujillo" git push -q ../original-servidor.git main cd ../mi-copia git fetch -q upstream git switch -q main git merge -q upstream/main cat ventas.csv git log --oneline
ciudad,monto Lima,1200 Arequipa,890 Trujillo,1450 c0dd365 Entran las ventas de Trujillo b566789 Primera version del reporte de ventas
fetch trae sin mezclar, merge mezcla. Tu
main vuelve a estar al día con el original 🔄
La trampa
Quieres proponer un arreglo en un proyecto ajeno. Lo bifurcas, clonas, arreglas el CSV de ventas ahí mismo y abres el pull request.
$ git branch * main $ git commit -am "Se corrige el monto de Lima" $ git push origin main # y al dia siguiente, otro arreglo distinto... $ git commit -am "Se agrega Chiclayo" $ git push origin main
Qué está mal
Los dos cambios están dentro del mismo pull request 🙃
Un pull request no es una lista de commits que tú eliges: es todo lo que tenga esa rama. Si trabajas en main, cada cosa nueva que subas se mete sola en la propuesta abierta, aunque no tenga nada que ver.
Quien revisa se encuentra un arreglo de un monto mezclado con una ciudad nueva y no puede aceptar uno sin el otro. Casi siempre acaba pidiendo que lo separes, o sea que el atajo costó más tiempo.
La costumbre: una rama por propuesta, con nombre de lo que hace, y main se queda limpia para poder empezar la siguiente desde ahí.
Comprueba que se entendió
Comprueba que lo tienes
Vas a proponer un arreglo en un proyecto que no es tuyo. ¿Dónde haces el commit?
- En
mainde mi bifurcación - En una rama nueva de mi bifurcación
- En
maindel proyecto original - Da igual, el pull request los separa
Ejercicios
1. Monta el original y tu bifurcación
Crea el proyecto del catálogo de bodegas, publícalo y haz tu copia.
cd .. mkdir catalogo cd catalogo git init -q printf 'bodega,ciudad\nBodega Inti,Cusco\n' > bodegas.csv git add bodegas.csv git commit -q -m "Catalogo inicial de bodegas" cd .. git clone -q --bare catalogo catalogo-servidor.git git clone -q --bare catalogo fork-bodegas.git git clone -q fork-bodegas.git trabajo cd trabajo git remote add upstream ../catalogo-servidor.git git remote -v
origin /home/miss-yera/fork-bodegas.git (fetch) origin /home/miss-yera/fork-bodegas.git (push) upstream ../catalogo-servidor.git (fetch) upstream ../catalogo-servidor.git (push)
origin es tuyo, upstream es de la otra persona.
2. Crea la rama de tu propuesta
Una rama con nombre de lo que hace.
git switch -q -c agrega-minimarkets printf 'Minimarket Sol,Trujillo\n' >> bodegas.csv git add bodegas.csv git commit -q -m "Se agrega el minimarket de Trujillo" git branch
* agrega-minimarkets main
El asterisco marca dónde estás parada.
3. Mira lo que vas a proponer
El diff contra main es exactamente lo que
verá quien revise.
git diff main..agrega-minimarkets
diff --git a/bodegas.csv b/bodegas.csv index 9fe9605..d3027d2 100644 --- a/bodegas.csv +++ b/bodegas.csv @@ -1,2 +1,3 @@ bodega,ciudad Bodega Inti,Cusco +Minimarket Sol,Trujillo
Una línea agregada y nada más. Así se ve una propuesta limpia ✨
4. Súbela a tu bifurcación
Manda la rama a origin, que es tu copia.
git push -q -u origin agrega-minimarkets git ls-remote --heads origin
a9a0491c4de4c36c7b7cc8adea3385832f96b850 refs/heads/agrega-minimarkets a9874ae5ade9ebff480ec9f29629b1b651573849 refs/heads/main
Dos ramas allá: la original y la tuya.
5. Trae lo nuevo del original
El proyecto avanzó mientras esperabas. Ponte al día.
cd ../catalogo printf 'ciudad,monto\nLima,1200\n' > ciudades.csv git add ciudades.csv git commit -q -m "Entra el corte por ciudad" git push -q ../catalogo-servidor.git main cd ../trabajo git fetch -q upstream git switch -q main git merge -q upstream/main ls
bodegas.csv ciudades.csv
El archivo nuevo del original ya está en tu main, y tu rama
sigue intacta.
6. Actualiza tu propuesta
Lleva lo nuevo a tu rama para que la propuesta no envejezca.
git switch -q agrega-minimarkets
git merge -q main
ls
cat bodegas.csv
git log --oneline -3
bodegas.csv ciudades.csv bodega,ciudad Bodega Inti,Cusco Minimarket Sol,Trujillo bc33316 Merge branch 'main' into agrega-minimarkets a9a0491 Se agrega el minimarket de Trujillo b648c87 Entra el corte por ciudad
El corte por ciudad y tu minimarket conviven. La propuesta sigue siendo tuya y está al día.
7. Intenta subir al proyecto original
Prueba a mandar tu rama a una dirección que no existe, que es lo que pasa cuando escribes mal el remoto.
git push otro-remoto agrega-minimarkets
fatal: 'otro-remoto' does not appear to be a git repository fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
Git no inventa destinos: si el apodo no está configurado, se planta 🛑
Lo que te llevas
Fork, clone, rama, push y un clic. Y una rama por propuesta, siempre.