Git puede usar cuatro protocolos principales para transferir datos: Local, HTTP, Secure Shell (SSH) y Git. Vamos a ver en qué consisten y las circunstancias en que querrás (o no) utilizar cada uno de ellos.
El más básico es el Protocolo Local, donde el repositorio remoto es simplemente otra carpeta en el disco. Se utiliza habitualmente cuando todos los miembros del equipo tienen acceso a un mismo sistema de archivos, como por ejemplo un punto de montaje NFS, o en el caso menos frecuente de que todos se conectan al mismo computador. Aunque este último caso no es precisamente el ideal, ya que todas las instancias del repositorio estarían en la misma máquina; aumentando las posibilidades de una pérdida catastrófica.
Si dispones de un sistema de archivos compartido, podrás clonar (clone), enviar (push) y recibir (pull) a/desde repositorios locales basado en archivos. Para clonar un repositorio como estos, o para añadirlo como remoto a un proyecto ya existente, usa el camino (path) del repositorio como su URL. Por ejemplo, para clonar un repositorio local, puedes usar algo como:
$ git clone /opt/git/project.git
O como:
$ git clone file:///opt/git/project.git
Git trabaja ligeramente distinto si indicas 'file://' de forma explícita al comienzo de la URL. Si escribes simplemente el camino, Git intentará usar enlaces rígidos (hardlinks) o copiar directamente los archivos que necesita. Si escribes con el prefijo 'file://', Git lanza el proceso que usa habitualmente para transferir datos sobre una red; proceso que suele ser mucho menos eficiente. La única razón que puedes tener para indicar expresamente el prefijo 'file://' puede ser el querer una copia limpia del repositorio, descartando referencias u objetos superfluos. Esto sucede normalmente, tras haberlo importado desde otro sistema de control de versiones o algo similar (ver ch10-git-internals.asc sobre tareas de mantenimiento). Habitualmente, usaremos el camino (path) normal por ser casi siempre más rápido.
Para añadir un repositorio local a un proyecto Git existente, puedes usar algo como:
$ git remote add local_proj /opt/git/project.git
Con lo que podrás enviar (push) y recibir (pull) desde dicho remoto exactamente de la misma forma a como lo harías a través de una red.
Las ventajas de los repositorios basados en carpetas y archivos, son su simplicidad y el aprovechamiento de los permisos preexistentes de acceso. Si tienes un sistema de archivo compartido que todo el equipo pueda usar, preparar un repositorio es muy sencillo. Simplemente pones el repositorio básico en algún lugar donde todos tengan acceso a él y ajustas los permisos de lectura/escritura según proceda, tal y como lo harías para preparar cualquier otra carpeta compartida. En la próxima sección, [r_git_on_the_server], veremos cómo exportar un repositorio básico para conseguir esto.
Este camino es también útil para recuperar rápidamente el contenido del
repositorio de trabajo de alguna otra persona. Si tú y otra persona estáis
trabajando en el mismo proyecto y ésta quiere mostrarte algo, el usar un comando
tal como git pull /home/john/project
suele ser más sencillo que el que esa
persona te lo envíe (push) a un servidor remoto y luego tú lo recojas (pull)
desde allí.
La principal desventaja de los repositorios basados en carpetas y archivos es su dificultad de acceso desde distintas ubicaciones. Por ejemplo, si quieres enviar (push) desde tu portátil cuando estás en casa, primero tienes que montar el disco remoto; lo cual puede ser difícil y lento, en comparación con un acceso basado en red.
Cabe destacar también que una carpeta compartida no es precisamente la opción más rápida. Un repositorio local es rápido solamente en aquellas ocasiones en que tienes un acceso rápido a él. Normalmente un repositorio sobre NFS es más lento que un repositorio SSH en el mismo servidor, asumiendo que las pruebas se hacen con Git sobre discos locales en ambos casos.
Git puede utilizar el protocolo HTTP de dos maneras.
Antes de la versión 1.6.6 de Git, solo había una forma de utilizar el protocolo
HTTP y normalmente en sólo lectura. Con la llegada de la versión 1.6.6 se
introdujo un nuevo protocolo más inteligente que involucra a Git para negociar
la transferencia de datos de una manera similar a como se hace con SSH.
En los últimos años, este nuevo protocolo basado en HTTP se ha vuelto muy
popular puesto que es más sencillo para el usuario y también más inteligente.
Nos referiremos a la nueva versión como el HTTP Inteligente'' y llamaremos
a la versión anterior el HTTP
tonto''. Comenzaremos primero con el protocolo HTTP ``Inteligente''.
El protocolo HTTP ``Inteligente'' funciona de forma muy similar a los protocolos SSH y Git, pero se ejecuta sobre puertos estándar HTTP/S y puede utilizar los diferentes mecanismos de autenticación HTTP. Esto significa que puede resultar más fácil para los usuarios, puesto que se pueden identificar mediante usuario y contraseña (usando la autenticación básica de HTTP) en lugar de usar claves SSH.
Es, probablemente, la forma más popular de usar Git ahora, puesto que puede configurarse para servir tanto acceso anónimo (como con el protocolo Git) y acceso autenticado para realizar envíos (push), con cifrado similar a como se hace con SSH. En lugar de tener diferentes URL para cada cosa, se puede tener una única URL para todo. Si intentamos subir cambios (push) al repositorio, nos pedirá usuario y contraseña, y para accesos de lectura se puede permitir el acceso anónimo o requerir también usuario.
De hecho, para servicios como GitHub, la URL que usamos para ver el repositorio en la web (por ejemplo, ``https://github.com/schacon/simplegit[]'') es la misma que usaríamos para clonar y, si tenemos permisos, para enviar cambios.
Si el servidor no dispone del protocolo HTTP Inteligente'', el cliente de Git intentará con el protocolo clásico HTTP que podemos llamar HTTP
Tonto''. Este protocolo espera obtener el repositorio Git a través de un servidor web como si accediera a archivos normales. Lo bonito de este protocolo es la simplicidad para configurarlo. Básicamente, todo lo que tenemos que hacer es poner el repositorio Git bajo el directorio raíz de documentos HTTP y especificar un punto
de enganche (hook) de post-update
(véase ch08-customizing-git.asc).
Desde ese momento, cualquiera con acceso al servidor web donde se publique el repositorio podrá también clonarlo. Para permitir acceso de lectura con HTTP, debes hacer algo similar a lo siguiente:
$ cd /var/www/htdocs/
$ git clone --bare /path/to/git_project gitproject.git
$ cd gitproject.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update
Y esto es todo.
El punto de enganche post-update
que trae Git de manera predeterminada
ejecuta el comando adecuado (git update-server-info
) para hacer que las
operaciones de clonado o recuperación (fetch) funcionen de forma adecuada.
Este comando se ejecuta cuando se envían cambios (push) al repositorio
(mediante SSH, por ejemplo); luego, otras personas pueden clonar mediante algo como:
$ git clone https://example.com/gitproject.git
En este caso concreto, hemos utilizado la carpeta /var/www/htdocs
, que es la
habitual en configuraciones Apache, pero se puede usar cualquier servidor web
estático. Basta con que se ponga el repositorio básico (bare) en la carpeta
correspondiente. Los datos de Git son servidos como archivos estáticos simples
(véase ch10-git-internals.asc para saber exactamente cómo se sirven).
Por lo general tendremos que elegir servirlos en lectura/escritura con el servidor
HTTP Inteligente'' o en solo lectura con el servidor
tonto''. Mezclar
ambos servicios no es habitual.
Nos centraremos en las ventajas de la versión ``Inteligente'' del protocolo HTTP.
La simplicidad de tener una única URL para todos los tipos de acceso y que el servidor pida autenticación sólo cuando se necesite, hace las cosas muy fáciles para el usuario final. Permitir autenticar mediante usuario y contraseña es también una ventaja sobre SSH, ya que los usuarios no tendrán que generar sus claves SSH y subir la pública al servidor antes de comenzar a usarlo. Esta es la principal ventaja para los usuarios menos especializados, o para los usuarios de sistemas donde el SSH no se suele usar. También es un protocolo muy rápido y eficiente, como sucede con el SSH.
También se pueden servir los repositorios en sólo lectura con HTTPS, lo que significa que se puede cifrar la transferencia de datos; incluso se puede identificar a los clientes haciéndoles usar certificados convenientemente firmados.
Otra cosa interesante es que los protocolos HTTP/S son los más ampliamente utilizados, de forma que los cortafuegos corporativos suelen permitir el tráfico a través de esos puertos.
Git sobre HTTP/S puede ser un poco más complejo de configurar comparado con el SSH en algunos sitios. En otros casos, se adivina poca ventaja sobre el uso de otros protocolos.
Si utilizamos HTTP para envíos autenticados, proporcionar nuestras credenciales cada vez que se hace puede resultar más complicado que usar claves SSH. Hay, sin embargo, diversas utilidades de cacheo de credenciales, como Keychain en OSX o Credential Manager en Windows; haciendo esto menos incómodo. Lee ch07-git-tools.asc para ver cómo configurar el cacheo seguro de contraseñas HTTP en tu sistema.
SSH es un protocolo muy habitual para alojar repositorios Git en hostings privados. Esto es así porque el acceso SSH viene habilitado de forma predeterminada en la mayoría de los servidores, y si no es así, es fácil habilitarlo. Además, SSH es un protocolo de red autenticado sencillo de utilizar.
Para clonar un repositorio a través de SSH, puedes indicar una URL ssh:// tal como:
$ git clone ssh://user@server/project.git
También puedes usar la sintaxis estilo scp del protocolo SSH:
$ git clone user@server:project.git
Pudiendo asimismo prescindir del usuario; en cuyo caso Git asume el usuario con el que estés conectado en ese momento.
El uso de SSH tiene múltiples ventajas. En primer lugar, SSH es relativamente fácil de configurar: los ``demonios'' (daemons) SSH son de uso común, muchos administradores de red tienen experiencia con ellos y muchas distribuciones del SO los traen predefinidos o tienen herramientas para gestionarlos. Además, el acceso a través de SSH es seguro, estando todas las transferencias encriptadas y autentificadas. Y, por último, al igual que los protocolos HTTP/S, Git y Local, SSH es eficiente, comprimiendo los datos lo más posible antes de transferirlos.
El aspecto negativo de SSH es su imposibilidad para dar acceso anónimo al repositorio. Todos han de tener configurado un acceso SSH al servidor, incluso aunque sea con permisos de solo lectura; lo que no lo hace recomendable para soportar proyectos abiertos. Si lo usas únicamente dentro de tu red corporativa, posiblemente sea SSH el único protocolo que tengas que emplear. Pero si quieres también habilitar accesos anónimos de solo lectura, tendrás que reservar SSH para tus envios (push) y habilitar algún otro protocolo para las recuperaciones (pull) de los demás.
El protocolo Git es un demonio'' (daemon) especial, que viene incorporado con
Git. Escucha por un puerto dedicado (9418) y nos da un servicio similar al del
protocolo SSH; pero sin ningún tipo de autentificación. Para que un repositorio
pueda exponerse a través del protocolo Git, tienes que crear en él un archivo
'git-daemon-export-ok'; sin este archivo, el
demonio'' no hará disponible el
repositorio. Pero, aparte de esto, no hay ninguna otra medida de seguridad. O el
repositorio está disponible para que cualquiera lo pueda clonar, o no lo está.
Lo cual significa que, normalmente, no se podrá enviar (push) a través de este
protocolo. Aunque realmente si que puedes habilitar el envío, si lo haces, dada
la total falta de algún mecanismo de autentificación, cualquiera que encuentre
la URL a tu proyecto en Internet, podrá enviar (push) contenidos a él. Ni qué
decir tiene, que esto sólo lo necesitarás en contadas ocasiones.
El protocolo Git es el más rápido de todos los disponibles. Si has de servir mucho tráfico de un proyecto público o servir un proyecto muy grande, que no requiera autentificación para leer de él, un ``demonio'' Git es la respuesta. Utiliza los mismos mecanismos de transmisión de datos que el protocolo SSH, pero sin la sobrecarga de la encriptación ni de la autentificación.
El principal problema del protocolo Git, es su falta de autentificación. No es recomendable tenerlo como único protocolo de acceso a tus proyectos. Habitualmente, lo combinarás con un acceso SSH o HTTPS para los pocos desarrolladores con acceso de escritura que envíen (push) material, dejando el protocolo 'git://' para los accesos solo-lectura del resto de personas.
Por otro lado, necesita activar su propio ``demonio'', y necesita configurar 'xinetd' o similar, lo cual no suele estar siempre disponible en el sistema donde estés trabajando. Requiere además abrir expresamente el acceso al puerto 9418 en el cortafuegos, ya que estará cerrado en la mayoría de los cortafuegos corporativos.