Wie können Binärdateien bei der git
Verwendung der .gitignore
Datei ignoriert werden ?
Beispiel:
$ g++ hello.c -o hello
Die "Hallo" -Datei ist eine Binärdatei. Kann git
diese Datei ignorieren?
[^\.]*
.
Wie können Binärdateien bei der git
Verwendung der .gitignore
Datei ignoriert werden ?
Beispiel:
$ g++ hello.c -o hello
Die "Hallo" -Datei ist eine Binärdatei. Kann git
diese Datei ignorieren?
[^\.]*
.
Antworten:
# 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
!/**/
anstelle von verwendet !*/
. Welches ist korrekt? / cc @VonC
Fügen Sie so etwas hinzu
*.o
in der .gitignore-Datei und platzieren Sie es im Stammverzeichnis Ihres Repos (oder Sie können es in einem beliebigen Unterverzeichnis ablegen - es gilt ab dieser Ebene) und checken Sie es ein.
Bearbeiten:
Bei Binärdateien ohne Erweiterung sollten Sie sie besser in bin/
einem anderen Ordner ablegen. Immerhin gibt es kein Ignorieren basierend auf dem Inhaltstyp.
Du kannst es versuchen
*
!*.*
aber das ist nicht kinderleicht.
gcc
Übergeben erstellt wurden -o $@
.
Um alle ausführbaren Dateien an Ihre anzuhängen .gitignore
(was Sie wahrscheinlich mit "Binärdatei" meinen, gemessen an Ihrer Frage), können Sie verwenden
find . -executable -type f >>.gitignore
Wenn Sie sich nicht für die Reihenfolge der Zeilen in Ihrem interessieren .gitignore
, können Sie Ihre auch .gitignore
mit dem folgenden Befehl aktualisieren, der auch Duplikate entfernt und die alphabetische Reihenfolge beibehält.
T=$(mktemp); (cat .gitignore; find . -executable -type f | sed -e 's%^\./%%') | sort | uniq >$T; mv $T .gitignore
Beachten Sie, dass Sie die Ausgabe nicht direkt an weiterleiten können .gitignore
, da dadurch die Datei abgeschnitten wird, bevor cat
sie zum Lesen geöffnet wird. Möglicherweise möchten Sie \! -regex '.*/.*/.*'
auch eine Option hinzufügen, um festzustellen, ob Sie keine ausführbaren Dateien in Unterverzeichnisse aufnehmen möchten.
Bei Binärdateien ist es am besten, ihnen entweder eine Erweiterung zu geben, die Sie einfach mit einem Standardmuster herausfiltern können, oder sie in Verzeichnisse zu legen, die Sie auf Verzeichnisebene herausfiltern können.
Der Erweiterungsvorschlag ist in Windows besser anwendbar, da Erweiterungen Standard sind und grundsätzlich erforderlich sind. Unter Unix können Sie jedoch Erweiterungen für Ihre ausführbaren Binärdateien verwenden oder nicht. In diesem Fall können Sie sie in einen Bin / Ordner legen und bin/
Ihrem .gitignore hinzufügen .
In Ihrem sehr spezifischen Beispiel mit kleinem Umfang können Sie einfach hello
Ihren .gitignore eingeben.
Sie können versuchen in Ihrem .gitignore
:
*
!*.c
Dieser Ansatz hat viele Nachteile, ist jedoch für kleine Projekte akzeptabel.
Wenn Sie ein Makefile verwenden, können Sie versuchen, Ihre Make-Regeln zu ändern, um die Namen neuer Binärdateien an Ihre Gitignore-Datei anzuhängen.
Hier ist ein Beispiel für ein Makefile für ein kleines Haskell-Projekt.
all: $(patsubst %.hs, %, $(wildcard *.hs))
%: %.hs
ghc $^
grep -xq "$@" .gitignore || echo $@ >> .gitignore
Dieses Makefile definiert eine Regel zum Erstellen ausführbarer Dateien aus Haskell-Code. Nachdem ghc aufgerufen wurde, überprüfen wir den .gitignore, um festzustellen, ob die Binärdatei bereits darin enthalten ist. Ist dies nicht der Fall, hängen wir den Namen der Binärdatei an die Datei an.
Binärdateien sind oft ohne Erweiterungen. Wenn dies Ihr Fall ist, versuchen Sie Folgendes:
*
!/**/
!*.*
Hier ist eine andere Lösung mit Datei. Auf diese Weise landen ausführbare Skripte nicht in gitignore. Möglicherweise müssen Sie die Interpretation der Dateiausgabe an Ihr System anpassen. Sie können dann einen Pre-Commit-Hook einrichten, um dieses Skript bei jedem Commit aufzurufen.
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)
Eine Möglichkeit, auch in einigen Unterverzeichnissen zu ignorieren, nicht nur in einer Wurzel:
# 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/**/*.*
Oder wenn Sie nur bestimmte Dateitypen einschließen möchten:
/*
!/*.c
!/*.h
!/subdir/
/subdir/**/*
!/subdir/**/
!/subdir/**/*.c
!/subdir/**/*.h
Scheint, als könnte es sogar für jedes neue Unterverzeichnis funktionieren, wenn Sie wollen!:
/*
!/*.c
!/*.h
!/*/
/*/**/*
!/*/**/
!/*/**/*.c
!/*/**/*.h
Führende Schrägstriche sind nur in den ersten beiden Zeilen wichtig und in anderen optional. Tailing Slash In !/*/
und !/subdir/
ist ebenfalls optional, jedoch nur in dieser Zeile.
Wenn Sie diese Befehle in Ihrer .gitignore-Datei befolgen und die Dateien weiterhin angezeigt werden, möchten Sie möglicherweise Folgendes versuchen:
git rm --cached FILENAME
Fügen Sie danach Ihren .gitignore hinzu, legen Sie fest und drücken Sie. Ich habe 40 Minuten gebraucht, um das zu verstehen. Ich hoffe, das hilft Neulingen wie mir
Alter Thread, aber immer noch relevant. Ich habe das Makefile so geändert, dass die resultierende Binärdatei nach dem Verknüpfen den Namen [Dateiname] hat. bin statt nur [filname]. Dann habe ich * .bin-Dateien im Gitignore hinzugefügt.
Diese Routine erfüllt meine Bedürfnisse.
Ich kenne keine andere Lösung, als sie einzeln hinzuzufügen .gitignore
.
Eine grobe Methode zum Testen besteht darin, die Ausgabe des Dateibefehls zu überprüfen:
find . \( ! -regex '.*/\..*' \) -type f | xargs -n 1 file | egrep "ASCII|text"
BEARBEITEN
Warum benennst du dich nicht einfach ausführbar hello.bin
?
.bin
eine schlechte Praxis ist.
Fügen Sie einfach hello
oder /hello
zu Ihrem .gitignore. Entweder funktioniert.
hello
.
Ich habe eine Gitignore-Datei mit zwei Einträgen im GOPATH-Verzeichnis erstellt.
/bin
/pkg
Derzeit werden alle kompilierten Entwicklungen ignoriert.
.gitignore verwendet Glob-Programmierung , um Dateien zu filtern, zumindest unter Linux.
Ich bin dabei, bei einem Meetup einen Codierungsvortrag zu halten, und habe in Vorbereitung ein Verzeichnis mit mehreren Unterverzeichnissen erstellt, die in der Reihenfolge benannt sind, in der ich sie präsentieren möchte: 01_subject1, 02_subject2, 03_subject3. Jedes Unterverzeichnis enthält eine Quelldatei mit einer sprachabhängigen Erweiterung, die zu einer ausführbaren Datei kompiliert wird, deren Name mit dem Namen der Quelldatei ohne die Erweiterung gemäß der gängigen Praxis übereinstimmt.
Ich schließe die kompilierten Dateien in den Verzeichnissen mit vorangestellten Ziffern mit der folgenden .gitignore-Zeile aus:
[0-9][0-9]_*/[!\.]*
Nach meinem Verständnis der Dokumentation sollte es nicht funktionieren. Das nachfolgende Sternchen sollte fehlschlagen, da es mit einer beliebigen Anzahl nicht angegebener Zeichen übereinstimmen sollte, einschließlich des '.' + Erweiterung. Das Weglassen des nachfolgenden Sterns sollte fehlschlagen (und tut dies auch), da [!\.]
nur ein einzelnes Zeichen ohne Punkt übereinstimmt. Ich habe jedoch das abschließende Sternchen hinzugefügt, wie ich es für einen regulären Ausdruck tun würde, und es funktioniert. Mit Arbeit meine ich, dass Git Änderungen an der Quelldatei bemerkt, aber nicht die Existenz oder Änderungen an den kompilierten Dateien.
Aufbauend auf der Antwort von VenomVendors
# Ignore all
*
# Unignore all files with extensions recursively
!**/*.*
# Unignore Makefiles recursively
!**/Makefile
# other .gitignore rules...
Fügen Sie Ihrer .gitignore-Datei Folgendes hinzu:
[^\.]*
Erläuterung:
[] 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"
Der .gitignore
Mechanismus funktioniert auf Datei nur anhand Namen , nicht auf Dateiinhalte . Eine Binärdatei zu sein ist eine Eigenschaft des Inhalts, daher können Sie git nicht bitten, Binärdateien direkt zu ignorieren, sondern sie nur nach Namen zu ignorieren (und wie andere vorgeschlagen, können Sie entweder alle Binärdateinamen zu Ihren hinzufügen.gitignore
oder eine geeignete verwenden Namenskonvention).
Die Tatsache, dass .gitignore
mit Dateinamen gearbeitet wird, ist eine wichtige Eigenschaft in Bezug auf die Leistung: Git muss nur Dateien auflisten, aber nicht öffnen und lesen, um zu wissen, welche Dateien ignoriert werden sollen. Mit anderen Worten, Git wäre furchtbar langsam, wenn Sie ihn bitten könnten, Dateien aufgrund ihres Inhalts zu ignorieren.