gitignore sin archivos binarios


141

¿Cómo se pueden ignorar los archivos binarios al gitusar el .gitignorearchivo?

Ejemplo:

$ g++ hello.c -o hello

El archivo "hola" es un archivo binario. ¿Se puede gitignorar este archivo?



2
Estoy muy sorprendido de que una pregunta tan antigua e importante no tenga una respuesta adecuada. Estoy aún más sorprendido de que la respuesta sea sencilla [^\.]*.
TamaMcGlinn

esto no funciona
timotheecour

Respuestas:


136
# Ignore all
*

# Unignore all with extensions
!*.*

# Unignore all dirs
!*/

### Above combination will ignore all files without extension ###

# Ignore files with extension `.class` & `.sm`
*.class
*.sm

# Ignore `bin` dir
bin/
# or
*/bin/*

# Unignore all `.jar` in `bin` dir
!*/bin/*.jar

# Ignore all `library.jar` in `bin` dir
*/bin/library.jar

# Ignore a file with extension
relative/path/to/dir/filename.extension

# Ignore a file without extension
relative/path/to/dir/anotherfile

1
¡Esta solución funciona a las mil maravillas! No entiendo por qué al ignorar todos los directorios "! * /", ¿También puede ignorar los archivos de subdir con una extensión? (por ejemplo, aaa / bbb.c) pero aún ignora el archivo de subdir sin extensiones. (por ejemplo, aaa / ccc)
dragonxlwang

44
Parece que este método no funciona como se esperaba después de que descubrí que cuando hay varias capas de directorio ...
dragonxlwang

@dragonxlwang Tengo curiosidad de dónde no funcionaría esto? La solución aceptada aquí stackoverflow.com/a/19023985/1426932 es ligeramente diferente y utiliza en !/**/lugar de !*/; cual es el correcto / cc @VonC
timotheecour

Es bastante común en la cultura Unix nombrar scripts de shell así como ejecutables binarios sin extensiones, en cuyo caso esta solución hará que se ignoren los scripts. Una mejor idea es agregar ejecutables binarios a .gitignore manualmente cada vez que se agreguen al proyecto; por lo general, esto no sucede con tanta frecuencia. Si eso es demasiado engorroso, entonces la solución de makefile sugerida por vedantk es mejor.
Peter Helfer

Esto ignorará el archivo MAKE
VMatrix1900

42

Agrega algo como

*.o

en el archivo .gitignore y colóquelo en la raíz de su repositorio (o puede colocarlo en cualquier subdirectorio que desee; se aplicará desde ese nivel en adelante) y regístrelo.

Editar:

Para binarios sin extensión, es mejor colocarlos en bin/alguna otra carpeta. Después de todo, no hay ignorar según el tipo de contenido.

Puedes probar

*
!*.*

Pero eso no es infalible.


1
Edición añadida ¿Hay alguna razón por la que no desea que su binario tenga una extensión
Manojlds

10
Los ejecutables a menudo no tienen extensiones. Estoy tratando de hacer lo mismo aquí para los archivos creados al gccpasar -o $@.
Nathan Lilienthal

29

Para agregar todos los ejecutables a su .gitignore(lo que probablemente quiere decir con "archivo binario" a juzgar por su pregunta), puede usar

find . -executable -type f >>.gitignore

Si no le importa el orden de las líneas en su .gitignore, también puede actualizarlo .gitignorecon el siguiente comando que también elimina los duplicados y mantiene intacto el orden alfabético.

T=$(mktemp); (cat .gitignore; find . -executable -type f | sed -e 's%^\./%%') | sort | uniq >$T; mv $T .gitignore

Tenga en cuenta que no puede canalizar la salida directamente .gitignore, ya que eso truncaría el archivo antes de catabrirlo para su lectura. Además, es posible que desee agregar \! -regex '.*/.*/.*'como opción para buscar si no desea incluir archivos ejecutables en subdirectorios.


23

Su mejor opción con los binarios es darles una extensión que pueda filtrar fácilmente con un patrón estándar o colocarlos en directorios que pueda filtrar a nivel de directorio.

La sugerencia de extensión es más aplicable en Windows, porque las extensiones son estándar y básicamente requeridas, pero en Unix, puede o no usar extensiones en sus archivos binarios ejecutables. En este caso, puede colocarlos en un bin / carpeta y agregarlos bin/a su .gitignore.

En su ejemplo muy específico de pequeño alcance, simplemente puede poner hellosu .gitignore.


15

Puedes probar en tu .gitignore:

*
!*.c

Este enfoque tiene muchas desventajas, pero es aceptable para proyectos pequeños.


3
Sería bueno si menos
enumeras

La desventaja obvia es el orden de las reglas de permiso-denegación, la forma correcta es ignorar solo los archivos no deseados, no rechazarlos todos y luego incluir solo los archivos deseados.
Andrei Beliankou

13

Si está utilizando un archivo MAKE, puede intentar modificar sus reglas de creación para agregar los nombres de los nuevos archivos binarios a su archivo .gitignore.

Aquí hay un Makefile de ejemplo para un pequeño proyecto de Haskell;

all: $(patsubst %.hs, %, $(wildcard *.hs))

%: %.hs
    ghc $^
    grep -xq "$@" .gitignore || echo $@ >> .gitignore

Este archivo MAKE define una regla para crear ejecutables a partir del código Haskell. Después de invocar ghc, verificamos el .gitignore para ver si el binario ya está en él. Si no es así, agregamos el nombre del binario al archivo.


Ahora, este es un enfoque diferente.
René Nyffenegger


5

Aquí hay otra solución usando el archivo. De esta forma, los scripts ejecutables no terminarán en gitignore. Es posible que deba cambiar cómo se interpreta la salida del archivo para que coincida con su sistema. Uno podría configurar un enlace de precompromiso para llamar a este script cada vez que se compromete.

import subprocess, os

git_root = subprocess.check_output(['git', 'root']).decode("UTF-8").strip()
exes = []
cut = len(git_root)

for root, dirnames, filenames in os.walk(git_root+"/src/"):
  for fname in filenames:
    f = os.path.join(root,fname)
    if not os.access(f,os.X_OK):
      continue

    ft = subprocess.check_output(['file', f]).decode("UTF-8")

    if 'ELF' in ft and 'executable' in ft:
      exes.append(f[cut:])

gifiles = [ str.strip(a) for a in open(git_root + "/.gitignore").readlines() ]
gitignore=frozenset(exes+gifiles)

with open(git_root+"/.gitignore", "w") as g:
  for a in sorted(gitignore):
    print(a, file=g)

Hice un script similar y publiqué en una pregunta duplicada: stackoverflow.com/a/28258619/218294 Su código es más bonito :) el mío probablemente se ejecuta más rápido ya que ejecuta "archivo" solo una vez, o unas pocas veces (usando xargs).
Sam Watkins

4

Una forma de ignorar también en algún subdirectorio, no solo en una raíz:

# Ignore everything in a root
/*
# But not files with extension located in a root
!/*.*
# And not my subdir (by name)
!/subdir/
# Ignore everything inside my subdir on any level below
/subdir/**/*
# A bit of magic, removing last slash or changing combination with previous line
# fails everything. Though very possibly it just says not to ignore sub-sub-dirs.
!/subdir/**/
# ...Also excluding (grand-)children files having extension on any level
# below subdir
!/subdir/**/*.*

O, si desea incluir solo algunos tipos específicos de archivos:

/*
!/*.c
!/*.h
!/subdir/
/subdir/**/*
!/subdir/**/
!/subdir/**/*.c
!/subdir/**/*.h

¡Parece que incluso puede funcionar como para cada nuevo subdirectorio si lo desea !:

/*
!/*.c
!/*.h
!/*/
/*/**/*
!/*/**/
!/*/**/*.c
!/*/**/*.h

Las barras diagonales iniciales son importantes solo en las dos primeras líneas y opcionales en otras. La barra oblicua !/*/y !/subdir/también es opcional, pero solo en esta línea.


3

Si sigue estos comandos en su archivo .gitignore y parece que todavía aparecen archivos, puede probar:

git rm --cached FILENAME

Después de eso, agregue su .gitignore, comprométase y presione. Me tomó 40 minutos entender eso, espero que esto ayude a los novatos como yo


2

Hilo antiguo, pero aún relevante. Cambié el archivo MAKE para que el archivo binario resultante después del enlace tenga el nombre [filname]. bin en lugar de solo [filname]. Luego agregué archivos * .bin en el gitignore.
Esta rutina satisface mis necesidades.


1

No conozco ninguna otra solución, pero agregarlas una por una .gitignore.

Una forma cruda de probar es grep la salida del comando de archivo:

find . \( ! -regex '.*/\..*' \) -type f | xargs -n 1 file | egrep "ASCII|text"

EDITAR

¿Por qué no nombras simplemente tu ejecutable hello.bin?


Porque nombrar ejecutables con la extensión de archivo .bines una mala práctica.
MD XF


0

Creé un archivo .gitignore con dos entradas en el directorio GOPATH.

/bin
/pkg

Ignora todos los desarrollos compilados, actualmente.


0

.gitignore usa programación global para filtrar archivos, al menos en Linux.

Estoy a punto de dar una charla de codificación en un Meetup y, en preparación, hice un directorio con varios subdirectorios que están nombrados de acuerdo con el orden en que quiero presentarlos: 01_subject1, 02_subject2, 03_subject3. Cada subdirectorio contiene un archivo fuente con una extensión dependiente del idioma que se compila en un archivo ejecutable cuyo nombre coincide con el nombre del archivo fuente sin la extensión de acuerdo con la práctica común.

Excluyo los archivos compilados en los directorios con prefijo numérico con la siguiente línea .gitignore:

[0-9][0-9]_*/[!\.]*

Según mi comprensión de la documentación, no debería funcionar. Tener el asterisco final debe fallar porque debe coincidir con cualquier número de caracteres no especificados, incluido el '.' + extensión. Omitir el asterisco final debería fallar (y lo hace) porque [!\.]solo coincide con un único carácter que no sea punto. Sin embargo, agregué el asterisco final, como lo haría para una expresión regular, y funciona. Por trabajo, quiero decir que git nota cambios en el archivo fuente, pero no la existencia o cambios en los archivos compilados.



0

Agregue lo siguiente a su archivo .gitignore:

[^\.]*

Explicación:

[] encloses a character class, e.g. [a-zA-Z] means "any letter".
^  means "not"
\. means a literal dot - without the backslash . means "any character"
*  means "any number of these characters"

0

El .gitignoremecanismo funciona solo en función de los nombres de los archivos , no en el contenido de los archivos . Ser un archivo binario es una propiedad del contenido, por lo tanto, no puede pedirle a git que ignore los archivos binarios directamente, sino solo que los ignore por su nombre (y, como se sugirió, puede agregar todos los nombres de archivos binarios a su nombre .gitignoreo usar uno apropiado). convenio de denominación).

El hecho de que .gitignorefuncione con nombres de archivos es una propiedad importante en cuanto al rendimiento: Git solo necesita enumerar archivos, pero no abrirlos y leerlos para saber qué archivos ignorar. En otras palabras, Git sería terriblemente lento si pudieras pedirle que ignore los archivos en función de su contenido.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.