AprendeGit
Capítulo 6 15 min de lectura 6 secciones

Trabajando con Git de forma remota

Repositorios remotos: clonar, enlazar, pull, push y ramas remotas.

Hasta ahora hemos visto cómo podemos trabajar con repositorios locales. Esto quiere decir que los cambios se quedan en nuestro ordenador yotras personas no pueden verlos. Aunque esto puede tener cierta utilidad, esto no es lo que queremos.

Para que un equipo de personas pueda colaborar en un mismo código base, se necesita una forma de comunicar los cambios entre ellos. Y estolo logramos con los repositorios remotos.

Los repositorios remotos son repositorios que están hospedados en un servidor y que servirá de punto de sincronización entre diferentes repositorios locales.

Se puede crear y levantar tu propio servidor de Git para lograr esto pero en este curso vamos a enfocarnos a lograr esto usando GitHub.

GitHubes el proveedor de repositorios en la nube para hospedar código fuente más utilizado en la actualidad, especialmente en el mercado occidental.

Los repositorios remotos no están en nuestra máquina. Están hospedados en un servidor externo pero podremos sincronizar nuestros cambios cuando queramos.

Creando un repositorio remoto en GitHub

Como hemos dicho antes, vamos a usarGitHubpara crear nuestro primer repositorio remoto. Es completamente gratisy nos permite crear un número ilimitado de repositorios, tanto públicos como privados.

AunqueGitHubes actualmente el servicio de hospedaje de repositorios remotos más utilizado, existen otras alternativas igual de válidas como GitLaboBitBucket (ambos compatibles con Git). https://about.gitlab.com/https://bitbucket.org/

Para crear un nuevo repositorio remoto en GitHub accede a la página
https://repo.new/.

Al acceder te pedirá tus credenciales para poder continuar. Si tienes una cuenta ya creada, podrás iniciar sesión con ella. De lo contrario, créate una cuenta para poder continuar.

Una vez que hayas creado tu cuenta, podrás crear un repositorio nuevo y te aparecerá esta pantalla:

En esta pantalla podremos crear nuestro repositorio remoto
  1. Es el dueño del repositorio. Por defecto aparece tu cuenta de usuario pero también podemos crear organizaciones que sean dueñas de repositorios. 2. El nombre del repositorio. Este nombre será el que aparezca en la URL del repositorio y el que usaremos para poder acceder a él más adelante. El nombre debe ser único entre los repositorios que ya tengamos pero no entre todos los que existen en GitHub. 3. Una descripción cortasobre qué trata el repositorio. 4. El tipo de visibilidad del repositorio. Puedes elegir entre público o privado. Ten en cuenta que si es público, cualquier persona podrá descubrir el repositorio, ver su código e incluso intentar contribuir. Si no quieres que nadie pueda verlo, ponlo en privado (puedes cambiarlo más adelante). 5. Puedes iniciar tu repositorio con un archivo llamadoREADME.mdque contenga una breve descripción del repositorio. También puedes añadir desde el inicio un archivo.gitignorepara evitar hacer seguimiento de archivos que no quieres que se suban al repositorio y añadir una licencia para determinar qué uso puede hacerse del código. 6. Cuando ya lo tengas todo preparado, es hora de darle aCreate Repository.

Por favor, no descuides seleccionar una licencia. Si no seleccionas ninguna significa que el código que subes, aunque visible, tiene todos los derechos reservados. Por lo tanto, nadie podría modificar ni redistribuir el código sin tu permiso explícito. Igual es lo que quieres, pero lo ideal es que tengas una licencia en tu repositorio para evitar un malentendido. ¿Te interesa saber cómocrearunrepositorioremotodesdelalíneadecomandos? ¡Se puede! Revisa la sección sobre GitHub CLI del curso, que te explico cómo.

Clonando un repositorio remoto ya creado previamente

Imagina que ya existe un repositorio remoto creado y quieres trabajar con él en tu ordenador. ¿Cómo puedes crear un repositorio local en tu ordenador con los ficheros y ramas del repositorio remoto para poder trabajar con él?

A esta acción se le llamaclonar. Se llama así porque, literalmente, lo que hacemos es una copia exacta del repositorio remoto en nuestra máquina. Todo el historial de commits y todas las ramas son descargadas en nuestro ordenador. Recuerda que, como ya hemos comentado anteriormente,Git es un sistema distribuido, lo que significa que podemos tener copias completas de los repositorios en diferentes lugares y sincronizarlos entre ellos.

Para clonar un repositorio remoto necesitamos saber su dirección. Esta dirección puede ser su direcciónHTTPSoSSH. Normalmente, la forma preferida, debería ser usando SSH.

Primero pulsas el botón Code. En el diálogo, selecciona SSH si no está ya activado. Después, pulsa el icono del lateral para que se copie la dirección en tu portapapeles

Ahora que tenemos la dirección, es el momento de usar el comando git clonepara clonar el repositorio remoto en nuestra máquina.

# Para clonar un repositorio remoto con la dirección SSH
$ git clone git@github.com:tu-usuario/libro-javascript.git

Cloning into ‘libro-javascript’… remote: Enumerating objects: 12 , done. remote: Counting objects: 100 % ( 12 /12), done. remote: Compressing objects: 100 % ( 7 /7), done. remote: Total 12 (delta 2 ), reused 3 (delta 0 ), pack-reused 0 Receiving objects: 100 % ( 12 /12), done. Resolving deltas: 100 % ( 2 /2), done.

# Para clonar un repositorio remoto con la dirección HTTPS
$ git clone https://github.com/tu-usuario/libro-javascript.git

Repasemos un poco el resultado de ejecutar esta línea:

  1. Hemos ejecutado el comando git cloney le hemos indicado que queremos clonar el repositorio situado en git@github.com:tu-usuario/libro-javascript.git (dirección SSH). 2. Git ha clonado el repositorio remoto en nuestro ordenador. Ha creado una carpetalibro-javascripten el lugar de la línea de comandos que nos encontrábamos. 3. En esa carpeta, se ha creado una copia del repositorio remoto que, ahora, es un repositorio local. 4. En el repositorio local ha dado nombre a una carpeta llamada.gitque contiene toda la información sobre el repositorio (versiones, commits, ramas…) 5. Nos ha dejado un directorio de trabajo listo con la rama principal, listas para ser usada.

Por defecto al clonar un repositorio se crea una carpeta con el mismo nombre que el repositorio remoto. Si quieres que el nombre de la carpeta sea diferente puedes indicarlo:

# clonamos el repositorio tu-usuario/blog

git clone git@github.com:tu-usuario/blog.git blog-tu-usuario

¿NotienesconfiguradalallaveSSHparatuordenador?¡No te preocupes! Tienes un capítulo completo del curso llamadoConfigurando la conexión SSH con GitHubque te puede guiar paso a paso para que lo hagas y entiendas qué es y cómo funciona la autenticación de SSH. Aunque a la hora de explicar la clonación de repositorios nos hemos enfocado en repositorios remotos, debes saber que también puedes usar git clonepara clonar un repositorio local a otro destino. Noesmuyusadopero a veces queremos trabajar con el mismo repositorio en dos directorios de trabajo y hacerlo puede ayudarte.

¿Cómo enlazar un repositorio local con un repositorio remoto?

A veces empezamos un desarrollo con un repositorio local y luego, más adelante, queremos subir nuestro código al repositorio remoto. Para ello, tenemos que hacer una sincronización entre los dos repositorios.

Para conectar nuestro repositorio local con el repositorio remoto debemos usar el comando git remote addy le pasaríamos dos parámetros. El primero sería el alias del repositorio remotoy el segundo seríala dirección del mismo repositorio remoto. Sería algo así:git remote add <dirección>.

Comoaliaspodemos usar cualquier nombre que queramos, pero por defecto usamos originpara indicar que el repositorio remoto que estamos sincronizando es el remoto principal.

Sobrela dirección del repositorioremoto… Si has seguido los pasos anteriores para crear un repositorio remoto, habrás llegado a una pantalla similar a esta:

Cada vez más, GitHub está utilizando las direcciones SSH por defecto. Por ello, es buena idea que siempre intentes utilizar estas

De esta forma, para añadir un repositorio remoto a nuestro repositorio local, tenemos que ejecutar:

# añadimos como origin la dirección ssh del repositorio remoto
$ git remote add origin git@github.com:tu-usuario/my-awesome-new-repo.git

Ten en cuenta que un repositorio local, en realidad, puede tener enlazados tantos repositorios remotos como queramos. Normalmente sólo será uno, como en este caso, pero más adelante veremos que es útil tener también otros repositorios

remotos en algunos casos.

Para saber qué repositorios remotos tiene enlazados nuestro repositorio local, podemos ejecutar el comando git remote:

# con -v conseguimos una salida más detallada
git remote -v

origin git@github.com:tu-usuario/my-awesome-new-repo.git (fetch)
origin git@github.com:tu-usuario/my-awesome-new-repo.git (push)

Traer los cambios del repositorio remoto a mi repositorio local

Cuando trabajamos en equipo, es muy común que haya cambios en el repositorio remoto que no tenemos en nuestro repositorio local. Para traer esos cambios a nuestro repositorio local, tenemos que ejecutar el comando git pully le pasaremos dos parámetros:

  • El primer parámetro sería elaliasdel repositorio remoto.
  • El segundo sería el nombre de la rama sobre la que queremos traer los cambios.

Por ejemplo, para traer los cambios del repositorio remotooriginy la rama main, deberíamos ejecutar lo siguiente:

# traemos los cambios del repositorio remoto

$ git pull origin main

From github.com:tu-usuario/miduconf-website * branch main -> FETCH_HEAD Auto-merging src/components/Principal.astro Merge made by the ‘ort’ strategy. src/components/Principal.astro | 27 +++++- …/logos/PlainConcepts.astro | 61 ++++++++++---- src/global.css | 20 +++++ 3 files changed, 92 insertions(+), 16 deletions(-)

¿Qué pasa si hay conflictos?

A veces, cuando hacemos un git pullnos encontramos con que hay conflictos entre los cambios que tenemos en nuestro repositorio local y los cambios que hay en el repositorio remoto. Esto puede ocurrir por varias razones:

  • Hemos hecho cambios en el mismo archivo que alguien ha modificado, en las mismas líneas. - Hemos eliminado un archivo que alguien ha modificado. - Hemos creado un archivo y alguien ha creado otro con el mismo nombre.

Sea como sea, en este punto,Git no sabe qué hacery nos deja elegir qué cambios queremos conservar. Para ello, debemos resolver los conflictos manualmente y luego hacer un git addy un git commitpara que los cambios queden reflejados en nuestro repositorio local.

En la sección deRamastienes una sección completa donde te explico cómo resolver conflictos.

La estrategia de merge por defecto

Desde la versión 2.27.0 de git cuando hacemos un git pull te muestra una advertencia si no tienes configurada qué estrategia debe seguir el comando a la hora de traer los cambios del repositorio remoto.

Esto es porque antes de esta versión, la estrategia de merge por defecto era hacer un mergesi no se podía hacer unfast-forward. A partir de ahora, debemos indicar nosotros qué estrategia queremos que sigagitpara traer los cambios del repositorio remoto.

$ git pull origin main

From github.com:tu-usuario/miduconf-website
* branch main -> FETCH_HEAD
hint: You have divergent branches and need to specify how to reconcile
them.
hint: You can do so by running one of the following commands sometime b
efore
hint: your next pull:
hint:
hint: git config pull.rebase false # merge
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
hint:
hint: You can replace "git config "with "git config --global "to seta
default
hint: preference for all repositories. You can also pass --rebase, --no
-rebase,
hint: or --ff-only on thecommand line to override the configured defau
lt per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.

Como ves, tenemos tres opciones:

  • git config pull.rebase falsepara hacer unmergecuando no se pueda hacer unfast-forwardde la rama remota en nuestro repositorio local. - git config pull.rebase truepara hacer unrebasecuando no se pueda hacer unfast-forwardde la rama remota en nuestro repositorio local. - git config pull.ff onlypara que sólo acepte unfast-forwardal traer los cambios, de lo contrario nos dará un error.

Cualquiera de las tres opciones es válida. Si no quieres complicarte, puedes usar la primera, ya que es la que se comporta como antes de la versión 2.27.0 de git. Si quieres que tu historial decommitssea más limpio, puedes usar la segunda opción. Y si quieres tener más control sobre lo que está pasando, puedes usar la tercera opción.

Recuerda que puedes adoptar una estrategia de merge o rebase para todos tus repositorios o para cada uno de ellos de forma independiente usando la opción —globalo no. Esto dependerá de tus preferencias.

Escribiendo en el repositorio remoto

git pushes un comando que permite enviar los cambios de un repositorio local a un repositorio remoto. Para ello, tenemos que ejecutar el comando git pushy le pasaríamos dos parámetros:

  • El primer parámetro sería elaliasdel repositorio remoto.
  • El segundo sería el nombre de la rama sobre la que queremos enviar los cambios.

Por ejemplo, para enviar nuestroscommitsal repositorio remotooriginy la rama main, deberíamos ejecutar lo siguiente:

# subimos los cambios del repositorio local

$ git push origin main

Esto hará que nuestros cambios locales se reflejen en el repositorio remoto y otras personas podrán verlos y sincronizar sus repositorios locales para trabajar con ellos.

Más adelante veremos cómo podemos enviar una rama distinta a la principal. Por ahora no nos preocuparemos por ello.

¡No me deja hacer push! Me dice que ha sido rechazado

Como hemos visto en Git tenemos por un lado repositorios locales y remotos. Cuando hacemos push, estamos intentando llevar nuestros cambios locales a un repositorio remoto para grabarlos pero a vecespuede arrojarnos un error en el que dice que ha rechazado la actualización.

Normalmente esto ocurre porque nuestro repositorio local no tiene cambios que han ocurrido en el repositorio remoto. Estos cambios pueden ser nuevoscommitso que el historial de cambios de la rama han cambiado (se ha sobrescrito el historial).

El error en cuestión se vería así:

$ git push origin main

To https://github.com/tu-usuario/my-repo.git ! [rejected] main -> main(non-fast-forward) error: failed to push some refs to’https://github.com/tu-usuario/my-repo.\ git’ hint: Updates were rejected because the tip of your current branch is b ** ehind hint: its remote counterpart. Integrate the remote changes (e.g. hint: ‘git pull …’) before pushing again. hint: See the’Note about fast-forwards’ in ‘git push —help’ for detai ** ls.

Aunque podrías usar el parámetro-fpara forzar elpushy saltar este error, esmejor no hacerlo si no sabes por qué estás teniendo este problema.

En realidad el propio error ya nos da la explicación de por qué no se ha podido enviar el cambio: tu repositorio local no tiene cambios que han ocurrido en el repositorio remoto.

Además, nos da una posible solución: tenemos que integrar los cambios del repositorio remoto en nuestro repositorio local con git pullantes de poder enviar los cambios.

¿Por qué pasa esto? Básicamente el historial que tienes en tu repositorio local es, actualmente, incompatible con el remoto. Lo podríamos ver en este ejemplo:

A -- B -- C -- D(repositorio remoto)
A -- B -- E (tu repositoriolocal)

Tu repositorio local no tiene los commitsCyDy, por lo tanto, al intentar enviar E… ¿cómo lo podría hacer? Cuando el commit modifica ficheros que ya han sido modificados en commits que te faltan, Git dejaría el repositorio remoto con conflictos porque es incapaz de saber cómo tiene que solucionar esas divergencias. Piensa que conflictos sólo pueden existir en repositorios locales, así que tiene que sincronizar los cambios localmente, arreglar los conflictos que existan y entonces subirlos al remoto, donde ya no existirá ningún conflicto.

Trabajando con ramas en remoto

Llevar cambios locales al repositorio remoto está muy bien pero no vamos a querer hacerlo siempre directamente contra la rama principal. Lo que vimos en la sección deRamasnos va a servir también aquí pero, esta vez, para trabajar en remoto.

Creando una rama remota

Para crear una rama remota, sólo tenemos que crear la rama en nuestro repositorio local y luego enviarla al repositorio remoto.

# Creamos una rama en el repositorio local
$ git switch -c website
Switched to a new branch 'website'

# Enviar la rama a nuestro repositorio remoto

$ git push origin website

Total 0 (delta 0 ), reused 0 (delta 0 ), pack-reused 0 remote: remote: Create a pull request for ‘website’on GitHub by visiting: remote: https://github.com/tu-usuario/manual-git/pull/new/website remote: To github.com:tu-usuario/manual-git.git * [new branch] website -> website

# Ten en cuenta que si intentas enviar una rama

$ git push origin rama-que-no-existe

error: src refspec rama-que-no-existe does not match any
error: failed to push some refs

Como ves tenemos un mensaje sobre crear unaPull Request. Lo ignoramos por ahora, pero más adelante explicamos esto en detalle.

Ya tenemos nuestra rama en el repositorio remoto. Ahora, podemos empezar a crear commits en nuestro repositorio local y enviarlos al repositorio remoto a la rama que hemos creado.

# Revisamos que estamos de forma local en la rama
$ git branch --show-current
# Creamos tres archivos vacíos

$ touch index.html styles.css app.js
$ git add index.html
$ git commit -m "Add index.html"
$ git add styles.css
$ git commit -m "Add styles"
$ git add app.js
$ git commit -m "Add JavaScript"
# Enviamos los cambios a la rama remota
$ git push origin website

Enumerating objects: 4 , done. Counting objects: 100 % ( 4 /4), done. Delta compression using up to 10 threads Compressing objects: 100 %( 2 /2), done. Writing objects: 100 % ( 3 /3), 276 bytes | 276 .00 KiB/s, done. Total 3 (delta 1 ), reused 1 (delta 0 ), pack-reused 0 remote: Resolving deltas: 100 % ( 1 /1), completed with 1 local object. To github.com:tu-usuario/manual-git.git 39af206..2bd2e0b website -> website

Integrando cambios en otra rama

Una vez que hemos terminado de trabajar en nuestra rama, vamos a querer integrar los cambios en la rama principal. Tenemos diferentes formas de hacerlo pero vamos a ver las dos más habituales: haciendo elmergeen local y enviar los cambios al repositorio remoto o enviando una pull request.

Integrando los cambios localmente y enviándolos

Para integrar los cambios de una rama en otra, tenemos que hacer unmergede la rama que queremos integrar en la rama principal. En nuestro caso, la ramawebsite en la rama main.

# Volvemos a la rama principal
$ git switch main
Switched to branch 'main'

# Integrar los cambios de la rama website

$ git merge website
Updating 39af206..2bd2e0b
Fast-forward
index.html | 0
styles.css | 0
app.js | 0
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 index.html
create mode 100644 styles.css
create mode 100644 app.js

# Enviar los cambios a la rama principal
$ git push origin main

Nota: Si intentas hacer unmergede una rama que no está actualizada con la rama principal, Git te dará un error. Para solucionarlo, tendrás que actualizar la rama que quieres integrar con la rama principal. Existe otro comando para integrar cambios de una rama en otra:git rebase. En este caso, no se crea un commit demergesino que se crean los commits de la rama que queremos integrar en la rama principal. Tienes un capítulo completo dedicado aRebasemás adelante.

Integrando los cambios con una Pull Request

Otra forma de integrar los cambios de una rama en otra es enviando unaPull Requestdesde el repositorio remoto. Esto es muy útil cuando trabajamos en equipo y queremos que otra persona revise los cambios que hemos hecho antes de integrarlos en la rama principal.

A lasPull Requestse las abrevia en ocasiones comoPR. Es posible que encuentres esa notación también en el curso.

Para lograrlo debes haber enviado desde tu repositorio local la rama que quieres integrar en la rama principal. En nuestro caso, la ramawebsite.

# Enviamos los cambios locales de la rama 'website'

$ git push origin website

En GitHub se le llamaPull Requesta la petición de integrar cambios de una rama en otra. Este nombre puede cambiar en otros hostings de código. Por ejemplo, en

GitLab se le llamaMerge Request.

Para enviar unaPull Requestdesde GitHub, tenemos que ir a la página de nuestro repositorio y seleccionar la rama que queremos integrar en la rama principal.

Al entrar al repositorio remoto en GitHub, nos aparecerá un banner que nos indica que una rama ha recibido cambios. El punto 1 nos indica la rama que ha sido actualiza recientemente, el punto 2 es el botón que podemos pulsar para iniciar el proceso de “Pull Request”

Si pulsamos el botón deCompare & pull request, nos aparecerá una página donde podemos seleccionar la rama principal con la que queremos integrar los cambios.

Una vez que hemos seleccionado la rama, nos aparecerá una página con los cambios que se van a integrar en la rama principal. Si estamos de acuerdo con los cambios, podemos hacer clic en el botónCreate pull request.

Nos abrirá una nueva página donde podemos añadir un título y una descripción a la pull request. Una vez que hemos terminado, podemos hacer clic en el botónCreate pull request.

El punto 1 indica el destino de la petición de cambios (donde queremos añadir los cambios de la rama). El punto 2 es la rama que queremos fusionar. Recuerda dejar un buen título y descripción en los puntos 3 y 4. Y finalmente, pulsamos 5 para hacer la PR.

Una vez que hemos enviado la pull request, podemos esperar a que otra persona revise los cambios. En ese punto se puede iniciar una conversación con comentarios, peticiones de cambios, bloquear la pull requesto aceptarla.

Si se acepta, finalmente, se debe pulsar el botón deMerge pull requestpara integrar los cambios en la rama de destino.

Así queda nuestra Pull Request. Si finalmente queremos integrar los cambios en la rama de destino, en este caso la rama ‘main’, entonces le daremos al botón que señalamos en la imagen

¿Terminaste de leer la teoría?

Márcalo para registrar tu avance y salta al quiz.

Quiz de comprobación

3 preguntas · 70% para aprobar
  1. 1

    Tienes un repo local y creaste uno vacío en GitHub. ¿Cómo los enlazas?

  2. 2

    ¿Qué hace `git clone https://github.com/tu-usuario/repo.git`?

  3. 3

    ¿Para qué sirve el flag -u en `git push -u origin main`?

Laboratorio guiado

terminalgit · LIVE
$