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.
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.
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 Respuestas a “Git como herramienta de control de versiones”