👽 Git - kontrola wersji
W tym module poznasz podstawowe informacje o systemie kontroli wersji git. Omówimy commity, synchronizację z repozytorium zdalnym, pracę z gałęziami oraz współpracę przez pull requesty.
Czym jest git?
Git to rozproszony system kontroli wersji, który umożliwia śledzenie zmian w plikach, współpracę między programistami i zarządzanie kodem źródłowym w sposób efektywny i bezpieczny. Jest szeroko stosowany w projektach open-source oraz w firmach na całym świecie.
Kluczowe cechy gita
- Rozproszony system – każdy użytkownik ma pełną kopię repozytorium,
- Wersjonowanie – śledzenie zmian i możliwość powrotu do wcześniejszych wersji kodu,
- Gałęzie (branches) – możliwość pracy nad różnymi wersjami kodu równocześnie,
- Integracja z platformami zdalnymi – np. GitHub, GitLab, Bitbucket.
Połączenie z repozytorium zdalnym
Tą funkcjonalość mamy już opanowaną - zrobiliśmy to w poprzednich krokach.
Co to są commity i jak działają?
Commit - zapisywanie zmian
Commit to jak "zapisanie gry" w programowaniu. To moment, w którym zapisujesz aktualny stan swoich plików w repozytorium git. Każdy commit ma unikalny identyfikator (hash) i zawiera informacje o tym, co zostało zmienione, kiedy i przez kogo.
Dlaczego commity są ważne?
- Pozwalają śledzić historię zmian w kodzie.
- Umożliwiają powrót do wcześniejszych wersji.
- Ułatwiają współpracę w zespole.
- Pomagają zrozumieć, co i dlaczego zostało zmienione.
Podstawowy workflow z commitami:
# 1. Sprawdź status plików
git status
# 2. Dodaj pliki do staging area (przygotowanie do commita)
git add nazwa-pliku.py
# lub dodaj wszystkie zmienione pliki:
git add .
# 3. Stwórz commit z opisem zmian
git commit -m "Add function to calculate average"
Dobre praktyki przy commitach:
- Pisz jasne i zwięzłe opisy commitów.
- Commituj często, ale tylko logicznie spójne zmiany.
- Używaj czasu teraźniejszego w opisach (np. "Add function" zamiast "Added function").
Przykłady dobrych opisów commitów:
"Fix calculation bug in average function"
"Add input validation for user data"
"Remove unused imports"
"Update function documentation"
Synchronizacja z repozytorium zdalnym
Push, Pull i Fetch
Gdy pracujesz (chociażby na tych zajęciach), musisz synchronizować zmiany z repozytorium zdalnym (np. na GitHubie). To dopiero tam inni zainteresowani będą mieć wgląd w kod i zmiany.
Push - wysyłanie zmian na serwer:
git push origin nazwa-galezi
origin to domyślna nazwa repozytorium zdalnego, a nazwa-galezi to gałąź, którą chcesz wysłać.
Pull - pobieranie i scalanie zmian:
git pull origin nazwa-galezi
git fetch + git merge.
Fetch - tylko pobieranie informacji:
git fetch origin
Kiedy używać którego polecenia?
git push- gdy skończyłeś pracę nad funkcją i chcesz udostępnić zmiany innym.git pull- gdy chcesz pobrać najnowsze zmiany od innych programistów.git fetch- gdy chcesz tylko sprawdzić, czy są nowe zmiany, bez ich scalania.
Typowy workflow:
# Przed rozpoczęciem pracy - pobierz najnowsze zmiany
git pull origin main
# Po skończeniu pracy - wyślij swoje zmiany
git push origin moja-galez
📝 Zadania
- Przenieś swoje zmiany po wykonanym poprzednim zadaniu do staging area.
- Zacommituj je.
- Wypchnij swoje zmiany do repozytorium zdalnego.
Gałęzie
Branches
Gałęzie pozwalają na jednoczesne rozwijanie różnych funkcji projektu bez wpływania na główną wersję kodu. To bardzo użyteczne, gdy kilka osób pracuje nad różnymi aspektami projektu lub gdy testujesz nowe funkcjonalności przed ich wdrożeniem do głównej wersji kodu.
Tworzenie nowej gałęzi:
git branch nazwa-galezi
Przełączanie się na nową gałąź:
git checkout nazwa-galezi
git switch nazwa-galezi
Tworzenie i przejście na nową gałąź jednocześnie:
git checkout -b nazwa-galezi
Merging (scalanie gałęzi):
Przykład: synchronizacja swojej gałęzi z najnowszymi zmianami z main:
# 1. Przełącz się na swoją gałąź
git checkout feature/kalkulator
# 2. Pobierz najnowsze zmiany z main
git pull origin main
# 3. Scal zmiany z main do swojej gałęzi
git merge main
# 4. Wyślij zaktualizowaną gałąź
git push origin feature/kalkulator
Kiedy to robić?
- Gdy ktoś inny dodał zmiany do main, a ty chcesz mieć najnowszą wersję.
- Gdy chcesz uniknąć konfliktów przy końcowym mergowaniu.
- Gdy chcesz przetestować swoją funkcję z najnowszymi zmianami.
Alternatywnie - rebase (bardziej eleganckie):
git checkout feature/kalkulator
git pull origin main
git rebase main
git push origin feature/kalkulator
Współpraca przez repozytorium zdalne
Pull Requests
Pull Requesty to sposób na proponowanie zmian w kodzie i ich review przed mergowaniem do głównej gałęzi.
Workflow:
- Wyślij gałąź na serwer:
git push origin feature/kalkulator. - Na GitHubie kliknij "Compare & pull request".
- Wypełnij tytuł i opis zmian.
- Poproś o review od innych programistów.
- Po zaakceptowaniu - merge do głównej gałęzi.
Dlaczego PR?
- Code review przed mergowaniem.
- Dokumentacja zmian i dyskusji.
- Lepsza jakość kodu.
- Współpraca w zespole.
Teraz masz podstawową wiedzę na temat gita. Możemy zaczynać pracę nad Pythonem!
Nowoczesne IDE mają moduły do obsługi kontroli wersji, więc możemy używać interfejsu graficznego zamiast poleceń w terminalu.
Przydatne w codziennej pracy
Revert i Reset - wycofywanie zmian
Błędy zdarzają się każdemu. Dlatego git oferuje kilka metod na ich cofnięcie.
Cofnięcie ostatniego commita:
git revert HEAD
Jeśli chcesz całkowicie usunąć commit:
git reset --hard HEAD~1
Usunięcie zmian w plikach przed commitem:
git checkout -- nazwa-pliku
Stash – przechowanie tymczasowych zmian
Czasami pracujemy nad jakąś zmianą, ale musimy pilnie przełączyć się na inną gałąź. W takich przypadkach możemy użyć stash.
Schowanie zmian:
git stash
Przywrócenie ostatniego stasha:
git stash pop
Sprawdzanie historii commitów
Historia commitów pomaga w śledzeniu zmian w kodzie, co jest szczególnie przydatne w zespołach.
Podstawowa historia commitów:
git log
Skrócona i czytelniejsza wersja:
git log --oneline --graph --all
Usuwanie plików z repozytorium i .gitignore
Nie zawsze chcemy, aby dany plik był częścią repozytorium.
Usunięcie pliku z repozytorium i lokalnego systemu plików:
git rm nazwa-pliku
Usunięcie pliku tylko z repozytorium, ale zachowanie go lokalnie:
git rm --cached nazwa-pliku
.gitignore
Plik .gitignore pozwala ignorować określone pliki i katalogi, aby nie były one dodawane do repozytorium.
Przykład .gitignore:
# Ignorowanie plików tymczasowych edytora
*.swp
*.swo
# Ignorowanie katalogu build
/build/
# Ignorowanie plików konfiguracyjnych
config.yaml
.env
.gitignore powinien być umieszczony w głównym katalogu repozytorium.
git LFS (Large File Storage)
Jeśli pracujesz z dużymi plikami, git może nie być optymalny do ich przechowywania. Git LFS (Large File Storage) to rozszerzenie gita, które pozwala przechowywać duże pliki osobno od kodu źródłowego.
Instalacja git LFS:
# Na systemach Linux/macOS
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt install git-lfs
# Na Windows
choco install git-lfs
Używanie git LFS:
git lfs install
git lfs track "*.psd"
.psd będą przechowywane w git LFS zamiast w standardowym repozytorium gita.
Dzięki temu repozytorium pozostaje lekkie, a duże pliki są przechowywane w zoptymalizowany sposób.