Operaciones de archivos y commit
Operaciones de archivos y commit
La función principal de Git es seguir las diferentes versiones de un proyecto. Un proyecto no es más que un conjunto de archivos. De forma práctica, Git solo se interesa por los archivos y los desarrolladores son quienes le indican qué archivos debe seguir.
El commit es el elemento central de Git. Es la piedra angular que permite vincular todos los elementos y todos los conceptos de Git. Un commit representa un conjunto coherente de modificaciones.
Por ejemplo, si un desarrollador corrige un error «bug», indicará a Git el archivo donde se efectuó la modificación y Git guardará el archivo corregido (conservando la antigua versión).
Antes de abordar la continuación del capítulo, es útil conocer cómo ve Git un archivo.
Una historia de hash
Un hash (que también puede llamarse un condensado o una firma) es un valor calculado a partir de un valor diferente. En la gran mayoría de los casos, este valor está representado en forma de una cadena de caracteres hexadecimales. El cálculo del hash utiliza un algoritmo complejo que este libro no detallará.
He aquí dos ejemplos de hash calculado con el algoritmo SHA-1:
Valor |
Hash |
Git |
5819778898df55e3a762f0c5728b457970d72cae |
git |
46f1a0bd5592a2f9244ca321b129902a06b53e03 |
Quiero una frase bastante larga, por lo menos más que el hash en todos los casos |
7a5a57cde20a9bbda76b70e9223292ce7f8472f9 |
En este ejemplo, recalcaremos dos cosas:
-
Un cambio menor en el contenido cambia totalmente el hash. Podemos observar esto comparando los hash de «Git» y «git».
-
Un hash tiene siempre el mismo tamaño: 40 caracteres (lo que equivale a 160 bits).
Es imposible recuperar el contenido original a partir del hash. Se puede tratar de adivinar, pero no se puede tener ninguna certeza, dado que un mismo hash puede corresponder a diferentes cadenas. En efecto, si se calcula el hash de 2160+1 cadenas distintas, se tiene necesariamente al menos una cadena que comparte el hash de otra (véase la sección Riesgo de colisión).
Los hashs suelen utilizarse para verificar que un archivo no se ha visto corrompido o bien para autentificar a un usuario sin tener que almacenar su contraseña sin cifrar.
1. Una identificación por contenido
Internamente, Git trabaja sobre...
Las tres zonas de un archivo
Un archivo puede encontrarse en tres lugares distintos: el directorio de trabajo, el índice y el repositorio. El archivo se encontrará en las distintas zonas según su avance en el proyecto.
El esquema siguiente muestra un proyecto totalmente virgen en el cual se acaba de inicializar un repositorio Git, es decir, que no hemos registrado ningún archivo en el proyecto. La única acción efectuada en este proyecto es un git init.
Para llegar a este resultado, puede usar los comandos:
mkdir zonaArchivo
cd zonaArchivo
git init
Para ver el estado de los archivos, vamos a usar el comando siguiente:
git status
Este comando muestra la siguiente salida:
git status
On branch master
Initial commit
nothing to commit (create/copy files and use "git add" to track)
El comando git status permite mostrar el estado de los archivos del repositorio. Este comando será explicado mediante los ejemplos que seguirán en la continuación de este capítulo.
En el ejemplo anterior, el comando git status muestra que no hay ningún archivo pendiente de hacer commit (nothing to commit).
1. El directorio de trabajo
Esta zona es el directorio del sistema de archivos donde trabaja el desarrollador. Es la carpeta del proyecto tal como se almacena en el disco duro. Git puede conocer los archivos que se encuentran en esta zona si han sido añadidos al menos una vez en Git. Un archivo que se encuentra solo en esta zona es un archivo totalmente desconocido para Git.
Este tipo de archivo se conoce también como archivo no seguido (untracked file en inglés).
Para llegar a este resultado, puede usar los comandos:
echo "<html>El archivo se encuentra en el directorio de trabajo</html>"
> archivo.html
El comando git status nos indica que el archivo está reconocido como un archivo no seguido.
git status
On branch master
Initial commit
Untracked files: ...
Operar con archivos
1. Añadir archivos al índice
Existen dos casos donde es conveniente añadir un archivo al índice.
El primer caso tiene lugar cuando el archivo es nuevo y desconocido por Git. Añadir este nuevo archivo al índice permitirá prevenir a Git de que este archivo debe ser tomado en cuenta. Como se explica antes, este archivo pasará de un estado donde no es seguido a un estado seguido por Git.
El segundo caso tiene lugar cuando el archivo ya cuenta con una versión, pero el desarrollador quiere incluir las modificaciones efectuadas en el archivo en el índice para hacer el commit.
Para añadir un archivo al índice, hay que utilizar el comando git add con la siguiente sintaxis:
git add nombre_archivo
También existen formas de añadir varios archivos al índice usando un solo comando. Por ejemplo, para añadir todos los archivos en el repositorio, debe usar el comando siguiente:
git add -A
Las mejores prácticas recomiendan no utilizar este comando. En efecto, si se utiliza este comando, se pueden añadir archivos que no queremos en nuestro repositorio. Estos archivos pueden ser archivos temporales creados por el sistema o cualquier otro archivo que no debe estar en el repositorio.
2. Mover o renombrar archivos
Git posee un comando que permite renombrar o mover un archivo. He aquí la sintaxis de este comando:
git mv antiguo_archivo nuevo_archivo
He aquí, por ejemplo, cómo renombrar el archivo archivo.html en index.html.
git mv archivo.html index.html
El comando git status muestra la siguiente salida:
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
...
Commit o guardar los cambios
1. Efectuar un primer commit
El commit es el elemento central de Git. Es él quien guarda todas las modificaciones del proyecto. Un commit debe representar un conjunto de cambios coherentes entre sí.
Es decir, que un commit no debe servir para hacer un respaldo de los datos. Un sistema de gestión de versiones no es un sistema de respaldo. Muchos desarrolladores que comienzan ven el sistema de versión como un sistema que les sirve para respaldar los cambios.
Un ejemplo permitirá comprender mejor la filosofía del commit. El desarrollador comienza a trabajar en una nueva funcionalidad. Si se va de vacaciones mientras que su desarrollo está en curso, no hará un commit a sus modificaciones solo para realizar una copia de seguridad. Eventualmente, tendrá por separado la nueva funcionalidad en varias pequeñas nuevas funcionalidades para hacer commits por separado.
De forma más simple, un commit es un paquete virtual de modificaciones. Por ejemplo, utilizando un repositorio nuevo en el cual se añadirían dos archivos vacíos:
-
index.html
-
style.css
El desarrollador codifica en estos archivos una página muy simple para un cliente que desee solo tener sus datos de contacto en un sitio web (el código de ejemplo es intencionadamente simple).
Después de añadir sus archivos en el índice, el desarrollador hace commit de las modificaciones con:
git commit -m "Página de contacto"
Posteriormente, el desarrollador añade el número de teléfono a la lista de contactos y hace commit de sus modificaciones.
Git commit -m "Contacto: añadimos teléfono"
En el capítulo siguiente abordamos con mayor amplitud el comando git log que permite listar los commits añadidos al repositorio.
git log
commit a2ab800
Author: Samuel DAUZON <git@dauzon.com>
Date: Mi Jul 20 23:25:31 2015 +0200
Contacto: añadimos teléfono
commit 1480a2
Author: Samuel DAUZON <git@dauzon.com>
Date: Mi Jul 20 23:16:48 +0200 2015
Página de contacto...