Dic 012012
 

Después de muchos años durante los cuales el sistema de control de versiones subversion (svn) ha sido el más ampliamente utilizado en el desarrollo de software, y especialmente en el software open source, ha aparecido git, que se está implantando rápidamente como el sucesor de svn.

En este artículo recogemos algunos apuntes sobre las características de git y las diferencias entre éste y subversion, así como los primeros pasos a dar para trabajar con git en un servidor linux debian.

Diferencias entre svn y git

Para un desarrollador acostumbrado a trabajar con subversion, git presenta dos importantes diferencias

Por una parte, en svn existe un repositorio central. cada desarrollador utiliza a una copia de trabajo. Cuando ha realizado cambios en los ficheros de la copia de trabajo, los guarda en el repositorio central:

Por el contrario, git es un sistema distribuido, en donde cada desarrollador tiene un repositorio completo. Cada desarrollador tiene la posibilidad de incorporar a su repositorio local los cambios en los repositorios de otros desarrolladores. Estos son repositorios “remotos” desde el punto de vista del primero.

Además, entre el área de trabajo y el repositorio de cada desarrollador, existe un área intermedia conocida como “index”, “cache” o “staging area”. Los ficheros modificados se copian primero al area intermedia o “index”, y despues se copian desde el “index” al repositorio local:

Instalación de git y configuración inicial

Comenzamos por instalar git. En Debian, simplemente instalamos con “apt-get” el paquete “git”:

$ sudo apt-get install git

A continuación, configuramos nuestro nombre completo y dirección de correo. Estos datos quedan grabados en el fichero $HOME/.gitconfig, y son los valores que se aplicarán por defecto a todos los repositorios que creemos:

$ git config --global user.name "Nombre Completo"
$ git config --global user.email "email@servidor.com"

La configuración global queda guardada en un fichero ~/.gitconfig en el directorio de login del usuario.

Creación de un nuevo repositorio git

Creamos un directorio para contener el repositorio, y en él ejecutamos el comando “git init”:

$ mkdir /tmp/git-repo/
$ cd /tmp/git-repo/
$ git init
Initialized empty Git repository in /home/usuario/git-repo/.git/

Con esto, se crea un único subdirectorio “.git” para almacenar la información de control del nuevo repositorio. Esta es una primera diferencia entre git y subversion, porque en subversion se crea un subdirectorio “.svn” debajo de cada uno de los subdirectorios del repositorio.

Obtener ayuda sobre los comandos git

Con el comando “git help” obtenemos una lista de los comandos más comunes para manejar el repositorio:

$ git help
usage: git [--version] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
 [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
 [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
 [-c name=value] [--help]
 <command> [<args>]
The most commonly used git commands are:
 add Add file contents to the index
 bisect Find by binary search the change that introduced a bug
 branch List, create, or delete branches
 checkout Checkout a branch or paths to the working tree
 clone Clone a repository into a new directory
 commit Record changes to the repository
 diff Show changes between commits, commit and working tree, etc
 fetch Download objects and refs from another repository
 grep Print lines matching a pattern
 init Create an empty git repository or reinitialize an existing one
 log Show commit logs
 merge Join two or more development histories together
 mv Move or rename a file, a directory, or a symlink
 pull Fetch from and merge with another repository or a local branch
 push Update remote refs along with associated objects
 rebase Forward-port local commits to the updated upstream head
 reset Reset current HEAD to the specified state
 rm Remove files from the working tree and from the index
 show Show various types of objects
 status Show the working tree status
 tag Create, list, delete or verify a tag object signed with GPG
See 'git help <command>' for more information on a specific command.

Además, podemos acceder a la página de manual correspondiente a cada comando para obtener ayuda más detallada sobre el mismo mediante:

$ git help <comando>

o bien

$ git <comando> --help

Guardar ficheros en el repositorio – Primera fase: “staging”

En git, los ficheros se envían al repositorio en dos fases, llamadas “staging” y “commit”.

En la primera fase, llamada “staging”, el contenido de los ficheros se copia a  un área intermedia, llamada “index” o “cache”, con el comando “git add <fichero>”. La operación contraria, para eliminar ficheros del area intermedia se realiza con el comando “git rm <fichero>”.

Después de copiar un fichero al área intermedia, podemos seguir modificandolo, pero cuando guardemos definitivamente los ficheros en el repositorio, lo que se guarda es la copia, y no el contenido actual del fichero en el directorio de trabajo.

Primero creamos unos ficheros de prueba:

$ echo "Fichero uno version uno" >fichero_uno.txt
$ echo "Fichero dos version uno" > fichero_dos.txt

Y a continuación los copiamos al área intermedia:

$ git add fichero_uno.txt
$ git add fichero_dos.txt

En cualquier momento, podemos comprobar el estado del repositorio con el comando “git status”:

$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#	new file:   fichero_dos.txt
#	new file:   fichero_uno.txt
#

Si a continuación modificamos uno de los ficheros, podemos ver que “git status” indica esta modificación, y advierte de que los últimos cambios realizados al fichero desde que se guardó en cache no serán guardados en el repositorio, hasta que no se vuelvan a guardar en cache con el comando “git add”:

$ echo "Fichero uno modificado" >fichero_uno.txt
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#	new file:   fichero_dos.txt
#	new file:   fichero_uno.txt
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   fichero_uno.txt
#

Como hemos señalado más arriba, el comando “git rm <fichero>” revierte los cambios efectuados por “git add <fichero”.

 

Guardar ficheros en el repositorio – Segunda fase: “commit”

En la segunda fase, el contenido copiado en cache es guardado en el repositorio con el comando “commit”. Igual que en subversion, este comando admite el flag “-m” para añadir un mensaje descriptivo de los cambios realizados:

$ git commit -m "Version uno"
[master (root-commit) a36dc32] Version uno
 2 files changed, 2 insertions(+)
 create mode 100644 fichero_dos.txt
 create mode 100644 fichero_uno.txt

Ahora podemos comprobar el nuevo estado del repositorio:

 git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   fichero_uno.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

y también ver el cambio en el registro de cambios, con el comando “git log”:

$ git log
commit a36dc32d4d5f6428ddc14fb91c5858548ba79669
Author: Desarrollador OpenAlfa <developer@openalfa.com>
Date:   Sat Dec 1 12:50:55 2012 +0000

    Version uno

Commit directo

Si un fichero que ya estaba copiado en cache ha sido modificado directamente, podemos guardarlo directamente en el repositorio sin necesidad de ejecutar nuevamente el comando “git add”:

$ git commit -m "guardo el fichero modificado" fichero_uno.txt

También podemos copiar automáticamente en cache todos los ficheros modificados y guardarlos en el repositorio con el comando “git commit -a”:

$ git commit -m "Guardo todas las modificaciones" -a

Guardar ficheros en el repositorio – Resumen

$ vi <fichero>
$ git add <fichero>
$ git commit -m "mensaje de descripción del cambio"

o bien:

$ vi <fichero>
$ git commit -m "mensaje de descripción del cambio" -a

Revisar los cambios realizados

La revisión de cambios se realiza con el comando “git diff”. Pero como un mismo fichero puede tener distintas modificaciones en el área de trabajo, en el área intermedia y en el repositorio, hay tres posibilidades de comparación:

  • Comparar el fichero en el área de trabajo con el fichero en el área intermedia:
$ git diff <fichero>
  • Comparar el fichero en el área de trabajo con el fichero en el repositorio:
$ git diff HEAD <fichero>
  • Comparar el fichero en el área intermedia con el fichero en el repositorio:
$ git diff --cached <fichero>

también se puede utilizar el switch “–staged” como sinónimo de “–cached”:

$ git diff --staged <fichero>

Deshacer los cambios realizados

También en este caso tenemos varias posibilidades:

  • Deshacer los cambios en el área de trabajo y en el área intermedia, recuperando el contenido del repositorio:
$ git checkout HEAD <fichero>
  • Deshacer los cambios en el área de trabajo, recuperando el contenido del área intermedia
$ git checkout <fichero>
  • Recuperar en el área intermedia el contenido del repositorio (no se modifica el área de trabajo):
$ git reset HEAD <fichero>

Recuperar en el área de trabajo una versión anterior del fichero

En el punto anterior hemos visto que utilizamos la palabra clave HEAD, que es un sinónimo de “la versión más reciente en el repositorio”. Para recuperar otras versiones, sustituimos HEAD por el identificador de la versión deseada:

$ git checkout <commit> <fichero>

El identificador es una cadena hexadecimal de cuarenta bytes, que podemos obtener con el comando “git log”. Por ejemplo:

$ git log fichero_uno.txt
commit 42b1de7ef387d30bab3b0849c229d6006c02f2e1
Author: Desarrollador OpenAlfa <developer@openalfa.com>
Date:   Sat Dec 1 13:00:01 2012 +0000

    Segunda version

commit a36dc32d4d5f6428ddc14fb91c5858548ba79669
Author: Desarrollador OpenAlfa <developer@openalfa.com>
Date:   Sat Dec 1 12:50:55 2012 +0000

    Version uno

Como vemos, hay dos versiones guardadas de “fichero_uno.txt”. la más reciente tiene el identificador de versión “42b1de7ef387d30bab3b0849c229d6006c02f2e1”, y la anterior tiene el identificador “a36dc32d4d5f6428ddc14fb91c5858548ba79669”.

Si queremos recuperar la primera versión del fichero, debemos ejecutar el comando:

$ git checkout a36dc32d4d5f6428ddc14fb91c5858548ba79669 fichero_uno.txt

En el próximo artículo de esta serie veremos la manera de trabajar con repositorios remotos en git.

 

 Publicado por en 1:11 pm

 Deja un comentario

(requerido)

(requerido)