Lista blanca y subdirectorios en Git

91

He creado una lista blanca solo para archivos de texto.

*
!*.txt

Ahora, tengo un archivo de texto sin seguimiento en un subdirectorio sub/dir/file.txt, y esto NO se muestra (se ignora). Sin embargo, se muestran los archivos de texto en el directorio raíz.

¿Por qué es así y cómo lo soluciono?

Nate
fuente
1
Relacionado: stackoverflow.com/q/987142/78845
Johnsyweb
¿Los archivos que desea incluir en un subdirectorio? Si es así, es posible que este subdirectorio ya esté ignorado por la primera estrella de su .gitignore.
fajran
Si. Estos archivos serán tan bajos en la estructura de directorios como la carpeta 11.1.102.55 en mi ejemplo. El anidamiento no siempre es el mismo entre carpetas / productos.
Nate
1
Conozco esta funcionalidad. Tenemos cientos de directorios. Sería más rápido simplemente ignorar explícitamente los tipos de archivo que no queremos que hacer un gitignore para cada directorio. Realmente estoy buscando una manera de sacar la funcionalidad de la lista blanca del archivo .gitignore.
Nate
1
No veo cómo esto es un duplicado. La otra pregunta es cómo incluir en la lista blanca ciertos archivos, mientras que esta pregunta cómo incluir ciertos tipos de archivos, incluidas las subcarpetas. En realidad, es más como un duplicado de stackoverflow.com/questions/8024924/… .
Big McLargeHuge

Respuestas:

146

Si lo intenta de esa manera, fallará, porque terminará en la lista negra de los directorios de su estructura.

Para resolverlo, desea incluir en la lista negra todo lo que no sea un directorio y no sea uno de los tipos de archivos que desea confirmar, mientras que no incluya directorios .

El .gitignorearchivo que hará esto:

# First, ignore everything
*
# Now, whitelist anything that's a directory
!*/
# And all the file types you're interested in.
!*.one
!*.two
!*.etc

Probé esto en una lista blanca de estructura de tres niveles para .txtarchivos en presencia de *.one, *.twoy *.threearchivos que usan un .gitignoreubicado en el directorio raíz del repositorio, funciona para mí. No tendrá que agregar .gitignorearchivos a todos los directorios de su estructura.

La información que utilicé para averiguar la respuesta provino, entre otras cosas, de esto (stackoverflow.com).

Simont
fuente
18
También necesita la entrada !.gitignore, cuando se usa *, ¿no es así?
sjas
2
Vea mi respuesta aquí: stackoverflow.com/questions/987142/… Puede ser más útil usar /*para incluir en la lista negra solo la carpeta de nivel superior, pero no todas las carpetas de forma recursiva, lo que en realidad significa .gitignoreque no debe buscar en las subcarpetas de una carpeta de la lista blanca.
Ryan Taylor
2

Una forma más sencilla de lograrlo es:

# Ignore all files...
*.*

# ...except the ones we want
!*.txt

Esto funciona porque gitignoreaplica patrones que no comienzan con /a todos los niveles debajo del .gitignorearchivo:

Si hay un separador al principio o en el medio (o ambos) del patrón, entonces el patrón es relativo al nivel de directorio del archivo .gitignore en particular. De lo contrario, el patrón también puede coincidir en cualquier nivel por debajo del nivel .gitignore.

Si quisiera hacer esto con los archivos dentro de un directorio , las cosas se vuelven más complejas:

# Ignore all files in all directories inside subdir...
/subdir/**/*.*

# ...except the ones we want
!/subdir/**/*.txt

Esto funciona porque gitignoretiene reglas especiales para **:

Dos asteriscos consecutivos (" **") en patrones que coincidan con el nombre de ruta completo pueden tener un significado especial:

  • Una barra seguida de dos asteriscos consecutivos y luego una barra que coincide con cero o más directorios. Por ejemplo, " a/**/b" coincide con " a/b", " a/x/b", " a/x/y/b" y así sucesivamente.

La pieza clave es asegurarse de no ignorar los directorios, porque entonces todos los archivos dentro de ese directorio se ignoran independientemente de otras reglas.

Sharadh
fuente
0

Busqué durante mucho tiempo:

  1. Supongamos que tengo una estructura de carpetas grande con ~ 100.000 directorios anidados de forma recursiva. En esas carpetas, hay alrededor de 30.000 archivos de tipo .txt(en mi caso: tipo *.md). Junto a estos *.mdarchivos, hay, digamos, 500 GB de (más de un millón) de archivos que no quiero rastrear.

  2. Quiero que git rastree solo .txt(o *.md) archivos en todas las carpetas y subdirecciones.

La respuesta correcta debería ser: esto no es posible en Git.

Lo que hice en su lugar:

[editar: tampoco funcionó - Traté de crear una carpeta con enlaces simbólicos (o enlaces duros) y usar git allí, pero git no sigue los enlaces simbólicos y sobrescribe los enlaces duros. Doh!]

Alex
fuente