¿Cuál es la diferencia entre añadir bin, bin/, bin/*y bin/**en mi archivo .gitignore? He estado usando bin/, pero mirando otros archivos .gitignore (en el archivo de eclipse, la estrella doble y la única se usan juntas de esta manera: tmp/**/*¿qué pasa con eso?) Veo que los dos primeros patrones también se usan ampliamente. ¿Alguien puede explicar las diferencias entre los tres?
89

**: stackoverflow.com/questions/1470572/…Respuestas:
bincoincide con cualquier archivo o directorio llamado 'bin'.bin/coincide con cualquier directorio llamado 'bin', lo que en efecto significa todo su contenido ya que Git no rastrea los directorios solo.bin/*coincide con todos los archivos y directorios directamente en cualquierbin/. Esto evita que Git encuentre automáticamente archivos en sus subdirectorios, pero si, digamos,bin/foose crea un subdirectorio, esta regla no coincidirá confooel contenido.bin/**coincide con todos los archivos y directorios de cualquierbin/directorio y todos sus subdirectorios.La palabra "cualquiera" es fundamental aquí, ya que las reglas no son relativas a la raíz del repositorio y se aplican en cualquier parte del árbol del sistema de archivos. Debe comenzar las reglas con a
/(o!/dejar de ignorar) lo que significa la raíz del repositorio, no la raíz del sistema, para que coincida solo con lo que se pretendía.ADVERTENCIA: Usted debe no utilizar reglas como
dir/*,/dir/**, etc. solos a menos que también Dejar de ignorar algo que existe dentro de ese directorio . Omita el asterisco o podría perder permanentemente muchos datos de ciertas invocaciones degit gc,git stashy más.Realmente no sé qué
tmp/**/*se supone que debo hacer. Inicialmente pensé que podría usarse para hacer coincidir archivos en los subdirectorios,tmp/pero no archivos directamente presentes entmp/sí mismo. Pero una prueba simple parece sugerir que esto ignora todos los archivos en formatotmp/.fuente
bin/ybin/**?bin/que ignorará el directorio bin, mientrasbin/**que incluirá el directorio bin pero no ninguno de sus contenidosbin/ignorará el directorio en sí (incluidos todos los subdirectorios y archivos), mientrasbin/**que ignorará todos los archivos en el directorio bin y sus subdirectorios, pero no el directorio bin en sí. Si eso es exacto o no, no estoy seguro.bin/** \n !bin/*(ya que no veo cómo forzar un salto de línea en mini-Markdown)binlos partidos tanto un archivo con el nombrebiny el contenido de labincarpeta. En tercer lugar,bin/*coincide con los archivos de sus subdirectorios. ¿Ustedes siquiera probaron esto?binybin/difieren solo en que este último solo coincidirá con un directorio.bin/**/*es el mismo quebin/**(aparentemente desde 1.8.2, según la respuesta de @ VonC).El asunto difícil, que me acaba de pasar una hora o así que rasga mi pelo otra vez, es que
bin/ybin/**no son absolutamente lo mismo! Dado que el primero ignora el directorio como un todo, y el segundo ignora cada uno de los archivos dentro de él, y a git en casi todos los casos no le importan los directorios, normalmente no hay diferencia. Sin embargo, si intenta!anular el ignorar una subruta, encontrará que git (ejem) la ignora si ignora el directorio principal. (de nuevo, en lugar del contenido del directorio)Esto es más claro con el ejemplo, por lo que para un repositorio recién iniciado configurado así:
Existen los siguientes archivos sin seguimiento:
Pero puede ver que los siguientes archivos no se ignoran:
Y si intentas agregar, obtienes:
Considero este comportamiento un error. (Todo esto está encendido
git version 1.8.4.msysgit.0)fuente
dir/ydir/**re. no ignorar con!ocurre porque "No es posible volver a incluir un archivo si se excluye un directorio principal de ese archivo" [fuente ]. Confuso, pero hecho por motivos de rendimiento. Consulte una pregunta de SO relacionada .Tenga en cuenta que, estrictamente hablando, git no rastrea directorios, solo archivos. Por lo tanto, no es posible agregar un directorio, solo su contenido .
En el contexto de
.gitignoresin embargo, git pretende entender los directorios por la única razón de que¿Qué significa esto para los patrones de exclusión? Veámoslos en detalle:
binEsto ignora
bin.binPuede
binincluir en la lista blanca archivos y carpetas ignorados agregando!entradas posteriores , pero no puede incluir en la lista blanca el contenido de las carpetas nombradasbinbin/Igual que el anterior, excepto que no coincide con los archivos nombrados
bin. Agregar un final/le dice a git que coincida solo con los directorios.bin/*Esto ignora
binbinbin/**Esto ignora
binbinfuente
Acabo de hacer un nuevo repositorio y probé algunas cosas. Aquí están mis resultados:
NUEVOS RESULTADOS
git versión 2.10.1.windows.1
bindirectorio con varias capas de profundidadbin.txtTest.txtbin/a/b/bin.txtbin/a/b/Test.txtbin/a/bin/bin.txtbin/a/bin/Test.txtbin/a/bin.txtbin/a/Test.txtbin/bin.txtbin/Test.txtbina gitignore: Resultadosbindirectorio (y más profundo) ahora se ignorabinabin/la gitignore: Resultadosbin/parabin/*bin/*parabin/**bin/**parabin/**/bin/bin.txtybin/Test.txtya no son ignoradosbin/**/parabin/**/*bin/bin.txtybin/Test.txtvuelven a ser ignoradosANTIGUOS RESULTADOS
versión de git: 2.7.0.windows.1
bindirectorio con varias capas de profundidadbin/a/b/Test.txtbin/a/bin/Test.txtbin/a/Test.txtbin/Test.txtbina gitignore: Resultadosbindirectorio (y más profundo) ahora se ignorabinabin/la gitignore: Resultadosbindirectorio (y más profundo) aún se ignora (sin cambios)bin/parabin/*bindirectorio (y más profundo) aún se ignora (sin cambios)bin/*parabin/**bindirectorio (y más profundo) aún se ignora (sin cambios)bin/**parabin/**/bin/Test.txtya no se ignorabin/**/parabin/**/*bindirectorio (y más profundo) se ignora nuevamentefuente
Tenga en cuenta que '
**', cuando se combina con un subdirectorio (**/bar), debe haber cambiado de su comportamiento predeterminado, ya que la nota de la versión de git1.8.2 ahora menciona:La regla a recordar (y que ayuda a comprender la diferencia de intenciones detrás de esa sintaxis) es:
No es posible volver a incluir un archivo si se excluye un directorio principal de ese archivo.
Normalmente, si desea excluir archivos de una subcarpeta de una carpeta ignorada f, debería hacer:
Es decir:
f/, la carpetaf/se ignoraría y las reglas siguientesfno importarían.f/**lograr lo mismo quef/, pero ignorar todos los subelementos (archivos y subcarpetas).Eso le da la oportunidad a la lista blanca (excluir de gitignore) las subcarpetas:
!f/**/.fsubcarpetas , puede agregar una regla para excluir un archivo ( )!f/a/sub/folder/someFile.txtfuente
Hay otra diferencia entre
bin/*ybin/.bin/coincidefoo/bin/test.txt(como se esperaba), perobin/*no, lo que parece extraño, pero está documentado: https://git-scm.com/docs/gitignoreLa razón de esto parece ser estas reglas:
Entonces, si el patrón termina con una barra, la barra se elimina y se trata como un patrón de shell glob, en cuyo caso
bincoincidefoo/bin/test.txt. Si termina con/*, la barra no se elimina y se pasa a fnmatch, que no coincide en los subdirectorios.Sin embargo, no ocurre lo mismo con
foo/bin/yfoo/bin/*, porque incluso después de eliminar la barra inclinadafoo/bin/, todavía contiene una barra, por lo que se trata como un patrón fnmatch, no como un glob. Es decir, no coincidirábar/foo/bin/test.txtfuente