Usando Git(1)


Es habitual encontrar manuales de Git en los que se describe la estructura interna de los changesets, los ficheros y otras tecnicidades similares. Sin embargo, el otro día nos reunimos en Agile-cr y sin quererlo me di cuenta de lo sencillo que resulta explicarlo sin hablar de nada de eso.

Así que voy a intentarlo :D

A pesar de haber escrito ya otro artículo sobre Git, creo que esta vez voy ha contarlo desde un punto de vista muy diferente: uno completamente práctico.

A vista de pájaro

Por mucho que quiera evitar tecnicidades, hay algunos términos que no resulta fácil evitar. Voy a tratar de reducirlos al mínimo.

Comencemos con un dibujo lleno de glamour:

-----------   1   ---------
| Working |<----->| Stash |
|  copy   |       ---------
-----------
     ^
     |2
     |
     v
----------   3   ---------   4    ----------
|  Stage |<----->| Local |<------>| Remote |
----------       ---------        ----------

Como véis, he pintado 5 zonas:

  • Working copy, que se corresponde con el espacio de trabajo, la zona habitual donde están los archivos que iremos modificando.
  • Stash, que es el cajón de sastre, donde podemos guardar los retales para utilizarlos luego. Podemos olvidarnos de esto por el momento, pero es interesante que sepamos de su existencia.
  • Stage, la rampa de lanzamiento, donde se van colocando las cosas que vamos a querer persistir.
  • local, que se corresponde con los archivos internos de Git en la máquina local. Realmente, el stash y el index (antes conocido como stage) forman parte de este bloque, pero separémoslo de forma didáctica.
  • remote, con los archivos de Git remotos.

Además, he marcado en el dibujo 4 procesos, todos ellos de dos direcciones, indicando las interacciones que pueden realizarse. Hay alguna de ellas que podemos saltarnos... Pero vamos a suponer en este artículo que no es así, por simplicidad. Y por simplicidad también, veremos sólo los puntos 2, 3 y 4.

Es importante no confundir el Stage con el Stash. En este artículo sólo hablaremos del Stage.

Y, a partir de ahora, mostraré cómo se suele trabajar con un repositorio tipo Git.

Proceso

Creación

Vamos a comenzar el "Proyecto Fantabuloso". Tenemos una idea en la cabeza y decidimos ponerla en práctica. Lo suyo sería comenzar escribiendo nuestras intenciones, por si acaso mañana nos olvidamos, así que escribiremos un archivo README indicando de qué va nuestro "Proyecto Fantabuloso".

Ya tenemos algo, y decidimos que vamos a utilizar un repositorio. Y Git nos parece una buena idea.

Lo primero es crear la estructura. Necesitamos que Git haga un poco de magia y nos prepare la zona de trabajo. Para ello:

$ git init

Y ya se han creado el stash, index y, por llamarlo de alguna forma, local.

Queremos añadir nuestro README para seguir su evolución. Para ello, primero tenemos que registrarlo en el index:

$ git add README

Resulta dificil describir este index. Digamos que es como una pizarra en la que se va apuntando lo que se desea hacer. Así podemos ir viendo lo que estamos preparando y, una vez hecho, persistirlo definitivamente.

Con el comando anterior ya hemos preparado todo lo que queremos guardar en nuestro index, así que persistimos:

$ git commit -m "Explaining about the Fantabulosum Project"
[master (root-commit) 59aff13] Explaining about the Fantabulosum Project
 0 files changed
 create mode 100644 README

Esta orden limpia el index y guarda todo lo que se encuentre allí en la copia local del repositorio. Ya está persistido. Podemos continuar con ciclos de add y commit.

Podéis ejecutarlo son la opción -m y se os abrirá vuestro editor favorito para que escribáis el mensaje.

Para comprobar el estado del working copy y del index podéis usar la orden siguiente:

$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   README
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   ignored

En este ejemplo vemos cómo el archivo README está preparado para ser añadido, mientras que el archivo ignored no se está siguiendo. Vemos también cómo Git nos ofrece cierta ayuda con órdenes que podemos utilizar, para sacarlo del index o para añadir archivos que actualmente se están ignorando.

Backups

Nuestro proyecto evoluciona y nos entra miedo de perder el "Proyecto Fantabuloso", así que queremos hacer un backup. Pero... ¿Por qué un complicado backup cuando podemos tener nuestro repositorio accesible en remoto?

Así que nos vamos a GitHub, BitBucket o algún otro lugar gratuito y creamos allí un repositorio. Debería ser tan simple como pulsar un botón y ponerle un nombre. Una vez hecho eso, nos darán una dirección, algo como "git://example.com/fantabulosum.git".

Otra opción es creárnoslo nosotros. Pero aquí ya entran temas de red en los que no quiero entrar. Por eso sólo voy a explicar cómo crearlo en un repositorio local, es decir, en otro directorio:

/opt/repos/fantabulosum$ git init --bare --shared
Initialized empty shared Git repository in /opt/repos/fantabulosum

Esto nos daría la ruta "/opt/repos/fantabulosum" o bien "ssh://user@machine:/opt/repos/fantabulosum" para utilizar como dirección del repositorio. Todas ellas se usarían igual a partir de ahora, así que disculpad que yo siga usando "git://example.com/fantabulosum.git" nada más.

Ya tenemos creado local y remote, pero no hay nada que los una. Así que desde mi working copy tengo que enlazarlos:

$ git remote add origin git://example.com/fantabulosum.git

Al enlazarlos, le hemos dado un nombre al enlace. Lo habitual es, como en este caso, usar origin como nombre del remote principal. Una vez enlazados, podemos empujar algunos cambios de local a remote:

$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 243 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To git://example.com/fantabulosum.git
 * [new branch]      master -> master

Sabemos qué es origin, el nombre que hemos puesto a nuestro remote, pero no qué es master. Fijáos que hasta ahora no he necesitado hablar de eso tan feo que son las ramas. Y aún no lo voy a hacer.

Baste saber de momento que Git tiene ramas y que si no te pones a hacer marranadas estarás en una rama cuyo nombre es master. Suficiente de momento.

Como es la primera vez que se hace un push, se enlaza la rama master y el remote origin, de manera que ya basta hacer:

$ git push
Everything up-to-date

Así que, a partir de ahora, a nuestros ciclos de editar, add y push se verán envueltos dentro de ciclos push.

Recuperando

Un mal día se nos jode el ordenador. Pero no es un problema, porque como tenemos nuestros backups podemos recuperarlo todo rápidamente:

$ git clone git://example.com/fantabulosum.git
Cloning into 'fantabulosum'...
done.

Y ya está. A seguir trabajando.

Deshaciendo

No sé los demás, pero yo muchas veces me equivoco: se me olvida añadir un archivo, añado uno de más, me equivoco en el mensaje del commit... Esas pequeñas cosas.

En estos casos la solución es preparar el index de acuerdo a como lo quiero y luego ejecutar:

$ git commit -m "new message" --amend

Y asunto arreglado.

Cuando meto la pata aún más y no es tan fácil arreglarlo, también hay solución. Pero tendría que liarme a hablar de cosas raras y no es el momento. Lo veremos más adelante.

Más que suficiente.

Y esto es todo lo que se necesita para trabajar con Git. Resumiendo:

  • Crear repositorio: git init
  • Crear repositorio compartido: git init --bare --shared
  • Añadir un archivo al index: git add file
  • Persistir el index: git commit -m "message"
  • Comprobar el estado del index: git status
  • La branch principal suele ser "master"
  • Enviar cambios de local a remote por primera vez: git push remote branch
  • Enviar cambios de local a remote: git push
  • Clonar el repositorio: git clone URL

En el próximo artículo continuaremos haciendo crecer nuestro "Proyecto Fantabuloso" y viendo más órdenes de Git.

Desmitificando Git

Como véis, no es dificil trabajar con Git. La dificultad comienza cuando se empiezan a utilizar ramas, cuando se comparten repositorios, etc. Es decir: cuando se hacen marranadas. Pues bien, comentaremos estas marranadas en próximos posts XD

Más información

Recomiendo la web de Git o el libro progit, de Scott Chacon.


Comentarios

Comments powered by Disqus