¿Cómo crear un nuevo repositorio en Git?
Para crear un nuevo repositorio utilizamos el comando init
dentro de un nuevo directorio en donde deseamos crear el repositorio.
mkdir mirepositorio
cd mirepositorio
git init .
Una ves que hemos utilizado el comando
git init
se creará un nuevo directorio oculto llamado.git
. Nunca realices cambios en este directorio, ya que es controlado automaticamente por Git.
¿Cómo esta constituido el directorio .git?
Si listamos los archivos dentro del directorio .git
vamos a ver la siguiente lista de archivos y directorios.
ls -la .git
branches
config
description
HEAD
hooks
info
objects
refs
Git como vemos tiene su propio sistema de archivos, cada uno de ellos tiene un propósito diferente que iremos desglosando.
¿Cuántos tipos de archivos existen en el sistema de archivos de Git?
En Git existen 4 tipos de archivos: Blob, Tree, Commit y Annotated Tag. Estos cuatro tipos de objetos permiten almacenar archivos y monitorear los cambios en estos.
En los objetos de tipo Blob en Git almacena archivos, cualquier archivo con cualquier extensión es almacenado como Blob.
En los objetos de tipo Tree (árbol) Git almacena directorios, de la misma forma que cualquier otro tipo de archivos, un directorio puede estar vacío o contener archivos u otros directorios. Por lo cual un Tree puede contener un grupo de Blobs y otros Trees.
Los objetos tipo Commit en Git almacenan las versiones del proyecto.
Los objetos tipo Annotated en Git almacenan texto persistente de un Commit.
En resumen los Blobs son la representación de un archivo en Git mientras que los Tree es la equivalencia de un directorio.
¿Cómo hace Git para convertir los archivos de un proyecto de Git, a objetos del sistema de archivos de Git?
Para poder convertir archivos al sistema de Git, Git utiliza dos comandos de bajo nivel.
Para crear nuevos objetos Git utiliza el comando git hash-object
.
Para leer los objetos Git utiliza el comando git cat-file
.
¿Cuátos archivos puede almacenar un proyecto Git?
Git utiliza hashes creados mediante sha1 para crear archivos, con ellos lleva implícitos:
- La cantidad de archivos que se pueden crear dentro del mismo repositorio.
- La posibilidad de producir el mismo hash en diferentes archivos.
El número de las combinaciones posibles con sha1 es igual a 2 elevado a la 160, lo que representa un número enorme que ademas es tan grande que la probabilidad de tener duplicidades sería prácticamente imposible.
¿Cómo explorar los objetos en el sistema de archivos de Git?
Para explorar los archivos de Git vamos a utilizar el comando git cat-file
, este comando tiene varias opciones.
Comando | Descripción |
---|---|
git cat-file -p HASH | Muestra el contenido de un objeto |
git cat-file -s HASH | Muestra el tamaño de un objeto |
git cat-file -t HASH | Muestra el tipo de un objeto |
¿Cómo crear un hash con en el sistema de archivos de Git?
Para crear un hash en el sistema de archivo de Git vamos a utilizar el sistema de pipes de Linux y enviarle al comando git hash-object
un texto.
echo "Hola Mundo" | git hash-object --stdin
Esto nos imprimirá el siguiente hash.
22c02951195e38dc2a602ed78dfec38f184f462c
Sin embargo si analizamos la estructura del sistema de archivos de git no encontraremos que se haya creado ningún objeto en .git/objects
, y esto lo podemos hacer utilizando el comando tree
de Linux.
tree .git
Si deseamos que el hash se escriba en el sistema de archivos requerimos utilizar el parámetro -w
como parte del comando hash-object
.
echo "Hola Mundo" | git hash-object --stdin -w
en la salida vamos a obtener el hash…
22c02951195e38dc2a602ed78dfec38f184f462c
Ahora si listamos el contenido del sistema de archivos de .git mediante…
tree .git
podremos encontrar nuestro hash dentro de .git/objects…
.git/objects
├── 22
│ └── c02951195e38dc2a602ed78dfec38f184f462c
├── info
└── pack
¿Cómo ver el contenido de un object en sistema de archivos de Git?
Para ver el contenido de un object en el sistema de archivos de git utilizamos el comando git cat-file
, especificando el parámetro -p
y el hash que vamos a desplegar.
git cat-file -p 22c02951195e38dc2a602ed78dfec38f184f462c
La salida es Hola Mundo
que es lo que contiene el objeto asociado a este hash.
¿Cómo ver el tipo de object en un sistema de archivos de Git?
Para ver el tipo de un object en el sistema de archivos de git utilizamos el comando git cat-file
especificando el parámetro -t
(type/tipo) y el hash que vamos a desplegar.
git cat-file -t 22c02951195e38dc2a602ed78dfec38f184f462c
La impresión de salida es blob
que representa el tipo de objeto asociado a este hash.
¿Cómo ver el tamaño de un object en un sistema de archivos de Git?
Para ver el tamaño de un object en sistema de archivos de git utilizamos el comando git cat-file
especificando el parámetro -s
(size/tamaño).
git cat-file -s 22c02951195e38dc2a602ed78dfec38f184f462c
El resultado de la ejecución es 11
.
¿Cómo crear un Git Blob en un archivo?
Para crear un blob en Git podemos utilizar el comando git hash-object
, siempre que tengamos un archivo existente.
Primero vamos a crear el archivo en donde enviaremos el blob.
echo "Archivo dentro del repo" > miarchivo.txt
Para visualizar el contenido del archivo podemos usar el comando cat
.
cat miarchivo.txt
Este nos mostrará el contenido del archivo que acabamos de crear.
Vamos a previsualizar como se vería nuestro has del archivo sin escribirlo en el sistema de archivos git.
git hash-object miarchivo.txt
80136d7103070e2b024d8394d7abdb2a725b0df2
Ahora finalmente vamos a escribirlo en el sistema de archivos utilizando el parámetro -w
.
git hash-object ARCHIVO -w
Si exploramos el contenido del directorio .git
utilizando el comando tree
podremos ver dentro de objects un nuevo archivo.
tree .git
├── objects
│ ├── 80
│ │ └── 136d7103070e2b024d8394d7abdb2a725b0df2
Notar que para cada objeto Git toma los dos primeros caracteres del hash para crear un directorio, y el resto del hash para el nombre del archivo.
Para visualizar el contenido del objeto que acabamos de crear basta utilizar nuevamente el comando git cat-file
indicando el hash del objeto.
git cat-file -p 80136d7103070e2b024d8394d7abdb2a725b0df2
Y la salida del comando sería Archivo dentro del repo
.
Ahora borramos el archivo original miarchivo.txt
.
rm miarchivo.txt
Después de borrado el archivo vamos a ejecutar nuevamente el comando tree .git
para ver el contenido del sistema de archivo de Git.
├── objects
│ ├── 80
│ │ └── 136d7103070e2b024d8394d7abdb2a725b0df2
Nuestro archivo debe seguir existiendo dentro del directorio ya que Git mantiene un registro de los objetos que se van empujando en su sistema de archivos.
Los blogs guardados en el sistema de archivos de Git tienen un nombre, pero este nombre no obedece al nombre del archivo con el cual hemos construido el blob
miarchivo.txt
sino alsha
del contenido este.
¿Qué elementos componen un Git object (objeto de Git)?
Cuando creamos un Git object este forma un hash de cuatro elementos.
- Tipo de objeto
- Longitud del objeto
- Delimitador
- Contenido
A todos estos elementos en conjunto se les aplica una instrucción hash que genera un identificador único.
Si intentamos ver el contenido de alguno de estos archivos, nos daremos cuanta que la salida de estos es irreconocible, y la razón es porque dichos archivos son almacenados como archivos binarios compresos.
Si quisiéramos realizar la operación manual del hash de un archivo podríamos emularlo de la siguiente forma.
echo "blob 11\0Hola Mundo" | shasum
Esto generaría el mismo resultado que git-catfile sobre un archivo de texto que incluya el texto “Hola Mundo”.
22c02951195e38dc2a602ed78dfec38f184f462c
En ocasiones debido a la codificación y cliente de terminal que se utilice, se hace necesario escapar los caracteres como
\0
, por lo que se usaecho -e
.
¿Qué son los trees (árboles) en Git?
Los trees (árboles) son uno de los cuatro tipos de objetos en Git. Un tree es una representación de directorios, que pueden contener blobs y otros trees.
Un objeto tipo tree en git contiene un grupo de links a blobs y trees. Cada uno de estos links contiene:
- Permisos
- Tipo (blob o tree)
- Hash (id único)
- Nombre de archivo
Existen 6 tipos de permisos en los trees de git.
Permisos | Descripción |
---|---|
040000 | Directory (directorio) |
100644 | Regular non-executable file (archivo regular no ejecutable) |
100664 | Regular non-executable group-writable file (archivo regular no ejecutable de grupo escribible) |
100755 | Regular executable file (archivo regular ejecutable) |
120000 | Symbolic link (archivo ejecutable) |
160000 | Gitlink |
Los blobs o directories tienen el valor
040000
.
En este punto solo tenemos blobs dentro de nuestro repositorio que tienen el id de su hash. Ahora vamos a crear un objeto tipo tree. Para ello vamos a utilizar referencias a los blobs existentes. Como estos son archivos de texto, tendrán el valor 100664 (archivo regular no ejecutable).
¿Cómo crear un tree dentro de un repositorio de Git?
Primero voy a empezar listando el contenido de mi repositorio utilizado el comando tree
de linux.
tree .git/objects
Salida…
.git/objects
├── 22
│ └── c02951195e38dc2a602ed78dfec38f184f462c
├── 80
│ └── 136d7103070e2b024d8394d7abdb2a725b0df2
├── info
└── pack
4 directories, 2 files