cgit: un visor vistoso para un repositorio git

25 Nov

Y mira que le he dado vueltas y vueltas a gitweb, el programa que se incluye casi de facto en cualquier instalación git. Pero nada, han sido quince minutos con cgit y he conseguido todo lo que pretendía.

Y lo que pretendía era muy sencillo: un visor web a mis repositorios git.

La parte de creación y de mantenimiento de estos repositorios la llevo a cabo mediante conexiones seguras (ssh) y cuentas concretas. Lo normal y lo que funciona sin problemas.

Pero quería ver los repositorios y, mejor aún, ser capaz de clonarlos empleando una URL sencilla de recordar. Ya que tengo un dominio concreto para ellos –https://git.example.net– quería ser capaz de ejecutar algo como:

$ git clone https://git.example.net/myrepo.git 

Porque muchas veces necesito acceder al contenido en lugares en los que no tengo montado un entorno de desarrollo ni pretendo crear nada.

Después de las peleas que he tenido con gitweb y el servidor web Apache encontrar algo tan sencillo como cgit ha sido todo un alivio.

Instalación

Tratándose de servidores Debian la instalación ha sido tan sencilla como instalar el paquete correspondiente: cgit.Luego viene la parte de crear un servidor virtual en Apache que ha quedado de la siguiente forma:

<VirtualHost *:443>
   ...
        DocumentRoot "/usr/lib/cgit/"

        <Directory "/usr/lib/cgit/">
                AllowOverride None
                Options ExecCGI FollowSymlinks
                Require all granted
        </Directory>

        Alias /css      "/usr/share/cgit"
        Alias /img      "/usr/share/cgit"
        ScriptAlias / "/usr/lib/cgit/cgit.cgi/"
</VirtualHost>

Y aunque ya se puede poner en marcha necesitamos antes configurarlo para que ciertos valores concuerden con lo que hemos establecido.

Configuración

El archivo /etc/cgitrc tiene su propia página de manual, con un buen puñado de opciones, pero al final he optado por la más sencilla para mí:

# Paŕametros web
css=/css/cgit.css
logo=/img/cgit.png
virtual-root=/

# Personalización
root-title=Software personal
root-desc=Visor de repositorios git

# Parámetros GIT: 
#    conservar scan-path el último 
#
enable-git-config=1
strict-export=git-daemon-export-ok
scan-path=/var/lib/git


# Especiales
enable-commit-graph=1
enable-http-clone=1

Es tan simple porque ya he centralizado todos los respositorios que poseo en un directorio concreto que el servidor Apache puede leer; ha bastado entonces con decirle que sea compatible con gitweb para que todo resulte de lo más sencillo.

Repositorios públicos y privados

Con la configuración anterior si queremos que un repositorio aparezca tenemos que cumplir un requisito: el archivo git-daemon-export-ok debe existir en él. Simple. O no.

Porque con mi configuración los repositorios que muestro son del tipo puro (bare) -sin copia de trabajo- y cuyos contenidos no cambian cuando efectúo operaciones de escritura desde otras máquinas.

Es decir, lo que veo en estos repositorios es lo siguiente:

$ ls -la
total 40
drwxr-xr-x   7 git  www-data 4096 nov 25 10:07 .
drwxr-xr-x  15 git  www-data 4096 nov 20 10:46 ..
drwxr-xr-x   2 git  www-data 4096 ene 24  2017 branches
-rwxr--r--   1 git  www-data   66 ene 24  2017 config
-rw-r--r--   1 git  www-data   18 ene 24  2017 description
-rw-r--r--   1 root root        0 nov 25 10:07 git-daemon-export-ok
-rw-r--r--   1 git  www-data   23 ene 24  2017 HEAD
drwxr-xr-x   2 git  www-data 4096 ene 24  2017 hooks
drwxr-xr-x   2 git  www-data 4096 jun  5 10:49 info
drwxr-xr-x 245 git  www-data 4096 nov 25 06:54 objects
drwxr-xr-x   4 git  www-data 4096 ene 24  2017 refs
$

En este caso el archivo que hace de conmutador sí que está, pero es que he tenido que crearlo a mano.

Si clono una copia de él, creo el mismo fichero en el directorio .git correspondiente, y envío los datos al servidor el archivo no aparecerá.

Así que, dado que tengo ya un mecanismo simple para gestionar los repositorios vía ssh voy a ampliar su capacidad para hacer públicos o no los repositorios.

El programa se llama public y tiene el siguiente aspecto:

#!/bin/sh


# If no project name is given
if [ $# -eq 0 ]
then

        # Display usage and stop
        echo "Usage: public <project> [on|off]"
        exit 1
else
        REPO=$1.git
        SW=$2
fi

if [ ! -d "$REPO" ]; then 
        echo "Repository $REPO not found"
        exit 1
fi 

PUBLIC=$REPO/git-daemon-export-ok

# Si no tenemos un parámetro
if [ "$SW" = "on" ]; then 
        touch $REPO/git-daemon-export-ok
elif [ "$SW" = "off" ]; then 
        rm -f $REPO/git-daemon-export-ok
elif [ -n "$SW" ]; then 
        echo "Parámetro erróneo (on|off): $SW"
        exit 1  
fi 
# Mostramos estado 
if [ -e $PUBLIC ]; then 
        echo "Repository $REPO is public" 
else
        echo "Repository $REPO is private"
fi
exit 0

Y puede usarse para

# Consultar el estado del repositorio (sin extensión)
$ ssh git@astillas.net public msat
Repository msat.git is public
$
# Ocultarlo 
$ ssh git@astillas.net public msat off
Repository msat.git is private
$ 
# O hacerlo visible desde cgit
$ ssh git@astillas.net public msat on
Repository msat.git is public
$

Y funciona de maravilla …