Gdy pracujemy w projekcie z innymi deweloperami albo nawet sami, to zachodzi potrzeba, aby nie wszystkie pliki były dodane do repozytorium. Pliki konfiguracyjne z dostępami do baz danych albo pliki „śmieciowe” wygenerowane podczas kompilacji, czy też pliki, które są tworzone przez środowiska programistyczne używane w pracy. Dzisiejszy wpis pokaże, jak nie udostępniać publicznie plików, których nie chcemy, aby były widoczne dla gita. Zapraszam 🙂
Ignorowanie plików
Mając kilka plików w naszym repozytorium, możemy świadomie dodawać pliki, które mają zostać wrzucone do repozytorium. Takie podejście spowoduję, że nie będziemy mogli użyć komendy
git add -A git commit -m "..."
Ponieważ, nie chcemy dodawać wszystkich plików do repozytorium, tylko wybrane. Takie podejście jest dość męczące i wymaga, abyśmy ciągle pamiętali, że nie możemy dodać konkretnego pliku.
Przykład:
C:\MojeRepo\ (master) git status On branch master Initial commit Untracked files: (use "git add..." to include in what will be committed) a.txt b.txt c.txt d.txt e.txt nothing added to commit but untracked files present (use "git add" to track)
Mamy w przestrzeni roboczej pięć plików i nie chcemy, aby plik c.txt był wrzucony do repozytorium, ponieważ w tym pliku trzymamy hasła i nazwy baz danych, z którą się łączymy. Wykonywanie pojedynczo komend indeksowania plików po kolei jest czasochłonne…
Na szczęście git oferuję mechanizm, który pomoże nam rozwiązać powyższą sytuację.
Plik .gitignore
W naszym folderze dodajmy specjalny plik, który będzie informować Git’a aby nie śledził konkretnych plików, można utworzyć plik za pomocą edytora bądź komendą
touch .gitignore
W naszej przestrzeni pojawił się nowy plik .gitignore
C:\MojeRepo\ (master) git status On branch master Initial commit Untracked files: (use "git add..." to include in what will be committed) .gitignore a.txt b.txt c.txt d.txt e.txt nothing added to commit but untracked files present (use "git add" to track)
W pliku .gitignore umieszczamy reguły, informacje dla Git’a których plików ma „nie widzieć”, nie śledzić. Otwórzmy nasz plik i dodajmy w nim nazwę pliku, który ma być nie śledzony, w naszym przypadku plik c.txt
//Zawartość pliku .gitignore c.txt
Teraz wydając polecenia
git status
Zobaczymy, że plik c.txt jest nie widoczny przez git’a
C:\MojeRepo\ (master) git status On branch master Initial commit Untracked files: (use "git add..." to include in what will be committed) .gitignore a.txt b.txt d.txt e.txt nothing added to commit but untracked files present (use "git add" to track)
Plik fizycznie nadal istnieje w naszym folderze
C:\MojeRepo\ (master) ls a.txt b.txt c.txt d.txt e.txt
Ale nie jest widoczny dla Git’a. Teraz możemy bez problemu dokonać rewizji wszystkich plików dwoma komendami, nie wliczając w to pliku c.txt. Najpierw zacznijmy śledzić nowe pliki, do tego służy polecenie
git add -A
Sprawdźmy zawartość repo, poniżej widzimy, że nowe pliki zostały zaindeksowane
C:\MojeRepo\ (master) git status On branch master Initial commit Changes to be committed: (use "git rm --cached..." to unstage) new file: .gitignore new file: a.txt new file: b.txt new file: d.txt new file: e.txt
Teraz utwórzmy pierwszą rewizję w repo
C:\MojeRepo\ (master) git commit -m "Utworzenie rewizji z wykluczeniem pliku c.txt " [master (root-commit) d1ebe3c] Wykluczenie pliku c.txt 5 files changed, 1 insertion(+) create mode 100644 .gitignore create mode 100644 a.txt create mode 100644 b.txt create mode 100644 d.txt create mode 100644 e.txt
Otwórz swój plik c.txt, używając edytora tekstu i wpisz „Ala ma kota” zapisz plik i sprawdź poleceniem git status czy git wyłapał nową zmianę w pliku. Odpowiadam, nie złapał, ponieważ git został po informowany, że ma nie śledzić pliku c.txt, reguła takiego działania została wprowadzona w pliku .gitignore
Koniec śledzenia pliku istniejącego w repo
Dobrze, a co jeżeli mam w repo już plik, ale na pewnym etapie prac uznaliśmy, że już nie chcemy, aby był śledzony. Dobre pytanie już tłumaczę i objaśniam, aby dokonać takiej operacji, należy:
- Wejdź do pliku .gitignore dodaj regułe: a.txt
- Wejdź do pliku a.txt i wpisz w nim tekst Ala ma kota
- Wykonaj polecenie git rm –cached a.txt
- Wykonaj rewizje
Tak jak napisałem w powyższych pod punktach zmodyfikuj plik .gitignore dodaj w nim linijkę
//Zawartość pliku .gitignore c.txt a.txt
Teraz, otwórz plik a.txt, dodaj w nim jakikolwiek tekst i zapisz. Najważniejsze, wykonaj polecenie które po informuję gita, że ma przestać śledzić plik
git rm --cached a.txt
Po wydaniu powyższego polecenie, wykonaj następne
C:\MojeRepo (master) git status On branch master Changes to be committed: (use "git reset HEAD..." to unstage) deleted: a.txt
Komunikat może wydawać się niepokojący, przecież nie chcemy, aby plik był fizycznie wykasowany, tylko chcemy, aby Git przestał go śledzić. Spokojnie, wszystko jest okej, teraz potwierdźmy Gita w przekonaniu, że plik a.txt został „wykasowany”
C:\MojeRepo (master) git commit -m "Git przestaje śledzić plik a.txt" [master e15b93c] tred 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 a.txt
Teraz wykonaj polecenie ls, aby upewnić się, że plik fizycznie nadal istnieje, możesz też wejść do folderu i sprawdzić jego zawartość
C:\MojeRepo (master) ls a.txt b.txt c.txt d.txt e.txt
Widać wyraźnie, że plik a.txt istnieje i ma się bardzo dobrze. Wejdź do tego pliku i zmodyfikuj go, dodaj w nim jakikolwiek tekst i zapisz.
Wydaj polecenie
C:\MojeRepo (master) git status On branch master nothing to commit, working tree clean
Jak widzimy, plik fizycznie istnieje, został zmodyfikowany, a Git przestał go śledzić.
Plik exclude
Różnica między plikiem .gitignore a exclude jest taka, że plik .gitignore jest wrzucony do repozytorium, co za tym idzie wszyscy użytkownicy repo, nie będą mogli śledzić konkretnych plików. A co jeżeli chcemy, aby konkretny plik był nieśledzony lokalnie, tak aby nie ingerować w plik .gitignore? Tutaj z pomocą przychodzi plik exclude.
Sprawdźmy zawartość naszego folderu z repozytorium
C:\MojeRepo (master) ls -a . .. .git .gitignore a.txt b.txt c.txt d.txt e.txt
Przejdźmy do katalogu
C:\MojeRepo\.git\info (master)
Sprawdź, czy w powyższym folderze znajduję się plik o nazwie exclude. W nowszych wersjach Git jest on dodawany automatycznie, w starszych wersjach musimy utworzyć plik ręcznie.
Tworzymy plik exclude
C:\MojeRepo\.git\info (master) touch exclude
Wejdź do nowo utworzonego pliku i wklej do niego poniższą zawartość:
# git ls-files --others --exclude-from=.git/info/exclude # Lines that start with '#' are comments. # For a project mostly in C, the following would be a good set of # exclude patterns (uncomment them if you want to use them): # *.[oa] # *~
Jeżeli miałeś plik w folderze, to nie musisz nic wklejać, ponieważ powyższy tekst jest właśnie z pliku exclude.
Dodajmy nowy plik do repo
touch f.txt
Jeżeli chcemy zignorować nowy plik, który nie został jeszcze zindeksowany przez gita, wystarczy, że w pliku exclude dodasz linijkę
f.txt
Teraz po wydaniu polecenia
C:\MojeRepo (master) git status On branch master nothing to commit, working tree clean
Co w przypadku, kiedy plik jest już śledzony i istnieje w repo?
Utwórzmy nowy plik, zmodyfikujmy go i wykonajmy rewizje:
C:\MojeRepo (master) touch h.txt (wpisz jakikolwiek tekst do pliku h.txt) git add h.txt git commit -m "Dodanie nowego pliku h.txt
Teraz wykonajmy ponownie modyfikacje na pliku h.txt sprawdźmy stan naszego obszaru roboczego
C:\MojeRepo (master) git status On branch master Changes not staged for commit: (use "git add..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: h.txt no changes added to commit (use "git add" and/or "git commit -a")
Wiemy, że nasz plik jest już w repo i jest aktualnie zmodyfikowany, a my chcemy, aby od tej pory, ten plik był niewidoczny dla Gita tylko u nas lokalnie. Wykonujemy te same kroki co w podpunkcie
Koniec śledzenia pliku istniejącego w repo. Z tą różnicą, że wchodzimy do pliku exclude i tam wpisujemy regułę dla pliku h.txt.
Istnieje jeszcze prostszy sposób, aby przestać śledzić plik, który istnieje w repo. Zamiast wydawać polecenia
C:\MojeRepo (master) git rm --cached a.txt
A potem robić rewizję, można przestać śledzić plik bez robienia rewizji, wystarczy wydać polecenie:
C:\MojeRepo (master) git update-index --assume-unchanged a.txt
Przykład
C:\MojeRepo (master) touch z.txt git add z.txt git commit -m "Dodanie pliku z.txt do repo" (zmodyfikuj plik z.txt dodaj do niego jakiś tekst, zapisz zmiany)
Po wydaniu polecenia
C:\MojeRepo (master) git status On branch master Changes not staged for commit: (use "git add..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: z.txt no changes added to commit (use "git add" and/or "git commit -a")
Otwórz plik exclude i dodaj do niego linijkę
z.txt
Zapisz plik, sprawdźmy naszą przestrzeń roboczą
C:\MojeRepo (master) git status On branch master Changes not staged for commit: (use "git add..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: z.txt no changes added to commit (use "git add" and/or "git commit -a")
Widzimy, że plik z.txt jest nadal śledzony, aby uniknąć tego wydaj kolejne polecenie
C:\MojeRepo (master) git update-index --assume-unchanged git status On branch master nothing to commit, working tree clean
Jak widzimy, Git przestał śledzić plik z.txt możemy wykonywać w nim różne modyfikację i nie musimy się obawiać, że zostaną przez nas dodane zmiany naniesione w tym pliku. Plusem pliku exclude jest tutaj taki, że nie musimy nadpisywać .gitignore oraz nie musimy robić rewizji. Komenda git update-index –assume-unchanged NazwaPliku pozwala na nie śledzenie pliku bez wykonywania komita.
Podsumowanie
Możliwości ignorowania plików są przydatną sprawą. W bardzo prosty i szybki sposób możemy poinformować Git’a, których plików ma nie śledzić i nie umieszczać ich w repozytorium. Dość często wykorzystuję się w projektach możliwości pliku .gitignore gdzie każdy członek, który korzysta z repozytorium ma od górnie ustalone, jakie pliki nie mogą znaleźć się w repo. Zastosowanie pliku exclude jest do użytku lokalnego dla naszej wygody. Na przykład, mamy plik konfiguracyjny, w którym nanosimy zmiany, ale nie chcemy ich udostępniać innym członkom zespołu, ponieważ w wersji oryginalnej ma odpowiednie środowiska, a na nasze potrzeby chcemy ustawić środowiska lokalnie. Użycie exclude jest idealną opcją, bo nanosimy zmiany w danym pliku na nasze lokalne potrzeby, a wypychając zmiany do repo, plik konfiguracyjny jest cały czas w stanie oryginalnym nienaruszającym struktury projektu.
Pozdro 🙂
One comment