¿Cómo se pueden ignorar los archivos binarios al git
usar el .gitignore
archivo?
Ejemplo:
$ g++ hello.c -o hello
El archivo "hola" es un archivo binario. ¿Se puede git
ignorar este archivo?
[^\.]*
.
¿Cómo se pueden ignorar los archivos binarios al git
usar el .gitignore
archivo?
Ejemplo:
$ g++ hello.c -o hello
El archivo "hola" es un archivo binario. ¿Se puede git
ignorar este archivo?
[^\.]*
.
Respuestas:
# 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
!/**/
lugar de !*/
; cual es el correcto / cc @VonC
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.
gcc
pasar -o $@
.
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 .gitignore
con 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 cat
abrirlo para su lectura. Además, es posible que desee agregar \! -regex '.*/.*/.*'
como opción para buscar si no desea incluir archivos ejecutables en subdirectorios.
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 hello
su .gitignore.
Puedes probar en tu .gitignore
:
*
!*.c
Este enfoque tiene muchas desventajas, pero es aceptable para proyectos pequeños.
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.
Los archivos binarios a menudo no tienen extensiones. Si este es tu caso, intenta esto:
*
!/**/
!*.*
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)
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.
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
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.
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
?
.bin
es una mala práctica.
Simplemente agregue hello
o /hello
a su .gitignore. Cualquiera de los dos funciona.
hello
.
Creé un archivo .gitignore con dos entradas en el directorio GOPATH.
/bin
/pkg
Ignora todos los desarrollos compilados, actualmente.
.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.
Basándose en VenomVendors respuesta
# Ignore all
*
# Unignore all files with extensions recursively
!**/*.*
# Unignore Makefiles recursively
!**/Makefile
# other .gitignore rules...
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"
El .gitignore
mecanismo 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 .gitignore
o usar uno apropiado). convenio de denominación).
El hecho de que .gitignore
funcione 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.