Jak można ignorować pliki binarne podczas git
korzystania z .gitignore
pliku?
Przykład:
$ g++ hello.c -o hello
Plik „hello” jest plikiem binarnym. Czy można git
zignorować ten plik?
[^\.]*
.
Jak można ignorować pliki binarne podczas git
korzystania z .gitignore
pliku?
Przykład:
$ g++ hello.c -o hello
Plik „hello” jest plikiem binarnym. Czy można git
zignorować ten plik?
[^\.]*
.
Odpowiedzi:
# 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
!/**/
zamiast !*/
; który jest prawidłowy? / cc @VonC
Dodaj coś takiego jak
*.o
w pliku .gitignore i umieść go w katalogu głównym repozytorium (lub możesz umieścić go w dowolnym podkatalogu - będzie obowiązywał od tego poziomu) i zaewidencjonuj.
Edytować:
W przypadku plików binarnych bez rozszerzenia lepiej umieścić je w bin/
lub innym folderze. W końcu nie ma ignorowania w oparciu o typ zawartości.
Możesz spróbować
*
!*.*
ale to nie jest niezawodne.
gcc
przekazanie -o $@
.
Aby dołączyć wszystkie pliki wykonywalne do swojego .gitignore
(co prawdopodobnie rozumiesz przez „plik binarny”, sądząc po pytaniu), możesz użyć
find . -executable -type f >>.gitignore
Jeśli nie zależy Ci na kolejności wierszy w Twoim .gitignore
, możesz również zaktualizować swój .gitignore
za pomocą następującego polecenia, które również usuwa duplikaty i zachowuje nienaruszoną kolejność alfabetyczną.
T=$(mktemp); (cat .gitignore; find . -executable -type f | sed -e 's%^\./%%') | sort | uniq >$T; mv $T .gitignore
Zauważ, że nie możesz potokować wyjścia bezpośrednio do .gitignore
, ponieważ spowodowałoby to obcięcie pliku przed cat
otwarciem go do odczytu. Możesz również dodać \! -regex '.*/.*/.*'
jako opcję, aby znaleźć, jeśli nie chcesz umieszczać plików wykonywalnych w podkatalogach.
Najlepszym rozwiązaniem w przypadku plików binarnych jest albo nadanie im rozszerzenia, które można łatwo odfiltrować za pomocą standardowego wzorca, albo umieszczenie ich w katalogach, które można odfiltrować na poziomie katalogu.
Sugestia rozszerzenia jest bardziej odpowiednia w systemie Windows, ponieważ rozszerzenia są standardowe i zasadniczo wymagane, ale w systemie Unix możesz lub nie używać rozszerzeń w plikach wykonywalnych. W takim przypadku możesz umieścić je w koszu / folderze i dodać bin/
do swojego .gitignore.
W swoim bardzo szczegółowym przykładzie o małym zakresie możesz po prostu wstawić hello
plik .gitignore.
Możesz spróbować w .gitignore
:
*
!*.c
Takie podejście ma wiele wad, ale jest akceptowalne w przypadku małych projektów.
Jeśli używasz pliku makefile, możesz spróbować zmodyfikować reguły make, aby dodać nazwy nowych plików binarnych do pliku .gitignore.
Oto przykład Makefile dla małego projektu Haskell;
all: $(patsubst %.hs, %, $(wildcard *.hs))
%: %.hs
ghc $^
grep -xq "$@" .gitignore || echo $@ >> .gitignore
Ten plik makefile definiuje regułę tworzenia plików wykonywalnych z kodu Haskell. Po wywołaniu ghc sprawdzamy plik .gitignore, aby zobaczyć, czy plik binarny już się w nim znajduje. Jeśli tak nie jest, dodajemy nazwę pliku binarnego do pliku.
Pliki binarne często nie mają rozszerzeń. Jeśli tak jest w Twoim przypadku, spróbuj tego:
*
!/**/
!*.*
ODNIESIENIE: https://stackoverflow.com/a/19023985/1060487
Oto inne rozwiązanie wykorzystujące plik. W ten sposób wykonywalne skrypty nie trafią do gitignore. Być może będziesz musiał zmienić sposób interpretacji danych wyjściowych z pliku, aby pasował do twojego systemu. Można wtedy ustawić hak przed zatwierdzeniem, aby wywoływać ten skrypt za każdym razem, gdy zatwierdzasz.
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)
Sposób na ignorowanie w jakimś podkatalogu, nie tylko w katalogu głównym:
# 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/**/*.*
Lub, jeśli chcesz uwzględnić tylko określone typy plików:
/*
!/*.c
!/*.h
!/subdir/
/subdir/**/*
!/subdir/**/
!/subdir/**/*.c
!/subdir/**/*.h
Wygląda na to, że może nawet działać tak, jak dla każdego nowego podkatalogu, jeśli chcesz !:
/*
!/*.c
!/*.h
!/*/
/*/**/*
!/*/**/
!/*/**/*.c
!/*/**/*.h
Ukośniki wiodące są ważne tylko w pierwszych dwóch wierszach i opcjonalne w pozostałych. Tailing slash in !/*/
i !/subdir/
jest również opcjonalny, ale tylko w tej linii.
Jeśli wykonasz te polecenia w pliku .gitignore, a pliki nadal wydają się pojawiać, możesz spróbować:
git rm --cached FILENAME
Następnie dodaj swój .gitignore, zatwierdź i wciśnij. Zrozumienie tego zajęło mi 40 minut, mam nadzieję, że pomoże to nowicjuszom takim jak ja
Stary wątek, ale nadal aktualny. Zmieniłem plik makefile, więc wynikowy plik binarny po dowiązaniu ma nazwę [nazwa pliku]. bin zamiast tylko [nazwa pliku]. Następnie dodałem pliki * .bin w gitignore.
Ta rutyna spełnia moje potrzeby.
Nie znam innego rozwiązania, ale dodam je pojedynczo do .gitignore
.
Prostym sposobem testowania jest grepowanie danych wyjściowych polecenia pliku:
find . \( ! -regex '.*/\..*' \) -type f | xargs -n 1 file | egrep "ASCII|text"
EDYTOWAĆ
Dlaczego po prostu nie nazwiesz swojego pliku wykonywalnego hello.bin
?
.bin
jest złą praktyką.
Po prostu dodaj hello
lub /hello
do swojego .gitignore. Albo działa.
hello
.
Utworzyłem plik .gitignore z dwoma wpisami w katalogu GOPATH.
/bin
/pkg
Obecnie ignoruje wszystkie skompilowane zmiany.
.gitignore używa programowania globalnego do filtrowania plików, przynajmniej w Linuksie.
Mam zamiar wygłosić wykład na temat kodowania na Meetupie i w ramach przygotowań stworzyłem katalog zawierający kilka podkatalogów, które są nazwane zgodnie z kolejnością, w jakiej chcę je przedstawić: 01_subject1, 02_subject2, 03_subject3. Każdy podkatalog zawiera plik źródłowy z rozszerzeniem zależnym od języka, który zgodnie z powszechną praktyką kompiluje się do pliku wykonywalnego, którego nazwa jest zgodna z nazwą pliku źródłowego bez rozszerzenia.
Wykluczam skompilowane pliki w katalogach z prefiksem liczbowym z następującą linią .gitignore:
[0-9][0-9]_*/[!\.]*
Zgodnie z moim rozumieniem dokumentacji to nie powinno działać. Gwiazdka na końcu powinna zakończyć się niepowodzeniem, ponieważ powinna pasować do dowolnej liczby nieokreślonych znaków, w tym „.” + rozszerzenie. Pominięcie końcowej gwiazdki powinno zakończyć się niepowodzeniem (i nie działa), ponieważ [!\.]
dopasowuje tylko jeden znak bez kropki. Jednak dodałem końcową gwiazdkę, tak jak w przypadku wyrażenia regularnego i to działa. Przez pracę rozumiem, że git zauważa zmiany w pliku źródłowym, ale nie zauważa istnienia lub zmian w skompilowanych plikach.
Opierając się na odpowiedzi VenomVendors
# Ignore all
*
# Unignore all files with extensions recursively
!**/*.*
# Unignore Makefiles recursively
!**/Makefile
# other .gitignore rules...
Dodaj do swojego pliku .gitignore:
[^\.]*
Wyjaśnienie:
[] 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"
.gitignore
Mechanizm działa w oparciu jedynie o plikach nazw , a nie w aktach treści . Bycie plikiem binarnym jest właściwością zawartości, dlatego nie możesz bezpośrednio poprosić git o ignorowanie plików binarnych, ale tylko po to, aby zignorować je po nazwie (i jak sugerowano inne, możesz dodać wszystkie nazwy plików binarnych do swojego .gitignore
lub użyć odpowiedniego Konwencja nazewnictwa).
Fakt, że .gitignore
działa na nazwach plików, jest ważny z punktu widzenia wydajności: Git musi tylko wyświetlać listę plików, ale nie musi ich otwierać i czytać, aby wiedzieć, które pliki zignorować. Innymi słowy, Git byłby strasznie wolny, gdybyś mógł poprosić go o ignorowanie plików na podstawie ich zawartości.