¿Cómo ignoro los archivos en un directorio en Git?

544

¿Cuál es la sintaxis adecuada para que el .gitignorearchivo ignore los archivos en un directorio?

Podría ser

config/databases.yml
cache/*
log/*
data/sql/*
lib/filter/base/*
lib/form/base/*
lib/model/map/*
lib/model/om/*

o

/config/databases.yml
/cache/*
/log/*
/data/sql/*
/lib/filter/base/*
/lib/form/base/*
/lib/model/map/*
/lib/model/om/*

?

Chris McKnight
fuente
55
¿ .gitignorediferencia entre archivos y directorios que ignora? por ejemplo, ¿ datavs data/significa cosas diferentes?
Charlie Parker el
66
@CharlieParker yes-ish: dataignorará los archivos y directorios que coincidan, data/ignorará solo los directorios que coincidan.
jox
Recuerde siempre que si ha organizado o comprometido el archivo que está tratando de ignorar, entonces no hay forma de ignorarlo :( Solo mis 2 centavos después de pensar que me equivoqué con mi patrón y perdí un cuarto de hora.
Adam
@Adam correcto, tendría que actualizar .gitignore y luego desestabilizar / git rm: almacenó en caché el archivo.
Chris McKnight

Respuestas:

374

FORMATO DE PATRÓN

  • Una línea en blanco no coincide con ningún archivo, por lo que puede servir como separador para facilitar la lectura.

  • Una línea que comienza #sirve como comentario.

  • Un prefijo opcional !que niega el patrón; cualquier archivo coincidente excluido por un patrón anterior se volverá a incluir. Si un patrón negado coincide, esto anulará las fuentes de patrones de precedencia más baja.

  • Si el patrón termina con una barra diagonal, se elimina con el propósito de la siguiente descripción, pero solo encontraría una coincidencia con un directorio. En otras palabras, foo/coincidirá con un directorio fooy rutas debajo de él, pero no coincidirá con un archivo normal o un enlace simbólico foo(esto es coherente con la forma en que funciona pathpec en general en git).

  • Si el patrón no contiene una barra oblicua /, git lo trata como un patrón glob de shell y comprueba una coincidencia con el nombre de ruta relativo a la ubicación del .gitignorearchivo (en relación con el nivel superior del árbol de trabajo si no es de un .gitignorearchivo).

  • De lo contrario, git trata el patrón como un globo de shell adecuado para el consumo fnmatch(3)con la FNM_PATHNAMEbandera: los comodines en el patrón no coincidirán con a /en el nombre de ruta. Por ejemplo, Documentation/*.htmlcoincide Documentation/git.htmlpero no Documentation/ppc/ppc.htmlo tools/perf/Documentation/perf.html.

  • Una barra inclinada inicial coincide con el comienzo del nombre de ruta. Por ejemplo, /*.ccoincide cat-file.cpero no mozilla-sha1/sha1.c.

Puedes encontrar más aquí

git help gitignore
o
man gitignore

Op De Cirkel
fuente
2
¿Cómo puedo poner un archivo .gitignore en el nivel superior y hacer que funcione para cualquier carpeta debajo de él? Gracias.
Royi
104
-1 TL; DR y apenas responde la pregunta. Se trata de directorios, no de archivos, por lo que la sección en negrita solo es apropiada con algo de gimnasia mental. @Jefromi fue más directo.
Bob Stein
He leído al hombre, y la respuesta de @ Jefromi es mejor, siempre y cuando también leas la advertencia de @ jox, y la de Luke Hutton podría ser más útil para ignorar, por ejemplo, los archivos de proyecto IDE.
WillC
1
Esto es en realidad una copia y pega de la documentación de git
mcont
1
No estoy seguro (esencialmente) copiar y pegar una manpágina o documento oficial es el mejor formato para SO ...
jdk1.0
183

Sería lo primero. Ir por extensiones también en lugar de estructura de carpetas.

Es decir, mi ejemplo C # desarrollo ignora el archivo:

#OS junk files
[Tt]humbs.db
*.DS_Store

#Visual Studio files
*.[Oo]bj
*.user
*.aps
*.pch
*.vspscc
*.vssscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.[Cc]ache
*.ilk
*.log
*.lib
*.sbr
*.sdf
ipch/
obj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad

#Tooling
_ReSharper*/
*.resharper
[Tt]est[Rr]esult*

#Project files
[Bb]uild/

#Subversion files
.svn

# Office Temp Files
~$*

Actualizar

Pensé en proporcionar una actualización de los comentarios a continuación. Aunque no responde directamente a la pregunta del OP, consulte lo siguiente para obtener más ejemplos de .gitignoresintaxis.

Wiki de la comunidad (en constante actualización):

.gitignore para proyectos y soluciones de Visual Studio

Se pueden encontrar más ejemplos con el uso de un lenguaje específico aquí (gracias al comentario de Chris McKnight):

https://github.com/github/gitignore

Luke Hutton
fuente
55
@ Stallman, esa es la range. Por lo tanto, coincide *.Objtanto como *.obj.
norbert
131

Se considera que las rutas que contienen barras son relativas al directorio que contiene el archivo .gitignore, generalmente el nivel superior de su repositorio, aunque también puede colocarlas en subdirectorios.

Entonces, dado que en todos los ejemplos que da, las rutas contienen barras diagonales, las dos versiones son idénticas. El único momento en que necesita poner una barra diagonal es cuando ya no hay ninguno en el camino. Por ejemplo, para ignorar foo solo en el nivel superior del repositorio, use /foo. Simplemente escribir fooignoraría cualquier cosa llamada foo en cualquier parte del repositorio.

Sus comodines también son redundantes. Si desea ignorar un directorio completo, simplemente llámelo:

lib/model/om

La única razón para usar comodines de la manera que tiene es si tiene la intención de ignorar posteriormente algo en el directorio:

lib/model/om/*      # ignore everything in the directory
!lib/model/om/foo   # except foo
Cascabel
fuente
55
Mejor explicación que la respuesta aceptada para esta pregunta
eerrzz
78

Una barra diagonal indica que la entrada de ignorar solo debe ser válida con respecto al directorio en el que reside el archivo .gitignore. Especificar *.oignoraría todos los archivos .o en este directorio y todos los subdirectorios, mientras /*.oque los ignoraría en ese directorio, mientras que nuevamente, /foo/*.osolo los ignoraría en /foo/*.o.

jørgensen
fuente
34

Si desea colocar un archivo .gitignore en el nivel superior y hacer que funcione para cualquier carpeta debajo de su uso /**/.

Por ejemplo, para ignorar todos los *.maparchivos en una /src/main/carpeta y subcarpetas, use:

/src/main/**/*.map
petrsyn
fuente
Necesitaba hacer esto. No estoy seguro de por qué necesitas dos ** . Uno fue suficiente para mí.
Novocaine
8
** coincide también con archivos en subdirectorios
petrsyn
Gracias por la información @petrsyn
Novocaine
30

¡Ambos ejemplos en la pregunta son en realidad muy malos ejemplos que pueden conducir a la pérdida de datos!

Mi consejo: ¡nunca agregue /*a directorios en archivos .gitignore, a menos que tenga una buena razón!

Una buena razón sería, por ejemplo, lo que escribió Jefromi: "si tiene la intención de ignorar posteriormente algo en el directorio" .

La razón por la que de otra manera no debería hacerse es que agregar /*a directorios funciona, por un lado, de la manera en que ignora adecuadamente todos los contenidos del directorio, pero por otro lado tiene un efecto secundario peligroso:

Si ejecuta git stash -u(para almacenar temporalmente archivos rastreados y no rastreados) o git clean -df(para borrar archivos no rastreados pero mantener ignorados) en su repositorio, todos los directorios que se ignoran con un anexo /*se eliminarán irreversiblemente .

Algunos antecedentes

Tenía que aprender esto de la manera difícil. Alguien en mi equipo estaba agregando /*algunos directorios en nuestro .gitignore. Con el tiempo tuve ocasiones en que ciertos directorios desaparecerían repentinamente. Directorios con gigabytes de datos locales que necesita nuestra aplicación. Nadie podía explicarlo y siempre me gusta volver a descargar todos los datos. Después de un tiempo tuve la noción de que podría tener que ver con eso git stash. Un día quería limpiar mi repositorio local (mientras mantenía los archivos ignorados) y estaba usando git clean -dfy nuevamente mis datos desaparecieron. Esta vez tuve suficiente e investigé el problema. Finalmente pensé que la razón es la adjunta /*.

Supongo que puede explicarse de alguna manera por el hecho de que directory/*ignora todo el contenido del directorio pero no el directorio en sí. Por lo tanto, no se considera rastreado ni ignorado cuando las cosas se eliminan. Aunque git statusy git status --ignoreddar una imagen ligeramente diferente en él.

Como reproducir

Aquí es cómo reproducir el comportamiento. Actualmente estoy usando Git 2.8.4.

Se creará un directorio llamado localdata/con un archivo ficticio en él ( important.dat) en un repositorio git local y el contenido se ignorará al colocarlo /localdata/*en el .gitignorearchivo. Cuando se ejecuta uno de los dos comandos git mencionados ahora, el directorio se perderá (inesperadamente).

mkdir test
cd test
git init
echo "/localdata/*" >.gitignore
git add .gitignore
git commit -m "Add .gitignore."
mkdir localdata
echo "Important data" >localdata/important.dat
touch untracked-file

Si haces un git status --ignoredaquí, obtendrás:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

  untracked-file

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)

  localdata/

Ahora tampoco

git stash -u
git stash pop

o

git clean -df

En ambos casos, el directorio supuestamente ignorado localdatadesaparecerá.

No estoy seguro de si esto puede considerarse un error, pero supongo que es al menos una característica que nadie necesita.

Informaré eso a la lista de desarrollo de git y veré qué piensan al respecto.

jox
fuente
15

Podría ser:

config/databases.yml
cache
log
data/sql
lib/filter/base
lib/form/base
lib/model/map
lib/model/om

o posiblemente incluso:

config/databases.yml
cache
log
data/sql
lib/*/base
lib/model/map
lib/model/om

en caso de que filtery formsean los únicos directorios en lib que tienen un basesubdirectorio que debe ignorarse (consúltelo como un ejemplo de lo que puede hacer con los asterics).

aefxx
fuente
14

El primero. Esas rutas de archivos son relativas desde donde está su archivo .gitignore.

Unixmonkey
fuente
2
Esto solo es cierto para los patrones que contienen una barra inclinada. Un solo nombre de directorio como "mydir" también ignorará los directorios (y archivos) que se encuentran en subcarpetas a cualquier profundidad. Solo poner una barra al frente lo hará relativo desde donde está su archivo .gitignore.
jox
4

Mantengo un servicio basado en GUI y CLI que le permite generar .gitignoreplantillas muy fácilmente en https://www.gitignore.io .

Puede escribir las plantillas que desee en el campo de búsqueda o instalar el alias de la línea de comando y ejecutar

$ gi swift,osx

Joe
fuente
0

Un archivo .gitignore de muestra puede verse como uno a continuación para un proyecto de Android Studio

# built application files
*.apk
*.ap_

# files for the dex VM
*.dex

# Java class files
*.class

# generated files
bin/
gen/

# Local configuration file (sdk path, etc)
local.properties


#Eclipse
*.pydevproject
.project
.metadata
bin/**
tmp/**
tmp/**/*
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
YourProjetcName/.gradle/
YourProjetcName/app/build/
*/YourProjetcName/.gradle/
*/YourProjetcName/app/build/

# External tool builders
.externalToolBuilders/

# Locally stored "Eclipse launch configurations"
*.launch

# CDT-specific
.cproject

# PDT-specific
.buildpath

# Proguard folder generated by Eclipse
proguard/

# Intellij project files
*.iml
*.ipr
*.iws
.idea/
/build
build/
*/build/
*/*/build/
*/*/*/build/
*.bin
*.lock
YourProjetcName/app/build/
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
.gradle/
app/build/
*app/build/

# Local configuration file (sdk path, etc)
local.properties
/YourProjetcName/build/intermediates/lint-cache/api-versions-6-23.1.bin
appcompat_v7_23_1_1.xml
projectFilesBackup
build.gradle
YourProjetcName.iml
YourProjetcName.iml
gradlew
gradlew.bat
local.properties
settings.gradle
.gradle
.idea
android
build
gradle
Shirish Herwade
fuente