Git
Ignorowanie plików i folderów
Szukaj…
Wprowadzenie
W tym temacie pokazano, jak unikać dodawania niechcianych plików (lub zmian plików) w repozytorium Git. Istnieje kilka sposobów (globalny lub lokalny .gitignore , .git/exclude , git update-index --assume-unchanged i git update-index --skip-tree ), ale pamiętaj, że Git zarządza treścią , co oznacza: ignorowanie faktycznie ignoruje zawartość folderu (tzn. pliki). Pusty folder byłby domyślnie ignorowany, ponieważ i tak nie można go dodać.
Ignorowanie plików i katalogów za pomocą pliku .gitignore
Możesz sprawić, aby Git ignorował niektóre pliki i katalogi - to znaczy wykluczył je ze śledzenia przez Git - tworząc jeden lub więcej plików .gitignore w repozytorium.
W projektach programowych .gitignore zazwyczaj zawiera listę plików i / lub katalogów generowanych podczas procesu kompilacji lub w czasie wykonywania. Wpisy w pliku .gitignore mogą zawierać nazwy lub ścieżki wskazujące na:
- zasoby tymczasowe, np. pamięci podręczne, pliki dziennika, skompilowany kod itp.
- lokalne pliki konfiguracyjne, których nie należy udostępniać innym programistom
- pliki zawierające tajne informacje, takie jak hasła logowania, klucze i poświadczenia
Po utworzeniu w katalogu najwyższego poziomu reguły będą miały zastosowanie rekurencyjne do wszystkich plików i podkatalogów w całym repozytorium. Po utworzeniu w podkatalogu reguły będą miały zastosowanie do tego konkretnego katalogu i jego podkatalogów.
Gdy plik lub katalog zostanie zignorowany, nie będzie to:
- śledzone przez Git
- zgłaszane przez polecenia takie jak
git statuslubgit diff - przemieszczane za pomocą poleceń takich jak
git add -A
W nietypowym przypadku, gdy musisz zignorować śledzone pliki, należy zachować szczególną ostrożność. Zobacz: Ignoruj pliki, które zostały już zatwierdzone w repozytorium Git .
Przykłady
Oto kilka ogólnych przykładów reguł w pliku .gitignore , opartych na wzorcach plików glob :
# Lines starting with `#` are comments.
# Ignore files called 'file.ext'
file.ext
# Comments can't be on the same line as rules!
# The following line ignores files called 'file.ext # not a comment'
file.ext # not a comment
# Ignoring files with full path.
# This matches files in the root directory and subdirectories too.
# i.e. otherfile.ext will be ignored anywhere on the tree.
dir/otherdir/file.ext
otherfile.ext
# Ignoring directories
# Both the directory itself and its contents will be ignored.
bin/
gen/
# Glob pattern can also be used here to ignore paths with certain characters.
# For example, the below rule will match both build/ and Build/
[bB]uild/
# Without the trailing slash, the rule will match a file and/or
# a directory, so the following would ignore both a file named `gen`
# and a directory named `gen`, as well as any contents of that directory
bin
gen
# Ignoring files by extension
# All files with these extensions will be ignored in
# this directory and all its sub-directories.
*.apk
*.class
# It's possible to combine both forms to ignore files with certain
# extensions in certain directories. The following rules would be
# redundant with generic rules defined above.
java/*.apk
gen/*.class
# To ignore files only at the top level directory, but not in its
# subdirectories, prefix the rule with a `/`
/*.apk
/*.class
# To ignore any directories named DirectoryA
# in any depth use ** before DirectoryA
# Do not forget the last /,
# Otherwise it will ignore all files named DirectoryA, rather than directories
**/DirectoryA/
# This would ignore
# DirectoryA/
# DirectoryB/DirectoryA/
# DirectoryC/DirectoryB/DirectoryA/
# It would not ignore a file named DirectoryA, at any level
# To ignore any directory named DirectoryB within a
# directory named DirectoryA with any number of
# directories in between, use ** between the directories
DirectoryA/**/DirectoryB/
# This would ignore
# DirectoryA/DirectoryB/
# DirectoryA/DirectoryQ/DirectoryB/
# DirectoryA/DirectoryQ/DirectoryW/DirectoryB/
# To ignore a set of files, wildcards can be used, as can be seen above.
# A sole '*' will ignore everything in your folder, including your .gitignore file.
# To exclude specific files when using wildcards, negate them.
# So they are excluded from the ignore list:
!.gitignore
# Use the backslash as escape character to ignore files with a hash (#)
# (supported since 1.6.2.1)
\#*#
Większość plików .gitignore jest standardowych w różnych językach, więc na początek jest zestaw przykładowych plików .gitignore wymienionych według języka, z którego można sklonować lub skopiować / zmodyfikować w projekcie. Alternatywnie, dla świeżego projektu możesz rozważyć automatyczne wygenerowanie pliku startowego za pomocą narzędzia online .
Inne formy .gitignore
Pliki .gitignore są przeznaczone do zatwierdzenia jako część repozytorium. Jeśli chcesz zignorować niektóre pliki bez zatwierdzania reguł ignorowania, oto kilka opcji:
- Edytuj plik
.git/info/exclude(używając tej samej składni co.gitignore). Reguły będą globalne w zakresie repozytorium; - Skonfiguruj globalny plik gitignore, który zastosuje reguły ignorowania do wszystkich lokalnych repozytoriów:
Ponadto możesz zignorować lokalne zmiany w śledzonych plikach bez zmiany globalnej konfiguracji git za pomocą:
-
git update-index --skip-worktree [<file>...]: dla drobnych modyfikacji lokalnych -
git update-index --assume-unchanged [<file>...]: dla gotowych do produkcji, niezmiennych plików w górę
Zobacz więcej szczegółów na temat różnic między tymi ostatnimi flagami a dokumentacją git update-index aby uzyskać dodatkowe opcje.
Czyszczenie zignorowanych plików
Możesz użyć git clean -X aby git clean -X zignorowane pliki:
git clean -Xn #display a list of ignored files
git clean -Xf #remove the previously displayed files
Uwaga: -X ( -X litery) czyści tylko ignorowane pliki. Użyj -x (bez wielkich liter), aby również usunąć nieśledzone pliki.
Więcej informacji znajduje się w dokumentacji git clean .
Więcej informacji znajduje się w podręczniku Git .
Wyjątki w pliku .gitignore
Jeśli pliki są ignorowane przy użyciu wzorca, ale mają wyjątki, należy poprzedzić wykrzyknikiem (!) Wyjątek. Na przykład:
*.txt
!important.txt
Powyższy przykład instruuje Git, aby ignorował wszystkie pliki z rozszerzeniem .txt z wyjątkiem plików o nazwie important.txt .
Jeśli plik znajduje się w zignorowanym folderze, NIE możesz go tak łatwo ponownie dołączyć:
folder/
!folder/*.txt
W tym przykładzie wszystkie pliki .txt w folderze pozostaną ignorowane.
Właściwym sposobem jest ponowne włączenie samego folderu w osobnym wierszu, a następnie zignorowanie wszystkich plików w folder przez * , a następnie ponowne dołączenie *.txt w folder , jak poniżej:
!folder/
folder/*
!folder/*.txt
Uwaga : W przypadku nazw plików rozpoczynających się od wykrzyknika dodaj dwa wykrzykniki lub użyj znaku \ :
!!includethis
\!excludethis
Globalny plik .gitignore
Aby Git ignorował niektóre pliki we wszystkich repozytoriach, możesz utworzyć globalny plik .gitignore za pomocą następującego polecenia w terminalu lub wierszu polecenia:
$ git config --global core.excludesfile <Path_To_Global_gitignore_file>
Git będzie teraz używał tego oprócz własnego pliku .gitignore każdego repozytorium. Zasady tego są następujące:
- Jeśli lokalny plik
.gitignorewyraźnie zawiera plik, podczas gdy globalny.gitignorego ignoruje, lokalny.gitignorema priorytet (plik zostanie dołączony) - Jeśli repozytorium klonuje się na wielu maszynach, to globalny
.gigignoremuszą zostać załadowane na wszystkich maszynach lub przynajmniej włączenie go, jak pliki zostaną zignorowane popychany do repo natomiast PC z globalnym.gitignorenie będzie go zaktualizować . To dlatego repo specyficzny.gitignorejest lepszym pomysłem niż globalnej, jeśli projekt jest opracowywane przez zespół
Ten plik jest dobrym miejscem do ignorowania ignorowanych przez platformę, maszynę lub użytkownika elementów, np. OSX .DS_Store , Windows Thumbs.db lub Vim *.ext~ i *.ext.swp ignoruje je, jeśli nie chcesz przechowywać ich w repozytorium . Tak więc jeden członek zespołu pracujący w systemie OS X może dodać wszystkie .DS_STORE i _MACOSX (co w rzeczywistości jest bezużyteczne), podczas gdy inny członek zespołu w systemie Windows może zignorować wszystkie thumbs.bd
Zignoruj pliki, które zostały już zatwierdzone w repozytorium Git
Jeśli już dodałeś plik do swojego repozytorium Git i teraz chcesz przestać go śledzić (aby nie był obecny w przyszłych zatwierdzeniach), możesz usunąć go z indeksu:
git rm --cached <file>
Spowoduje to usunięcie pliku z repozytorium i zapobiegnie śledzeniu dalszych zmian przez Git. Opcja --cached upewni się, że plik nie zostanie fizycznie usunięty.
Pamiętaj, że wcześniej dodana zawartość pliku będzie nadal widoczna w historii Git.
Pamiętaj, że jeśli ktoś usunie plik z repozytorium po usunięciu pliku z indeksu, jego kopia zostanie fizycznie usunięta .
Możesz sprawić, by Git udawał, że wersja katalogu roboczego pliku jest aktualna i zamiast tego odczytał wersję indeksu (ignorując w ten sposób zmiany) za pomocą bitu „ pomiń drzewko robocze ”:
git update-index --skip-worktree <file>
Ten bit nie wpływa na pisanie, bezpieczeństwo treści jest nadal priorytetem. Nigdy nie stracisz swoich cennych ignorowanych zmian; z drugiej strony ten bit jest w konflikcie z ukrywaniem: aby usunąć ten bit, użyj
git update-index --no-skip-worktree <file>
Czasem błędnie zaleca się okłamywanie Gita i zakładanie, że plik nie został zmieniony bez sprawdzania go. Na pierwszy rzut oka wygląda na ignorowanie jakichkolwiek dalszych zmian w pliku, bez usuwania go z indeksu:
git update-index --assume-unchanged <file>
Zmusi to git do zignorowania wszelkich zmian dokonanych w pliku (pamiętaj, że jeśli wyciągniesz jakieś zmiany do tego pliku lub ukryjesz go, twoje zignorowane zmiany zostaną utracone )
Jeśli chcesz, aby git „przejmował się” tym plikiem, uruchom następującą komendę:
git update-index --no-assume-unchanged <file>
Sprawdzanie, czy plik jest ignorowany
Polecenie git check-ignore zgłasza pliki ignorowane przez Git.
Możesz przekazać nazwy plików w wierszu poleceń, a git check-ignore wyświetli listę nazw plików, które są ignorowane. Na przykład:
$ cat .gitignore
*.o
$ git check-ignore example.o Readme.md
example.o
Tutaj tylko pliki * .o są zdefiniowane w .gitignore, więc Readme.md nie jest wymieniony w danych wyjściowych git check-ignore .
Jeśli chcesz zobaczyć wiersz, który .gitignore jest odpowiedzialny za ignorowanie pliku, dodaj -v do komendy git check-ignore:
$ git check-ignore -v example.o Readme.md
.gitignore:1:*.o example.o
Począwszy od wersji Git 1.7.6 możesz także używać git status --ignored , aby zobaczyć zignorowane pliki. Więcej informacji na ten temat można znaleźć w oficjalnej dokumentacji lub w Znajdowaniu plików ignorowanych przez .gitignore .
Ignorowanie plików w podfolderach (wiele plików gitignore)
Załóżmy, że masz taką strukturę repozytorium:
examples/
output.log
src/
<files not shown>
output.log
README.md
output.log w katalogu przykładów jest poprawny i wymagany, aby projekt zebrał zrozumienie, podczas gdy plik poniżej src/ jest tworzony podczas debugowania i nie powinien znajdować się w historii ani części repozytorium.
Istnieją dwa sposoby zignorowania tego pliku. Możesz umieścić ścieżkę bezwzględną do pliku .gitignore w katalogu głównym katalogu roboczego:
# /.gitignore
src/output.log
Alternatywnie możesz utworzyć plik .gitignore w katalogu src/ i zignorować plik względny do tego .gitignore :
# /src/.gitignore
output.log
Ignorowanie pliku w dowolnym katalogu
Aby zignorować plik foo.txt w dowolnym katalogu, wystarczy wpisać jego nazwę:
foo.txt # matches all files 'foo.txt' in any directory
Jeśli chcesz zignorować plik tylko w części drzewa, możesz określić podkatalogi określonego katalogu za pomocą ** wzorca:
bar/**/foo.txt # matches all files 'foo.txt' in 'bar' and all subdirectories
Lub możesz utworzyć plik .gitignore w katalogu bar/ . Odpowiednikiem poprzedniego przykładu byłoby utworzenie pliku bar/.gitignore z następującą zawartością:
foo.txt # matches all files 'foo.txt' in any directory under bar/
Ignoruj pliki lokalnie bez wprowadzania reguł ignorowania
.gitignore ignoruje pliki lokalnie, ale jest przeznaczone do zapisania w repozytorium i udostępnienia innym współautorom i użytkownikom. Możesz ustawić globalny .gitignore , ale wtedy wszystkie twoje repozytoria współużytkują te ustawienia.
Jeśli chcesz zignorować niektóre pliki w repozytorium lokalnie i nie .git/info/exclude pliku do żadnego repozytorium, edytuj .git/info/exclude w swoim repozytorium.
Na przykład:
# these files are only ignored on this repo
# these rules are not shared with anyone
# as they are personal
gtk_tests.py
gui/gtk/tests/*
localhost
pushReports.py
server/
Wstępnie wypełnione szablony .gitignore
Jeśli nie masz pewności, które reguły .gitignore pliku .gitignore , lub po prostu chcesz dodać ogólnie akceptowane wyjątki do swojego projektu, możesz wybrać lub wygenerować plik .gitignore :
Wiele usług hostingowych, takich jak GitHub i BitBucket oferują możliwość generowania .gitignore plików w oparciu o języki programowania i IDE można używać:
Ignorowanie kolejnych zmian w pliku (bez usuwania)
Czasami chcesz mieć plik przechowywany w Git, ale ignorujesz kolejne zmiany.
Powiedz Gitowi, aby zignorował zmiany w pliku lub katalogu przy użyciu update-index :
git update-index --assume-unchanged my-file.txt
Powyższe polecenie nakazuje Gitowi założyć, my-file.txt nie został zmieniony i nie sprawdzać ani nie zgłaszać zmian. Plik jest nadal obecny w repozytorium.
Może to być przydatne do zapewnienia wartości domyślnych i zezwalania na lokalne zastąpienia środowiska, np .:
# create a file with some values in cat <<EOF MYSQL_USER=app MYSQL_PASSWORD=FIXME_SECRET_PASSWORD EOF > .env # commit to Git git add .env git commit -m "Adding .env template" # ignore future changes to .env git update-index --assume-unchanged .env # update your password vi .env # no changes! git status
Ignorowanie tylko części pliku [stub]
Czasami możesz chcieć wprowadzić lokalne zmiany w pliku, którego nie chcesz zatwierdzać ani publikować. Idealnie ustawienia lokalne powinny być skoncentrowane w osobnym pliku, który można umieścić w .gitignore , ale czasami jako rozwiązanie krótkoterminowe pomocne może być posiadanie czegoś lokalnego w pliku zaewidencjonowanym.
Możesz sprawić, by Git „nie widział” tych linii, używając czystego filtra. Nie pojawią się nawet w różnicach.
Załóżmy, że tutaj jest fragment kodu z pliku file1.c :
struct settings s;
s.host = "localhost";
s.port = 5653;
s.auth = 1;
s.port = 15653; // NOCOMMIT
s.debug = 1; // NOCOMMIT
s.auth = 0; // NOCOMMIT
Nigdzie nie chcesz publikować linii NOCOMMIT .
Utwórz filtr „nocommit”, dodając go do pliku konfiguracyjnego Git, takiego jak .git/config :
[filter "nocommit"]
clean=grep -v NOCOMMIT
Dodaj (lub utwórz) to do .git/info/attributes lub .gitmodules :
file1.c filter=nocommit
Twoje linie NOCOMMIT są ukryte przed Git.
Ostrzeżenia:
- Użycie czystego filtra spowalnia przetwarzanie plików, szczególnie w systemie Windows.
- Zignorowana linia może zniknąć z pliku, gdy Git ją zaktualizuje. Można temu przeciwdziałać za pomocą filtra rozmazywania, ale jest trudniejszy.
- Nie testowano w systemie Windows
Ignorowanie zmian w śledzonych plikach. [kikut]
.gitignore i .git/info/exclude działają tylko dla nieśledzonych plików.
Aby ustawić flagę ignorowania w pliku śledzonym, użyj polecenia update-index :
git update-index --skip-worktree myfile.c
Aby to przywrócić, użyj:
git update-index --no-skip-worktree myfile.c
Możesz dodać ten fragment do swojej globalnej konfiguracji git, aby mieć wygodniejsze polecenia git hide , git unhide i git hidden :
[alias]
hide = update-index --skip-worktree
unhide = update-index --no-skip-worktree
hidden = "!git ls-files -v | grep ^[hsS] | cut -c 3-"
Możesz także użyć opcji --assume-niezmieniona z funkcją aktualizacji indeksu
git update-index --assume-unchanged <file>
Jeśli chcesz ponownie obejrzeć ten plik pod kątem zmian, użyj
git update-index --no-assume-unchanged <file>
Jeśli podano opcję --assume-niezmienioną, użytkownik obiecuje nie zmieniać pliku i pozwala Gitowi założyć, że działający plik drzewa odpowiada temu, co jest zapisane w indeksie. Git zawiedzie, jeśli będzie musiał zmodyfikować ten plik w indeksie np. podczas łączenia zatwierdzenia; dlatego w przypadku zmiany założonego pliku, który nie został wyśledzony, należy ręcznie obsłużyć sytuację. W tym przypadku nacisk kładziony jest na wydajność.
Podczas gdy opcja --skip-worktree jest przydatna, gdy instruujesz git, aby nigdy nie dotykał określonego pliku, ponieważ plik zostanie zmieniony lokalnie i nie chcesz przypadkowo zatwierdzić zmian (tj. Pliku konfiguracji / właściwości skonfigurowanego dla określonego środowisko). Drzewo przeskoku ma pierwszeństwo przed założeniem-niezmienione, gdy oba są ustawione.
Wyczyść już zatwierdzone pliki, ale zawarte w .gitignore
Czasami zdarza się, że plik był śledzony przez git, ale później został dodany do .gitignore, aby przestać go śledzić. Bardzo częstym scenariuszem jest zapominanie o czyszczeniu takich plików przed dodaniem ich do .gitignore. W takim przypadku stary plik nadal będzie się zawieszał w repozytorium.
Aby rozwiązać ten problem, można wykonać „wszystko na sucho” usunięcie wszystkiego z repozytorium, a następnie ponownie dodać wszystkie pliki z powrotem. Dopóki nie ma oczekujących zmian, a parametr --cached jest przekazywany, uruchomienie tej komendy jest dość bezpieczne:
# Remove everything from the index (the files will stay in the file system)
$ git rm -r --cached .
# Re-add everything (they'll be added in the current state, changes included)
$ git add .
# Commit, if anything changed. You should see only deletions
$ git commit -m 'Remove all files that are in the .gitignore'
# Update the remote
$ git push origin master
Utwórz pusty folder
Nie można dodawać i zatwierdzać pustych folderów w Git ze względu na to, że Git zarządza plikami i dołącza do nich swój katalog, co zmniejsza zatwierdzenia i przyspiesza. Aby obejść ten problem, istnieją dwie metody:
Metoda pierwsza: .gitkeep
Jednym ze .gitkeep na .gitkeep tego jest użycie pliku .gitkeep do zarejestrowania folderu w Git. Aby to zrobić, wystarczy utworzyć wymagany katalog i dodać plik .gitkeep do folderu. Ten plik jest pusty i nie służy żadnemu celowi poza rejestracją folderu. Aby to zrobić w systemie Windows (który ma dziwne konwencje nazewnictwa plików), po prostu otwórz git bash w katalogu i uruchom polecenie:
$ touch .gitkeep
To polecenie tworzy pusty plik .gitkeep w bieżącym katalogu
Metoda druga: dummy.txt
Kolejny hack do tego jest bardzo podobny do powyższego i można wykonać te same kroki, ale zamiast .gitkeep , po prostu użyj dummy.txt . Daje to dodatkową zaletę łatwego tworzenia go w systemie Windows za pomocą menu kontekstowego. Możesz też zostawić w nich śmieszne wiadomości. Możesz także użyć pliku .gitkeep do śledzenia pustego katalogu. .gitkeep zwykle jest pustym plikiem dodawanym w celu śledzenia pustego directoy.
Znajdowanie plików ignorowanych przez .gitignore
Możesz wyświetlić listę wszystkich plików ignorowanych przez git w bieżącym katalogu za pomocą polecenia:
git status --ignored
Więc jeśli mamy taką strukturę repozytorium:
.git
.gitignore
./example_1
./dir/example_2
./example_2
... i plik .gitignore zawierający:
example_2
... niż wynik polecenia będzie:
$ git status --ignored
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
.example_1
Ignored files:
(use "git add -f <file>..." to include in what will be committed)
dir/
example_2
Jeśli chcesz wyświetlić rekursywnie ignorowane pliki w katalogach, musisz użyć dodatkowego parametru - --untracked-files=all
Wynik będzie wyglądał następująco:
$ git status --ignored --untracked-files=all
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
example_1
Ignored files:
(use "git add -f <file>..." to include in what will be committed)
dir/example_2
example_2
