2011-04-19 26 views
90

¿Cómo se pueden ignorar los archivos binarios en git usando el archivo .gitignore?gitignore sin archivos binarios

Ejemplo:

$ g++ hello.c -o hello 

El archivo "Hola" es un archivo binario. ¿Puede git ignorar este archivo?

+0

posible duplicado de [¿Cómo agrego archivos sin puntos en ellos (todos los archivos sin extensión) al archivo gitignore?] (Http://stackoverflow.com/questions/19023550/how-do-i-add- files-without-dots-in-them-all-extension-less-files-to-the-gitign) –

Respuesta

36

añadir algo como

*.o 

en el archivo .gitignore y colocarlo en la raíz de tu repositorio (o se puede colocar en cualquier directorio secundarias que quiera - que será aplicable a partir de ese nivel en) y cheque en

Editar:.

para binarios sin extensión, usted es mejor colocarlos en bin/ o alguna otra carpeta. Después de todo, no hay ignorar en función del tipo de contenido.

Puede intentar

* 
!*.* 

pero eso no es infalible.

+12

'hello' no termina en' .o' ... – delnan

+1

Se agregó editar. ¿Hay alguna razón por la que no quiere que su binario tenga una extensión? – manojlds

+7

Los ejecutables a menudo no tienen extensiones. Estoy tratando de hacer lo mismo aquí para los archivos creados por 'gcc' passing' -o $ @ '. –

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 ponerlos 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 necesarias, pero en Unix, puede o no usar extensiones en los binarios ejecutables. En este caso, puede colocarlos en un bin/carpeta y agregar bin/ a su .gitignore.

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

1

No conozco otra solución, pero las agrego una por una al .gitignore.

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

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

EDITAR

¿Por qué no simplemente nombre que hello.bin ejecutable?

+0

Porque nombrar ejecutables con la extensión de archivo '.bin' es una mala práctica. –

23

para añadir todos los archivos ejecutables en el .gitignore (que probablemente significa "archivo binario" a juzgar por su pregunta), puede utilizar

find . -executable -type f >>.gitignore 

Si no se preocupan por orden de las líneas en su .gitignore , también puede actualizar su .gitignore con el siguiente comando, que también elimina los duplicados y mantiene el orden alfabético intacto.

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

Tenga en cuenta, que no se puede dar salida a la tubería directamente a .gitignore, porque eso sería truncar el archivo antes de cat lo abre para lectura.Además, es posible que desee agregar \! -regex '.*/.*/.*' como una opción para encontrar si no desea incluir archivos ejecutables en subdirectorios.

12

Usted puede tratar en su .gitignore:

* 
!*.c 

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

+2

Sería bueno que al menos enumerara las principales desventajas – pjvds

+0

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

11

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

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

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

%: %.hs 
    ghc $^ 
    grep -xq "[email protected]" .gitignore || echo [email protected] >> .gitignore 

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

+0

Ahora, este es un enfoque diferente. –

4

Aquí hay otra solución para usar el archivo. De esta forma, las secuencias de comandos ejecutables no terminarán en gitignore. Es posible que necesite cambiar la forma en que se interpreta la salida del archivo para que coincida con su sistema. Uno podría entonces configurar un gancho precompromiso para llamar a este script cada vez que se comprometa.

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) 
+0

Hice un script similar y publicado en una pregunta duplicado: http://stackoverflow.com/a/28258619/218294 Su código es más agradable :) mío probablemente se ejecuta más rápido ya que se ejecuta "archivo" sólo una vez, o unas pocas veces (usando xargs). –

3

Una forma de ignorar también en algunos subdirectorio, no sólo 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 sólo algunos tipos específicos de archivos:

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

¡Parece que también puede funcionar como para cada nuevo subdirectorio si lo desea !:

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

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

77
# 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 como un encanto! No entiendo por qué al ignorar todos los directorios "! * /", También se pueden 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

+3

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

2

Sólo tiene que añadir hello o /hello a su .gitignore. Cualquiera de los dos funciona

0

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

/bin 
/pkg 

Ignora todos los desarrollos compilados, actualmente.

0

.gitignore usa glob programming 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 se nombran de acuerdo con el orden en el 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 de origen sin la extensión de acuerdo con la práctica habitual.

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

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

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

Cuestiones relacionadas