gitignore senza file binari


141

Come si possono ignorare i file binari gitusando il .gitignorefile?

Esempio:

$ g++ hello.c -o hello

Il file "ciao" è un file binario. Puoi gitignorare questo file?



2
Sono molto sorpreso che una domanda così antica e importante non abbia una risposta adeguata. Sono ancora più sorpreso che la risposta sia semplice [^\.]*.
TamaMcGlinn,

questo non funziona
timotheecour

Risposte:


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
Questa soluzione funziona come un fascino! Non capisco perché unignore di tutte le directory "! * /", Possa anche unignore i file di subdir con un'estensione? (es. aaa / bbb.c) ma ignora comunque il file di subdir senza estensioni. (ad esempio aaa / ccc)
dragonxlwang

4
Sembra che questo metodo non funzioni come previsto dopo che ho scoperto che quando ci sono più livelli di directory ...
dragonxlwang

@dragonxlwang Sono curioso di sapere dove non funzionerebbe? La soluzione accettata qui stackoverflow.com/a/19023985/1426932 è leggermente diversa e utilizza !/**/invece di !*/; quale è corretto? / cc @VonC
timourecour

È abbastanza comune nella cultura Unix nominare script di shell e file eseguibili binari senza estensioni, nel qual caso questa soluzione farà ignorare gli script. Un'idea migliore è quella di aggiungere manualmente eseguibili binari a .gitignore ogni volta che vengono aggiunti al progetto - in genere non succede così spesso. Se è troppo ingombrante, allora la soluzione di makefile suggerita da vedantk è migliore.
Peter Helfer,

Questo ignorerà makefile
VMatrix1900 il

42

Aggiungi qualcosa di simile

*.o

nel file .gitignore e posizionalo nella radice del tuo repository (oppure puoi inserirlo in qualsiasi sottodirectory che desideri - si applicherà da quel livello in poi) e archiviarlo.

Modificare:

Per i binari senza estensione, è meglio posizionarli in bin/un'altra cartella. Dopotutto non è possibile ignorare in base al tipo di contenuto.

Puoi provare

*
!*.*

ma questo non è infallibile.


1
Aggiunta modifica. C'è qualche motivo per cui non vuoi che il tuo binario abbia un'estensione
Manojlds,

10
Gli eseguibili spesso non hanno estensioni. Sto provando a fare la stessa cosa qui per i file creati gccpassando -o $@.
Nathan Lilienthal,

29

Per aggiungere tutti i file eseguibili al tuo .gitignore(che probabilmente intendi per "file binario" a giudicare dalla tua domanda), puoi usare

find . -executable -type f >>.gitignore

Se non ti interessa ordinare le linee nel tuo .gitignore, potresti anche aggiornare il tuo .gitignorecon il seguente comando che rimuove anche i duplicati e mantiene intatto l'ordine alfabetico.

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

Si noti che non è possibile reindirizzare direttamente l'output .gitignore, poiché ciò troncerebbe il file prima di cataprirlo per la lettura. Inoltre, potresti voler aggiungere \! -regex '.*/.*/.*'un'opzione per trovare se non vuoi includere file eseguibili nelle sottodirectory.


23

La tua scommessa migliore con i binari è quella di dare loro un'estensione che puoi facilmente filtrare con uno schema standard, o metterli in directory che puoi filtrare a livello di directory.

Il suggerimento di estensione è più applicabile in Windows, poiché le estensioni sono standard e fondamentalmente richieste, ma in Unix è possibile o meno utilizzare estensioni nei file binari eseguibili. In questo caso, puoi metterli in un bin / cartella e aggiungerli bin/al tuo .gitignore.

Nel tuo esempio molto specifico, di portata ridotta, puoi semplicemente inserire il hellotuo .gitignore.


15

Puoi provare nel tuo .gitignore:

*
!*.c

Questo approccio presenta molti svantaggi, ma è accettabile per piccoli progetti.


3
Sarebbe bello se almeno
elencassi

L'ovvio svantaggio è l'ordine delle regole di autorizzazione, il modo corretto è quello di ignorare solo i file indesiderati, di non vietare tutti e quindi di includere solo i file desiderati.
Andrei Beliankou,

13

Se stai usando un makefile, potresti provare a modificare le tue regole di make per aggiungere i nomi di nuovi binari al tuo file .gitignore.

Ecco un Makefile di esempio per un piccolo progetto Haskell;

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

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

Questo makefile definisce una regola per la creazione di eseguibili dal codice Haskell. Dopo aver richiamato ghc, controlliamo il file .gitignore per vedere se il binario è già in esso. In caso contrario, aggiungiamo il nome del file binario al file.


Questo è un approccio diverso.
René Nyffenegger,


5

Ecco un'altra soluzione che utilizza il file. In questo modo gli script eseguibili non finiranno in gitignore. Potrebbe essere necessario modificare il modo in cui l'output del file viene interpretato in base al sistema in uso. Si potrebbe quindi impostare un hook pre-commit per chiamare questo script ogni volta che si commette.

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)

Ho creato uno script simile e pubblicato una domanda duplicata: stackoverflow.com/a/28258619/218294 Il tuo codice è più bello :) il mio probabilmente corre più veloce poiché esegue "file" solo una volta o alcune volte (usando xargs).
Sam Watkins,

4

Un modo per ignorare anche in alcuni sottodir, non solo in una radice:

# 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/**/*.*

Oppure, se si desidera includere solo alcuni tipi specifici di file:

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

Sembra che potrebbe anche funzionare come per ogni nuova sottodirectory, se vuoi !:

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

Le barre iniziali sono importanti solo nelle prime due righe e facoltative nelle altre. Tailing barra in !/*/ed !/subdir/è opzionale, ma solo in questa linea.


3

Se segui questi comandi sul tuo file .gitignore e i file sembrano ancora apparire, potresti provare:

git rm --cached FILENAME

Successivamente, aggiungi il tuo .gitignore, esegui il commit e il push. Mi ci sono voluti 40 minuti per capirlo, spero che questo aiuti ai neofiti come me


2

Vecchio thread, ma ancora rilevante. Ho modificato il makefile in modo che il file binario risultante dopo il collegamento abbia il nome [nomefile]. bin anziché solo [nome file]. Quindi ho aggiunto i file * .bin in gitignore.
Questa routine soddisfa i miei bisogni.


1

Non conosco altre soluzioni, ma aggiungendole una ad una a .gitignore.

Un modo grezzo per testare è grep l'output del comando file:

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

MODIFICARE

Perché non ti chiami semplicemente eseguibile hello.bin?


Perché la denominazione degli eseguibili con l'estensione del file .binè una cattiva pratica.
MD XF,


0

Ho creato un file .gitignore con due voci nella directory GOPATH.

/bin
/pkg

Attualmente ignora tutti gli sviluppi compilati.


0

.gitignore utilizza la programmazione glob per filtrare i file, almeno su Linux.

Sto per tenere un discorso di programmazione in un Meetup e, in preparazione, ho creato una directory con diverse sottodirectory che sono nominate in base all'ordine che voglio presentarle: 01_subject1, 02_subject2, 03_subject3. Ogni sottodirectory contiene un file di origine con un'estensione dipendente dalla lingua che viene compilata in un file eseguibile il cui nome corrisponde al nome del file di origine senza l'estensione secondo la prassi comune.

Escludo i file compilati nelle directory con prefisso numerale con la seguente riga .gitignore:

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

Secondo la mia comprensione della documentazione, non dovrebbe funzionare. Avere l'asterisco finale dovrebbe fallire perché dovrebbe corrispondere a qualsiasi numero di caratteri non specificati, incluso il '.' + estensione. L'omissione dell'asterisco finale dovrebbe fallire (e lo fa) perché [!\.]corrisponde a un solo carattere non punto. Tuttavia, ho aggiunto l'asterisco finale, come farei per un'espressione regolare, e funziona. Per lavoro, intendo che git nota le modifiche al file sorgente, ma non l'esistenza o le modifiche ai file compilati.



0

Aggiungi quanto segue al tuo file .gitignore:

[^\.]*

Spiegazione:

[] 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

Il .gitignoremeccanismo funziona solo in base ai nomi dei file , non al contenuto dei file . Essere un file binario è una proprietà del contenuto, quindi non puoi chiedere a git di ignorare direttamente i file binari, ma solo di ignorarli per nome (e come altri hanno suggerito, puoi aggiungere tutti i nomi di file binari al tuo .gitignoreo usare un appropriato convenzione di denominazione).

Il fatto che .gitignorefunzioni sui nomi dei file è un'importante proprietà dal punto di vista delle prestazioni: Git deve solo elencare i file, ma non aprirli e leggerli per sapere quali file ignorare. In altre parole, Git sarebbe terribilmente lento se potessi chiedergli di ignorare i file in base al loro contenuto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.