Saltar a contenido

Orígenes remotos

En esta sección abordaremos la manera de gestionar nuestros orígenes remotos (es decir, repositorios remotos) para posteriormente sincronizar el contenido de los mismos con nuestro repositorio local y viceversa.

Gestionando orígenes remotos

La mayoría de las acciones de Git se efectúan de manera local, en la máquina del cliente. Sin embargo, es posible sincronizar los archivos de nuestro repositorio local con un repositorio remoto.

Repositorios remotos

Existen varios proveedores de repositorios remotos de git. Entre los más populares se encuentran:

- [Bitbucket](https://bitbucket.org)
- [GitHub](https://github.com)
- [GitLab](https://gitlab.com)

Agregando origen remoto

En caso de haber iniciado un repositorio git de manera local, éste no tendrá vinculación con ningún repositorio remoto. Si quisiéramos sincronizar nuestro repositorio local con uno remoto:

git remote add <nombre-del-repositorio-remoto> <url-del-repositorio-remoto>

Por ejemplo, para agregar un repositorio repositorio remoto [HTTPS]:

git remote add origin https://gitlab.com/la9una/redes.git

Donde:

  • origin es el nombre habitual con el que se refiere a un repositorio remoto (puede ser cualquier otro)
  • https://gitlab.com/la9una/redes.git el la dirección URL del repositorio remoto

Repositorios clonados desde un repositorio remoto

En caso que hayamos clonado un repositorio remoto, éste ya tendrá configurado un origen remoto.

Visualizando origen remoto

Para ver los remotos que tenemos configurados, debemos ejecutar:

git remote -v

Si tenemos más de un origen remoto, el comando los listará todos.

Modificando orígen remoto

Podemos cambiar tanto el nombre como la URL del origen remoto que tengamos configurado en nuestro repositorio.

Nombre del origen remoto

La sintaxis del comando necesario para cambiar el nombre de un remoto (alias) es la siguiente:

git remote rename <antiguo-nombre-repositorio-remoto> <nuevo-nombre-repositorio-remoto>

Por ejemplo, para renombrar un origen remoto "origin" por "myrepo":

git remote rename origin myrepo

El nombre origin

Por defecto, se emplea el nombre _origin_ para referirse al origen remoto cada vez que clonamos un repositorio. Esto constituye una conveción y, por lo tanto, podemos cambiarlo por otro nombre si así lo deseamos.

URL del origen remoto

La sintaxis del comando necesario para cambiar la URL del origen remoto es:

git remote set-url <nombre-repositorio-remoto> <nueva-url-repositorio-remoto>

Por ejemplo:

git remote set-url origin https://gitlab.com/la9una/la9una.github.io.git

Eliminando un origen remoto

Si por alguna razón queremos eliminar un origen remoto -ya sea que hemos cambiado de servidor o simplemente, no queremos seguir utilizándolo-, la sintaxis del comando será:

git remote rm <nombre-repositorio-remoto> 

Por ejemplo:

git remote rm origin

Eviando y recibiendo información

Una de las grandes características de git es la de ser un repositorio distribuido que permite a cada desarrollador poseer una copia local exacta del repositorio remoto pudiendo contribuir al mismo y recibiendo, al mismo tiempo, los aportes que los miembros del equipo realizan.

Recibiendo desde repositorios remotos

Existen dos maneras de recibir contenido desde un repositorio remoto:

  1. Mediante la combinación de los comandos fetch y merge
  2. Mediante el comando pull

Diferencia entre fetch-merge y pull

git fetch y git merge

Este método para sincronizar información desde el repositorio remoto hacia el repositorio local se compone de dos comandos, cada uno con su cometido.

git fetch

El comando git fetch consulta las novedades de un repositorio remoto y las descarga en un repositorio local, sin afectar el contenido de éste último de ninguna manera.

La sintaxis general del comando es:

git fetch <nombre-repositorio-remoto> <rama> 

Por ejemplo:

git fetch origin master
Realiza la misma acción que el comando anterior, pero solo recupera la rama especificada.

git fetch
Recupera todas las ramas del repositorio. También descarga todos los commits y archivos requeridos del otro repositorio.

git fetch --all
Recupera todos los repositorios remotos registrados y sus ramas.

git fetch --prune
Limpia en local, las ramas remotas que ya no existen.

git merge

Fusiona los cambios descargados desde el repositorio remoto con el comando fetch con nuestro repositorio local. La sintaxis del comando:

git merge <nombre-rama-a-fusionar-con-la-actual> 

Por ejemplo:

git merge rama1

Fusionando ramas

Por ejemplo, para fusionar el contenido de `rama2` en `rama1` tendremos que estar ubicados en `rama1` y ejecutar el comando `git merge rama2`

git pull

Existe otra comando que combina las acciones de los comandos fetch y merge: el comando pull

git pull

La ejecución de la invocación predeterminada de git pull equivale a git fetch origin HEAD y git merge HEAD, donde HEAD es una referencia que apunta a la rama actual.

Error al intentar fusionar repositorios de orígenes diferentes

Si creamos un repositorio local y agregamos un origen (repositorio) externo, al intentar fusionar datos entre ambos obtendremos el siguiente error:
`fatal: refusing to merge unrelated histories`

Esto es así porque de forma predeterminada, los comandos de fusión de git, como merge y pull se niegan a fusionar historias que no comparten un antecesor común (es decir, se niegan a fusionar historias de dos proyectos que comenzaron sus vidas de forma independiente). Sin embargo, existe una opción para anular esta medida de seguridad: --allow-unrelated-histories. Entonces, si queremos ejecutar el comando pull lo haremos de la siguiente manera:

git pull <nombre-repositorio-remoto> <rama-local> --allow-unrelated-histories

Resolución de conflictos

En múltiples instancias del flujo de trabajo con git podemos encontrarnos con la situación de resolver un conflicto de forma manual (por ejemplo, cuando poseemos dos versiones del mismo archivo).

Cada vez que estemos frente a un conclicto, git nos avisará insertando código que nos indicará los fragmentos de código afectados:

<<<<<<< HEAD

[Contenido de la versión actual] 

=======

[Contenido nuevo] 

>>>>>>> [rama actual o número de commit]

Para resolver esta situación tendremos que:

  1. Decidir cómo quedará el fragmento de código que mantendremos y borrar el resto
  2. Borrar los comentarios introducidos automáticamente por git, es decir <<<<<<< HEAD, ======= y >>>>>>> [rama actual o número de commit]
  3. Guardar el archivo y agregar los cambios (add)
  4. Realizar la confirmación o commit
  5. Enviar los cambios al servidor remoto

Enviando hacia repositorios remotos

Cuando tu proyecto se encuentra en un estado que deseamos compartir, tenemos que enviarlo a un repositorio remoto. El comando que nos permite hacer esto es sencillo:

git push <nombre-repositorio-remoto><rama-local>

Por ejemplo, si queremos enviar nuestra rama (master) a nuestro servidor remoto (origin), ejecutaríamos el siguiente comando:

git push origin master

Error al intentar realizar git push

Puede ocurrir que otro desarrollador esté trabajando en el mismo archivo que nosotros y actualice el repositorio remoto antes que nosotros. En ese caso, al intentar hacer un `git push` obtendremos un error similar a este:
```bash
error: failed to push some refs to 'xxx@yyy'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

En primer lugar, tendremos que "bajarnos" el trabajo de la otra persona:

```bash
git pull <nombre-repositorio-remoto> <rama-local>
```

Y luego, realizar el envío de nuestros cambios al repositorio remoto:

```bash
git push <nombre-repositorio-remoto> <rama-local>
```

Comparando repositorio local con remoto

Podemos ver las diferencias entre el repositorio local y el remoto ejecutando:

git diff <rama-local> <nombre-remoto>/<rama-remota>

Por ejemplo:

git diff master origin/master

También podremos cotejar el historial de confirmaciones:

git log <rama-local> <nombre-remoto>/<rama-remota>

Por ejemplo:

git log master origin/master