RSS

Git como herramienta de control de versiones

21 Ago

git-logo

Git según la definición que podemos encontrar en la Wikipedia es:

Git es un software de control de versiones diseñado por Linus Torvalds, pensando en la eficiencia y la confiabilidad del mantenimiento de versiones de aplicaciones cuando estas tienen un gran número de archivos de código fuente.

Sin duda una de las características más destacadas y diferentes de Git respecto otros software de control de versiones es el hecho de que estamos hablando de un sistema distribuido de repositorios a la hora de replicar nuestro código.

Uno de los fundamentos principales de Git es que se va a realizar un desarrollo de programación lineal, es decir, cada uno de los desarrolladores se va a encargar de programar su parte de funcionalidad (ramificación) que será almacenada en su disco duro (repositorio) local. Los cambios locales realizados por cada uno de los desarrolladores serán propagados por el resto de repositorios (discos duros del resto de desarrolladores). Una de las ventajas de Git es que podemos trabajar en local de manera que dispongamos de control de versionado sobre el proyecto que estemos realizando sin necesidades de estar conectado a un repositorio central. Si quieres conocer las características esenciales de Git te recomiendo este enlace.

Para empezar con Git creo que es conveniente echar un vistazo a su página oficial. La parte de documentación es bastante buena y está catalogada en dos secciones:

  • Short and sweet. Si estás comenzando y quieres entender como funciona Git o cuales son los primeros comandos para empezar con él.
  • Longer, More In Depth. Se nos explica una introducción sobre como diseñar una arquitectura para nuestro proyecto que utilice Git, una expicación sobre como funciona internamente Git y guías más amplias si queremos aprender Git en profundidad.

En este tutorial vamos a utilizar la primera parte (Short and sweet) para instalar y ver algunos de los comandos básicos en Git. En particular me gusta mucho el Git reference porque te explica de manera sencilla que es Git. Esto es, Git en lugar de buscar diferencias a nivel de fichero se encarga de hacer fotos (snapshots) de nuestro código en un determinado momento, digamos que es parecido a como pueden funcionar las bases de datos relaciones. Si queremos comparar dos ‘fotos’ simplemente tendremos que usar Git para conocer las diferencias entre estas versiones. En esta imagen del documento de refencia de Git podemos ver como éste funciona.

git snapshots

Cada uno de los recuadros morados equivale a un snapshot de Git. En el caso de la imagen los snapshots se diferencian porque se han incluido progresivamente más ficheros en el proyecto. También habría diferencias si los ficheros existentes en snapshots anteriores se han modificado.

Crear un repositorio con Git

Para crear un repositorio en Git lo único que necesitamos es crear un nuevo directorio donde queramos alojar nuestro proyecto. Una vez dentro del directorio ejecutamos el comando git init que creará la configuración estándar para mantener un proyecto con Git como podemos ver en el siguiente código.

new-host:Documents Ivan$ mkdir git-repository
new-host:Documents Ivan$ cd git-repository/
new-host:git-repository Ivan$ git init
Initialized empty Git repository in /Users/Ivan/Documents/git-repository/.git/
new-host:git-repository Ivan$ ls -la
total 0
drwxr-xr-x   3 Ivan  staff  102 21 ago 12:56 .
drwx------+ 27 Ivan  staff  918 21 ago 12:56 ..
drwxr-xr-x  10 Ivan  staff  340 21 ago 12:56 .git
new-host:git-repository Ivan$ cd .git/
new-host:.git Ivan$ ls -lah
total 24
drwxr-xr-x  10 Ivan  staff   340B 21 ago 12:56 .
drwxr-xr-x   3 Ivan  staff   102B 21 ago 12:56 ..
-rw-r--r--   1 Ivan  staff    23B 21 ago 12:56 HEAD
drwxr-xr-x   2 Ivan  staff    68B 21 ago 12:56 branches
-rw-r--r--   1 Ivan  staff   111B 21 ago 12:56 config
-rw-r--r--   1 Ivan  staff    73B 21 ago 12:56 description
drwxr-xr-x  12 Ivan  staff   408B 21 ago 12:56 hooks
drwxr-xr-x   3 Ivan  staff   102B 21 ago 12:56 info
drwxr-xr-x   4 Ivan  staff   136B 21 ago 12:56 objects
drwxr-xr-x   4 Ivan  staff   136B 21 ago 12:56 refs
new-host:.git Ivan$ 

Si en lugar de crear nuestro propio proyecto queremos traernos el proyecto desde otra persona lo único que tendremos que ejecutar será el comando git clone [url], donde url será la dirección donde tenga alojado su repositorio esa persona.

Añadiendo ficheros y creando un nuevo snapshot

Vamos a trabajar con el repositorio creado en la sección anterior. Para añadir un nuevo fichero a nuestro repositorio tendremos que ejecutar el comando git add. Ten en cuenta que aunque este fichero este incluido en nuestro repositorio local, no estará todavía incluido en una nueva snapshot hasta que no ejecutemos el comando git commit.

Será en ese momento cuando el fichero pase a ser parte de una nueva snapshot. Si formamos parte de un equipo de desarrollo mayor está snapshot pasará a replicarse entre el resto de repositorios. Si queremos ver en cualquier momento el estado de un fichero dentro del repositorio podemos llamar al comando git status. En el ejemplo lo vamos a ver mejor:

new-host:git-repository Ivan$ pwd
/Users/Ivan/Documents/git-repository
new-host:git-repository Ivan$ git status
# On branch master
#
# Initial commit
#
nothing to commit (create/copy files and use "git add" to track)
new-host:git-repository Ivan$ touch file1
new-host:git-repository Ivan$ touch file2
new-host:git-repository Ivan$ git status -s
?? file1
?? file2
new-host:git-repository Ivan$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	file1
#	file2
nothing added to commit but untracked files present (use "git add" to track)

En el ejemplo vemos que hemos creado dos ficheros dentro de nuestro repositorio. Si preguntamos por su status vemos como file1 y file2 está en nuestro repositorio pero no serán parte de nuestra snapshot hasta que no hagamos un commit. Observa que si añadimos la opción -s a git status tenemos una descripción más amplia del estado de nuestro repositorio.

En el siguiente código vamos a añadir mediante git add los ficheros en nuestro repositorio, además modificaremos uno de los ficheros para ver como reacciona Git:

new-host:git-repository Ivan$ git status -s
A  file1
A  file2
new-host:git-repository Ivan$ vi file1
new-host:git-repository Ivan$ git status -s
AM file1
A  file2
new-host:git-repository Ivan$ 

En este código vemos como añadimos los dos ficheros previamente creados al repositorio, después modificamos uno de ellos. Al volver a ejecutar el comando ‘git status -s’ podemos ver como el primer fichero tiene los flags de ‘added‘ y ‘modified‘ mientras que el segundo fichero simplemente está ‘added’. Ten en cuenta que hasta este punto todavía los ficheros no forman parte de una nueva snapshot. Por lo cual sólo ‘viven’ en nuestro repositorio local.

Ahora vamos a ver el comando git diff que nos sirve para ver diferencias en nuestro repositorio. Ejecutaremos lo siguiente:

new-host:git-repository Ivan$ git diff
diff --git a/file1 b/file1
index e69de29..2e09960 100644
--- a/file1
+++ b/file1
@@ -0,0 +1 @@
+modified
new-host:git-repository Ivan$ vi file1
new-host:git-repository Ivan$ git diff
diff --git a/file1 b/file1
index e69de29..d14b45d 100644
--- a/file1
+++ b/file1
@@ -0,0 +1 @@
+modified again
new-host:git-repository Ivan$ git status -s
AM file1
A  file2

Cuando ejecutamos git diff podemos ver que existe diferencias en file1. Creamos file1 vacío, lo añadimos al repositorio y lo editamos (le añadimos una línea con el texto modified). Al editarlo el fichero file1 ha cambiado respecto su estado inicial.

En el siguiente código crearemos nuestra primer snapshot llamando al comando git commit. Como siempre vemos el código primero:

new-host:git-repository Ivan$ git commit -m 'git basic example'
[master (root-commit) 0757476] git basic example
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 file1
 create mode 100644 file2
new-host:git-repository Ivan$ git status -s
 M file1
new-host:git-repository Ivan$ git diff
diff --git a/file1 b/file1
index e69de29..d14b45d 100644
--- a/file1
+++ b/file1
@@ -0,0 +1 @@
+modified again
new-host:git-repository Ivan$ git add file1
new-host:git-repository Ivan$ git status -s
M  file1
new-host:git-repository Ivan$ git commit -m 'git basic example 2nd round'
[master 789b1a8] git basic example 2nd round
 1 files changed, 1 insertions(+), 0 deletions(-)
new-host:git-repository Ivan$ git status -s
new-host:git-repository Ivan$ git diff

La secuencia de comandos es bastante sencilla de seguir … aunque tal vez haya algo un tanto extraño. Si vemos después de hacer el primer commit (la opción -m permite añadirle un texto descriptivo) hay una llamada a git diff y pese a que ya hemos hecho commit nos indica que todavía diferencias. Esto es debido a que si modificamos un fichero éste tiene que volver a ser añadido al repositorio. Si vemos después hacemos un segundo commit y ya no existe ningún fichero en estado modificada.

Comandos útiles con Git

Hay otra serie de comandos que sirven para trabajar con Git. El nombre de todos ellos son bastante intuitivos. Hay que tener cuidado porque aunque se llaman igual muchos de ellos en SVN no significan exactamente lo mismo. Si quieres ver las difencias te recomiendo Alguno de estos comandos son:

  • git branch. Permite listar, crear o gestionar nuestros repositorios. Podemos ver las distintas ramas ó líneas de desarrollo existentes actualmente, podemos crear o eliminar una nueva rama
  • git checkout. Podemos unirnos a una rama de desarrollo o crear una nueva y comenzar nuestro desarrollo en ella.
  • git merge. Nos permite incluir las modificaciones de una rama en otra o incluso en la rama central de nuestro desarrollo.
  • git log. Podemos listar un log con el histórico de las versiones (snapshots) de nuestro proyecto. La opción –graph te permite incluso ver este histórico en forma de grafo.
  • git tag. Permite indicar un hito en nuestro desarrollo. Por ejemplo podemos poner un tag para indicar que esa snapshot se corresponde con una versión final de nuestro desarrollo.

Otros comandos útiles para trabajar de modo colaborativo pueden ser:

  • git remote. Permite acceder y listar a repositorios de otros desarrolladores
  • git fetch. Permite descargarse una rama de un repositorio remoto
  • git pull. Intentará integrar una rama remota con tu rama de desarrollo actual.
  • git push. Adjuntará tu rama al repositorio remoto indicado.

Al igual que los comandos anteriores, éstos últimos tienen numerosas opciones. Si quieres ver los comandos de manera más detallada aconsejo mirar en la siguiente dirección.

Si no os gusta trabajar por consola existen una serie de clientes gráficos que podrás encontrar aquí. En mi caso voy a mostrar una imagen de GitX (para MacOS) del proyecto creado para este post.

GitX

GitX

Pese a no haber probado mucho el modo gráfico todavía parece que la interfaz es bastante intuitiva y amigable.

En el siguiente post hablaré de los estados en los que se pueden encontrar un fichero dentro de un repositorio de Git.

 
5 comentarios

Publicado por en 21 agosto, 2011 en GIT, SCM

 

Etiquetas: , ,