Creative Commons License
Excepto donde se indique otra cosa, todo el contenido de este lugar está bajo una licencia de Creative Commons.
Taquiones > software > Git - anotaciones

Git - anotaciones

Comentarios iniciales

Para todos los ejemplos presentes y futuros de esta página nos situaremos en dos máquinas, un servidor que conserva la copia central del repositorio y al que llamaremos [server] en un ataque de originalidad, y otra máquina que será la que contenga finalmente una copia de trabajo del repositorio, y que se llamará [desktop] siguiendo la misma tendencia.

¿ Por qué copia central del repositorio ? Dado que Git anima precisamente a lo contrario, ¿ por qué insistir en imitar el esquema CVS ? Pues porque desarrollo en solitario, tanto en casa como en mi trabajo, y como no suelo estar en los dos sitios al mismo tiempo necesito tener a mano siempre la última versión actualizada de los fuentes.

Situaciones

remote HEAD refers to nonexistent ref, unable to checkout

Si estamos intentando clonar un repositorio y aparece este mensaje, casi seguro que se trata de que, al crearlo, no hemos actualizado la información del servidor mediante:

[server] $ cd repositorio
[server] $ git update-server-info

y si es así, casi seguro que no hemos dado permisos de ejecución al programa de post-actualización:

[server] $ chmod u+x .git/hooks/post-update

Operaciones

Crear un parche y enviarlo al autor

Fue el propio Joey Hess el que me proporcionó, a petición mía, una guía simple para realizar esta tarea dado que me encargo de las traducciones al español de IkiWiki.

  1. Creamos el parche

    [desktop] $ git commit -a -m 'updated spanish translation'
    [desktop] $ git format-patch HEAD^
    0001-updated-spanish-translation.patch
    
  2. Enviamos el parche

    [desktop] $ git send-email 0001-updated-spanish-translation.patch
    Who should the emails appear to be from? [Víctor Moral <victor@taquiones.net>]
    Emails will be sent from: Víctor Moral <victor@taquiones.net>
    Who should the emails be sent to? author@ikiwiki
    Message-ID to be used as In-Reply-To for the first email?
    (mbox) Adding cc: =?utf-8?q?V=C3=ADctor=20Moral?= <victor@taquiones.net> from line 'From: =?utf-8?q?V=C3=ADctor=20Moral?= <victor@taquiones.net>'
    OK. Log says:
    Server: myserver.net
    MAIL FROM:<victor@taquiones.net>
    RCPT TO:<author@ikiwiki>,<victor@taquiones.net>
    From: =?utf-8?q?V=C3=ADctor=20Moral?= <victor@taquiones.net>
    To: author@ikiwiki
    Cc: =?utf-8?q?V=C3=ADctor=20Moral?= <victor@taquiones.net>
    Subject: [PATCH] updated spanish translation
    Date: Wed, 22 Apr 2009 09:23:50 +0200
    Message-Id: <1240385030-12089-1-git-send-email-victor@taquiones.net>
    X-Mailer: git-send-email 1.6.2.3
    
    
    Result: 250 OK id=1LwWoA-0006ZY-Ot
    
    
    [desktop] $
    

Para ello antes tenemos que haber instalado y configurado correctamente el programa git send-email del paquete git-email. En realidad basta con crear una sección [sendemail] en nuestro archivo ~/.gitconfig e incluir los valores descritos en la documentación del programa.

Importar un repositorio SubVersion

El objetivo es conseguir en un directorio una copia Git de un repositorio subversion existente; dicha copia deberá estar limpia de particularidades subversion pero con su registro de cambios y lista de autores intacta.

Según la guía de Jon Maddox se deben seguir los siguientes pasos:

  1. Instalar el correspondiente paquete git-svn.

    [server] $ sudo apt-get install git-svn
    
  2. Crear un archivo de autores que permite establecer una relación entre los usuarios subversion y los usuarios Git.

    [server] $ echo "victor = Victor Moral <victor@taquiones.net>" > users.txt
    
  3. Crear un directorio temporal y pasarse a él.

    [server] $ mkdir adriano-tmp
    [server] $ cd adriano-tmp
    
  4. Inicializar el repositorio:

    [server] $ git-svn init svn+ssh://victor@venexma.net/var/lib/svn/adriano --no-metadata
    

    cuidando de no incluir información específica de SVN, aunque sí el histórico de cambios (commit log), mediante el parámetro --no-metadata.

  5. Indicar al repositorio el mapa de usuarios:

    [server] $ git config svn.authorsfile ../users.txt
    
  6. Importar el contenido del repositorio:

    [server] $ git-svn fetch 
    This may take a while on large repositories
            A       t/00.load.t
            A       t/perlcritic.t
            A       t/pod.t
            A       t/pod-coverage.t
            .
            .
            .
    r2524 = 8197e214cb753d146d1e6b205eeb7cc6cbb5a332 (git-svn)
            M       lib/Adriano.pm
    r2527 = 0fab890c998ed8b670f435a28dfe91c066326bee (git-svn)
    Checked out HEAD:
    svn+ssh://victor@venexma.net/var/lib/svn/adriano r2527
    [server] $
    

    variando los detalles, naturalmente, ya que aquí en realidad estoy transcribiendo fragmentos de un proyecto antiguo que tengo por ahí.

  7. Verificar el resultado para quedarnos más tranquilos:

    [server] $ git log 
    commit 0fab890c998ed8b670f435a28dfe91c066326bee
    Author: Victor Moral <victor@taquiones.net>
    Date:   Fri Oct 10 11:01:42 2008 +0000
    
    
    
    - Eliminada la dependencia y uso de variables de entorno.
    
    commit 0fab890c998ed8b670f435a28dfe91c066326bee Author: Victor Moral <victor@taquiones.net> Date: Fri Oct 10 11:01:42 2008 +0000
    - Eliminada la dependencia y uso de variables de entorno.
    
    commit 8197e214cb753d146d1e6b205eeb7cc6cbb5a332 Author: Victor Moral <victor@taquiones.net> Date: Thu Oct 9 13:35:22 2008 +0000
    - Nueva versión para añadirle soporte a configuración externa vía YAML.
    
    commit 48124296889fc73a3764deac735d41a9a70b9521 Author: Angel Ortega <angel@triptico.com> Date: Tue Jul 24 10:41:52 2007 +0000
    Referenciada Adriano::idfiscal desde la clase clientes_recientes.
    
    ... [server] $
  8. Clonamos el repositorio importado de subversion en un directorio Git limpio (y desnudo, bare, puesto que lo vamos a emplear como base):

    [server] $ cd ..
    [server] $ git clone --bare adriano-tmp adriano 
    Initialized empty Git repository in /home/victor/git/adriano/.git/
    [server] $
    

¿ Cuál es exactamente la diferencia entre uno y otro ? Bueno, a primera vista las diferencias son sobre todo en los orígenes. Si nos situamos en cada uno de ellos y pedimos un listado de la configuración podremos verlo mejor.

[server] $ cd adriano-tmp
[server] $ git-config --list
...
svn-remote.svn.nometadata=1
svn-remote.svn.url=svn+ssh://victor@venexma.net/var/lib/svn/adriano
svn-remote.svn.fetch=:refs/remotes/git-svn
...
[server] $ cd ../adriano
[server] $ git-config --list
...
remote.origin.url=/home/victor/git/adriano-tmp/.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*

Lo siguiente es eliminar las referencias anteriores del repositorio, y para ello Bernhard Hartleb sugiere lo siguiente en un comentario de la guía anteriormente citada:

[server] $ cd 
[server] $ rm -R adriano-tmp
[server] $ cd adriano
[server] $ git remote rm origin

Y para terminar preparamos una copia de trabajo en nuestra máquina habitual:

[desktop] $ git clone victor@server:git/adriano

Emplear un repositorio central

Con Git podemos trabajar de varias formas dado que se proporciona a cada copia clon la totalidad del repositorio, incluyendo el historial de cambios, y una de ellas es el estilo CVS en el que existe un repositorio central en el que terminan todos los cambios y desde el que parten todas las contribuciones, puesto que es la copia principal.

Si en un momento dado necesitamos que nuestro repositorio de trabajo sea una copia satélite de dicho repositorio central podemos hacer lo siguiente:

  1. Crear un repositorio vacío y desnudo (bare repository) en la localización central que aquí asumimos va a ser otra máquina.

    [desktop] $ ssh victor@server "GIT_DIR=git/coco git-init --bare"
    Initialized empty Git repository in /home/victor/git/coco/
    
  2. Cambiamos el URL al que apunta nuestra copia local:

    [desktop] $ cd git/adriano
    [desktop] $ git-config remote.origin.url victor@server:git/coco 
    [desktop] $
    
  3. Enviamos todo el repositorio al servidor central:

    [desktop] $ git push origin master
    

Ahora podemos experimentar obteniendo copias desde el repositorio central, efectuando cambios y mezclándolos o no con el desarrollo principal, y/ó directamente borrando nuestra copia y transladándola a otra máquina.

Ignorar archivos de desarrollo

Como me he encontrado con esta situación un montón de veces, y hasta que adopte una solución más elegante, anoto aquí el contenido genérico del archivo .gitignore correspondiente a estos casos.

*.bak
*.orig
*-stamp
*.tar.gz
Build
_build
blib
debian/files

y conviene incluir los resultantes según el nombre del paquete, como por ejemplo:

debian/ikiwiki-plugin-hl*

Enlaces y referencias