23  Ignorar archivos/carpetas

Es muy usual tener un archivo llamado .gitignore donde se pueden colocar los nombres de archivos o carpetas que no queremos llevar registro.

Creemos unos archivos de prueba.

cd Mi_primer_repo
mkdir resultados
touch a.csv b.csv c.csv resultados/a.out resultados/b.out

Si preguntamos el estado veremos los cambios no registrados en el historial.

git status

Estos archivos por el momento no nos sirven de nada y guardarlos o registrarlos sería una perdida de tiempo/espacio. Para ignorarlos, creamos el archivo .gitignore y añadimos los nombres a ese archivo:

nano .gitignore
*.csv
resultados/
cat .gitignore

Estos patrones le están diciendo a Git que ignore todos los archivos .csv y todo lo que hay en la carpeta resultados, si después añadimos algo a la carpeta lo seguirá ignorando. Y si alguno de esos archivos ya se le dijo a Git que llevará su registro lo seguirá registrando.

git status

Si nos fijamos, el único documento que ahora nos menciona Git es el archivo .gitignore. Lo que nos falta es añadirlo y hacer el commit.

git add .gitignore
git commit -m "Creamos el archivo gitignore e ignoramos todo lo que hay en resultados y archivos csv"
git status

El archivo .gitignore nos ayuda a no cometer el error de accidentalmente tratar de registrar y rastrear algo que se le dijo que no lo hiciera.

git add a.csv

Si realmente queremos agregarlo, tendríamos que usar la opción -f:

git add -f a.csv

Para ver el estado de los archivos ignorados usamos la siguiente instrucción:

git status --ignored
NoteEjercicio 1

Supongamos que tenemos las siguientes subcarpetas:

resultados/plots
resultados/datos

¿Qué tenemos que hacer si queremos ignorar solamente lo que hay en datos y no lo que hay en plots?

Si queremos ignorar únicamente el contenido de la carpeta datos, pero seguir rastreando los archivos de plots, podemos crear (o modificar) un archivo .gitignore y agregar la siguiente línea:

resultados/datos/

La barra / al final indica que queremos ignorar todo el contenido del directorio datos.

El archivo .gitignore podría verse así:

resultados/datos/

Con esta configuración, Git ignorará archivos como

resultados/datos/datos1.csv
resultados/datos/salida.txt

pero seguirá rastreando normalmente archivos como

resultados/plots/figura1.png
resultados/plots/heatmap.pdf

Podemos comprobar qué archivos están siendo rastreados con:

git status

y observaremos que los archivos dentro de resultados/datos/ no aparecen, mientras que los archivos dentro de resultados/plots/ sí.

Para ignorar por ejemplo todos los archivos que terminan en .csv excepto uno en específico (b.csv) podemos indicarlo en el archivo .gitignore como:

*.csv  # ignoramos todos los csv
!b.csv # exepto el que se llama b.csv
NoteEjercicio 2

Supongamos ahora que tenemos la siguiente estructura de carpetas:

resultados/plots
resultados/datos
resultados/img
resultados/analisis

Y que queremos ignorar todo excepto lo que hay en datos. ¿Cómo lo harían?

Una forma de hacerlo es ignorar primero todo el contenido de resultados y después excluir de esa regla a la carpeta datos.

Para ello, en el archivo .gitignore podemos escribir:

resultados/*
!resultados/datos/

Sin embargo, para que Git también considere los archivos dentro de datos, debemos añadir:

resultados/*
!resultados/datos/
!resultados/datos/**

Con esto, Git ignorará archivos como

resultados/plots/figura1.png
resultados/img/logo.jpg
resultados/analisis/salida.txt

pero seguirá rastreando archivos dentro de

resultados/datos/

Por ejemplo,

resultados/datos/datos1.csv
resultados/datos/mediciones.txt

Podemos verificarlo con:

git status

y observaremos que solamente aparecen los archivos contenidos en resultados/datos.

NoteEjercicio 3

Supongamos que tenemos la siguiente estructura de archivos:

resultados/rdatos/a.csv
resultados/rdatos/b.csv
resultados/rdatos/c.csv
resultados/rdatos/info.txt

¿Cómo le indicas a Git que ignore todos los csv de la carpeta rdatos menos el que se llama info.txt?

Como únicamente queremos ignorar los archivos con extensión .csv dentro de la carpeta rdatos, podemos añadir al archivo .gitignore la siguiente línea:

resultados/rdatos/*.csv

Con esta regla, Git ignorará

resultados/rdatos/a.csv
resultados/rdatos/b.csv
resultados/rdatos/c.csv

pero seguirá rastreando cualquier archivo cuya extensión no sea .csv, por ejemplo

resultados/rdatos/info.txt

Podemos verificarlo con:

git status

y observaremos que únicamente aparecerá info.txt, mientras que los archivos .csv serán ignorados.

NoteEjercicio 4

Supongamos que tenemos la siguiente estructura de datos:

resultados/a.csv
resultados/analisis1/b.csv
resultados/analisis2/c.csv
resultados/analisis2/sub_1/d.csv

¿Cómo le indicamos a Git que ignore todos los archivos .csv sin indicar manualmente todos los directorios?

Si queremos ignorar todos los archivos con extensión .csv, independientemente del directorio en el que se encuentren, podemos añadir al archivo .gitignore la siguiente línea:

*.csv

Con esta regla, Git ignorará automáticamente archivos como

resultados/a.csv
resultados/analisis1/b.csv
resultados/analisis2/c.csv
resultados/analisis2/sub_1/d.csv

sin necesidad de especificar manualmente cada carpeta.

Podemos verificar qué archivos están siendo ignorados mediante:

git status

y observaremos que los archivos con extensión .csv no aparecerán.

Alternativamente, podríamos usar:

**/*.csv

que explícitamente indica que se ignoren todos los archivos .csv en cualquier subdirectorio, aunque en la mayoría de los casos basta con escribir simplemente:

*.csv
NoteEjercicio 5

Si en el archivo .gitignore escribimos lo siguiente, ¿qué está ignorando?

*.csv
!*.csv

La primera línea

*.csv

le indica a Git que ignore todos los archivos con extensión .csv.

Sin embargo, la segunda línea

!*.csv

niega la regla anterior y vuelve a incluir todos los archivos .csv.

Por lo tanto, el efecto neto es que ningún archivo .csv será ignorado.

Recordemos que en un archivo .gitignore, las reglas se procesan de arriba hacia abajo y las reglas posteriores tienen prioridad sobre las anteriores.

Por ejemplo, si tenemos los archivos

a.csv
b.csv
datos/c.csv

ninguno de ellos será ignorado.

Podemos comprobarlo con:

git status

y observaremos que todos los archivos .csv aparecerán normalmente.