¡Esta es una revisión vieja del documento!
Tabla de Contenidos
Repositorios remotos
Sección perteneciente al curso Control de versiones con Git Avanzado.
Introducción
Hasta ahora hemos trabajado en local como si fuéramos el único desarrollador de un proyecto.
Ahora veremos cómo conectarnos a un repositorio remoto y trabajar tanto en nuestro repositorio local como en el remoto.
El escenario más común es estar en un equipo de trabajo donde tendremos un repositorio remoto con el que vamos a estar sincronizándonos todos los desarrolladores.
Veremos que la gran parte del tiempo estaremos trabajando en nuestro repositorio remoto y solo de vez en cuando vamos a sincronizar con el remoto para que los demás puedan tener nuestro código o nosotros el de los demás.
Trabajar con servidores remotos
Aunque la gran parte del tiempo desarrollaremos en nuestro repositorio local, hay 3 motivos por los que nos conectaremos al remoto:
- Subir trabajo que hemos hecho en local y no está en el remoto
- Descargar trabajo que haya en remoto y no tengamos en local
- Actualizar información que tenemos sobre el repositorio remoto.
La primera vez, se crea un repositorio vacío en el servidor. El primer commit se crea siempre en un repositorio local.
Otro escenario es que ya exista un repositorio remoto con información (otro desarrollador ha hecho alguna subida). Nosotros tendríamos que descargarnos el repositorio remoto a nuestro equipo. Este proceso se llama clonar un repositorio.
Soluciones existentes
- Azure DevOps / Team Foundation Server
En todas esas opciones hay que crearse una cuenta.
En esos servidores de repositorios Git, podremos crear repositorios vacíos, que es lo que nos interesa.
Hay dos métodos para conectarnos a un repositorio remoto:
- Vía HTTPS: el más común.
- Vía SSH
Trabajar con remotes
Vamos a ver cómo se conecta un repositorio local a un repositorio remoto. Para ello, en Git existe un tipo de objeto llamado remote.
Podemos tener nuestro repositorio local conectado a varios servidores remotos, no solo a uno.
Si solo hay un remote, este se llama origin (por convención).
Un remoto tiene un nombre y una URL. Para añadirlo:
git remote add <NOMBRE_REMOTE> <URL_REMOTE>
Por ejemplo:
git remote add origin https://ruta/repositorio/remoto.git
En este momento se crea un alias, pero no se establece la conexión con el servidor. Solo cuando nos vayamos a sincronizar con el servidor (subir o descargar cambios).
Si queremos renombrar un remote:
git remote rename <NOMBRE_ACTUAL> <NUEVO_NOMBRE>
Listar remotes:
git remote
Si quisiéremos ver además la dirección a la que apunta:
git remote -v
Veremos que nos va a mostrar dos, una dirección para subir los cambios y otra para descarga de cambios. Normalmente serán la misma.
Poner ejemplo de salida del comando anterior
Cambiar la URL de un remote:
git remove set-url <NOMBRE_REMOTE> <NUEVA_URL>
Si ahora queremos subir los cambios al repositorio remoto:
git push <REMOTE> <RAMA_LOCAL>
Por ejemplo, si queremos subir la rama local master al repositorio remoto origin:
git push origin master
En ese momento se establecerá conexión con el remote, comprobará credenciales y subirá los cambios.
Si ahora queremos ver las ramas locales y las copias de las ramas remotas:
git branch -a
Ahora veremos el escenario en el que el repositorio remoto ya existe y queremos sincronizar con nuestro repositorio local.
Si no teníamos copia, clonaremos el repositorio:
git clone <URL_REMOTE> [<DIRECTORIO>]
El comando anterior, creará un repositorio git en local y obtendrá una copia de todos los ficheros del repositorio local. Además, se habrá creado el remote.
Si nos hemos bajado una copia de una rama que no tenemos en local, “saltamos” a esa rama:
git checkout develop
No solo saltaremos a esa rama, sino que la creará.
Si estamos en master y queremos vincular nuestra rama master local con la rama master remota:
git branch --set-upstream-to origin/master
Si hacemos esta asociación, podemos usar git push de forma más abreviada:
git push
Si estamos en master, el comando anterior sabrá que estamos vinculados con origin/master.
Para ver la asociación, en el repositorio local, de ramas locales y remotas, ejecutamos git branch -avv
Push, fetch y pull
git push: subir cambios al remotogit fetch: actualiza todo el trabajo remoto, es decir, actualiza la copia local con lo más reciente del repositorio remoto.git pull: obtener cambios del remoto (es la mezcla de fetch y merget)
Comunicación con el remoto
Los remotos solo admiten merge de tipo fast-forward.
El flujo habitual de trabajo cuando estamos en un equipo es
- Subimos nuestros cambios al remoto
- El remoto dice que esa rama tiene un aspecto distinto porque otro desarrollador la ha hecho avanzar.
- Pide bajar esa rama a local y fusionarla
- Subimos de nuevo los cambios al remoto
Si hacemos desde local un push de una rama que no existe en el remoto, se aceptará siempre.
Poniendo en práctica la sincronización con el remoto
Comandos para comunicarnos con el remoto
Enviar cambios al repositorio remoto:
git push <NOMBRE_REMOTE> <NOMBRE_RAMA>
Si la rama que vamos a subir ya la tenemos “trackeada”, no sería necesario indicarla. Así que el comando se podría resumir como:
git push <NOMBRE_REMOTE>
Si queremos “trakear” la rama al hacer el push:
git push -u <NOMBRE_REMOTE> <NOMBRE_RAMA>
Sincronizar mi copia local del remoto:
git fetch
Recordemos que aunque tengamos asociado un remote, no se hace una sincronización automática, por eso es recomendable hacer el fetch para actualizar la copia local que tenemos del repositorio remoto.
Traer cambios del remoto:
- git fetch + git merge =
git pull - git fetch + git rebase =
git pull --rebase
Subir tags al remoto (por defecto se suben las ramas, no las tags):
git push --tags
Borrar ramas del remoto:
git push -d <NOMBRE_REMOTE> <NOMBRE_RAMA>
Marcar ramas remotas borradas, para cuando queramos que ramas que se han borrado en remoto, se borren también de la copia local:
git fetch --prune
Configurar prune por defecto:
git config [--global|--system] fetch.prune true
Hay que tener cuidado con el comando anterior porque borra automáticamente sin pedir confirmación. Si un desarrollador se equivoca al borrar una rama remota, se borrará la que tengamos en local sin que nos enteremos
Conclusión
Hemos visto cómo se trabaja en equipo con un servidor remoto contribuyendo a un mismo repositorio.
No necesitamos estar sincronizando constantemente. De vez en cuando haremos “push” para subir cambios y “pull” para descargarlos.
Lo más habitual es que cuando subamos con un “push”, el servidor remoto nos lo rechaze y tengamos entonces que hacer un “merge” en nuestro repositorio local y luego subirlo de nuevo.
Recursos
- Capítulo del libro Pro Git sobre remotos:
