Pull Request w GitHub – feature branch i code review

by Patryk

W poprzednich lekcjach tworzyliśmy gałęzie, zapisywaliśmy na nich zmiany i łączyliśmy je za pomocą git merge. Wszystko robiliśmy samodzielnie, bezpośrednio w terminalu. W codziennej pracy jednak częściej będziemy pracować zespołowo, w której wygląda to zgoła inaczej. Zanim zmiana trafi do głównej gałęzi projektu, ktoś powinien na nią spojrzeć i ocenić. Może zauważyć błąd, poprosić o dodatkowy test albo zaproponować inne rozwiązanie. Dopiero po sprawdzeniu zmian zespół decyduje o ich połączeniu. Służy do tego Pull Request w Github.

W tej lekcji przejdziemy przez cały proces na naszym repozytorium devops-lab. Utworzymy feature branch, dodamy skrypt monitorujący wykorzystanie dysku i wyślemy zmiany na GitHuba. Następnie otworzymy Pull Request, wykonamy przegląd kodu i poprawimy wykryty problem. Na końcu połączymy zmiany z master, zaktualizujemy lokalne repozytorium i usuniemy niepotrzebną gałąź.

Czym jest Pull Request?


Załóżmy, że pracujesz w zespole odpowiedzialnym za utrzymanie aplikacji. Dostajesz zadanie dodania prostego skryptu, który sprawdza wykorzystanie dysku. Możesz utworzyć osobną gałąź, przygotować zmianę i wykonać lokalny merge:

git switch master
git merge feature/disk-monitoring

Technicznie wszystko zadziała, o ile Git będzie w stanie połączyć historie. Problem w tym, że pozostali członkowie zespołu nie mieli okazji sprawdzić Twojej pracy.

Pull Request pozwala pokazać proponowane zmiany przed włączeniem ich do głównej gałęzi. Na GitHubie można przejrzeć zmodyfikowane pliki, zobaczyć commity, zostawić komentarze i sprawdzić wyniki automatycznych testów, jeśli zostały skonfigurowane.

Przykładowy przebieg pracy wygląda tak:

Zadanie
   |
   v
feature branch
   |
   v
Zmiany i commity
   |
   v
git push
   |
   v
Pull Request na GitHubie
   |
   v
Code review
   |
   +----> Poprawki ----> git push
   |                         |
   |<------------------------+
   |
   v
Merge do master
   |
   v
Aktualizacja lokalnego master

Pull Request i code review to funkcje platformy GitHub. Podobny mechanizm znajdziesz również w GitLabie, gdzie najczęściej używa się nazwy Merge Request.

Przygotowanie repozytorium


Sprawdź połączenie z GitHubem:

git remote -v

Powinieneś zobaczyć repozytorium origin, które konfigurowaliśmy we wcześniejszej lekcji.

Podczas lekcji o konfliktach tworzyliśmy testowe konfiguracje bezpośrednio na master. Jeżeli nie wysłałeś tych commitów na GitHuba, poniższe polecenie git log może je pokazać. Nie wykonuj wtedy automatycznie git push, żeby się ich pozbyć z listy. W ten sposób opublikowałbyś również wszystkie wcześniejsze ćwiczenia.

git fetch origin
git switch master
git log --oneline origin/master..master

Jeżeli chcesz przeprowadzić tę lekcję bez wysyłania tamtych commitów, możesz skorzystać z nowej kopii repozytorium:

cd ~

git clone --branch master \
  git@github.com:TWOJ_LOGIN/devops-lab.git \
  devops-lab-pr

cd ~/devops-lab-pr

Zakładamy, że master jest już zgodny z historią na GitHubie, a git status pokazuje czyste drzewo robocze.

Zadanie: monitorowanie wykorzystania dysku


Na potrzeby demonstracji załóżmy, że dostaliśmy zadanie:

DEVOPS-100: Add disk monitoring script

Zadanie polega na utworzeniu skryptu, który pokaże wykorzystanie miejsca na dysku i będzie ostrzegał po osiągnięciu ustalonego progu. Nie będziemy rozbudowywać go o wysyłanie powiadomień czy integrację z systemem monitoringu. Na razie zależy nam na przećwiczeniu procesu pracy z kodem.

Utworzenie feature brancha

Zanim zaczniemy zmieniać pliki, utwórz osobną gałąź i sprawdź czy znajdujesz się na niej:

git switch -c feature/disk-monitoring
git branch

Dodanie skryptu monitorującego dysk


W poprzednich lekcjach tworzyliśmy już skrypty w katalogu scripts, między innymi system-info.sh i monitoring.sh.

Dodajmy następny:

nano scripts/disk-monitoring.sh

Wklej do niego poniższą zawartość. Na razie skrypt wykonuje dwie rzeczy. Pokazuje wykorzystanie systemu plików zawierającego katalog / i wypisuje ustawiony próg ostrzeżenia

#!/usr/bin/env bash

THRESHOLD=80

df -h /

echo "Warning threshold: ${THRESHOLD}%"

To jeszcze nie jest pełny mechanizm alarmowania. Za chwilę wrócimy do tego podczas przeglądu kodu.

Zapisz plik i nadaj mu uprawnienia do wykonania a następnie go uruchom:

chmod +x scripts/disk-monitoring.sh
./scripts/disk-monitoring.sh

Zobaczysz informacje o wykorzystaniu miejsca oraz linię:

Warning threshold: 80%

Wartości zwracane przez df będą zależeć od Twojej maszyny.

Pierwszy commit

Nowy skrypt powinien znajdować się w sekcji nieśledzonych plików. Sprawdź status repozytorium:

git status

Dodaj go do staging area:

git add scripts/disk-monitoring.sh

Zanim utworzymy commit, przejrzyjmy przygotowaną zmianę:

git diff --staged

Zobaczysz zawartość skryptu oraz informację o nadanych mu uprawnieniach wykonywania. Jeżeli wszystko się zgadza, zapisz commit:

git commit -m "Add disk monitoring script"

Dokumentacja w osobnym commicie

Skrypt działa, ale ktoś, kto otworzy repozytorium po raz pierwszy, może nie wiedzieć, do czego służy. Dodajmy krótki opis do README.md. Na końcu dopisz:

## Disk monitoring

Run `./scripts/disk-monitoring.sh` to display
disk usage for `/` and the configured warning threshold.

Sprawdź zmianę:

git diff

A następnie dodaj go do staging area i dodaj commit:

git add README.md
git commit -m "Document disk monitoring script"

Wysłanie feature brancha na GitHuba


Do tej pory nasza nowa gałąź istnieje tylko lokalnie. Sprawdźmy stan repozytorium:

git status
git log --oneline --decorate --graph --all -10

Jeżeli drzewo robocze jest czyste, możemy opublikować gałąź:

git push -u origin feature/disk-monitoring

Git wyśle commity do repozytorium na GitHubie.

Opcję -u poznaliśmy już wcześniej. Ustawia ona upstream, czyli powiązanie lokalnej gałęzi z jej odpowiednikiem w zdalnym repozytorium. Dzięki temu kolejne zmiany z feature/disk-monitoring wyślemy krótszym poleceniem:

git push

Sprawdź dostępne gałęzie:

git branch -a

Powinieneś zobaczyć między innymi:

* feature/disk-monitoring
  master
  remotes/origin/feature/disk-monitoring
  remotes/origin/master

Mamy już lokalną i zdalną wersję feature brancha. Możemy przejść do GitHuba.

Tworzenie Pull Requesta na GitHubie


Otwórz w przeglądarce swoje repozytorium devops-lab i przejdź do zakładki Pull requests.

Ponieważ przed chwilą wysłaliśmy nową gałąź feature/disk-monitoring, GitHub wyświetla u góry strony komunikat o jej ostatniej aktualizacji. Obok znajduje się zielony przycisk Compare & pull request.

Po jego otworzeniu GitHub otworzy stronę porównania gałęzi. Sprawdź, czy wybrane są:

Base: master

Compare: feature/disk-monitoring

Oznacza to, że chcemy włączyć zmiany z naszej gałęzi feature/disk-monitoring do głównej gałęzi master.

Zwróć uwagę na kolejność. base to gałąź, która ma otrzymać zmiany, natomiast compare wskazuje gałąź, na której je przygotowaliśmy.

Poniżej GitHub pokaże commity oraz pliki zmodyfikowane w ramach naszego zadania. Powinniśmy zobaczyć:

README.md
scripts/disk-monitoring.sh

Na tym etapie zmiany nadal nie zostały połączone z master. Dopiero przygotowujemy je do przeglądu.

Jak opisać Pull Request?

Sam tytuł Add disk monitoring script nie wyjaśnia całego zadania. W opisie warto zamieścić trzy informacje: co zmieniliśmy, dlaczego to zrobiliśmy i w jaki sposób sprawdziliśmy działanie, przykładowo:

## What changed

- Added `scripts/disk-monitoring.sh`.
- Added usage instructions to README.
- Configured an initial 80% warning threshold.

## Why

We need a simple way to inspect disk usage
on the Debian VM.

## Testing

- Ran the script locally on Debian.
- Checked the output of `df -h /`.
- Verified executable permissions.

Zwróć uwagę, że nie twierdzimy jeszcze, iż skrypt poprawnie wykrywa przekroczenie progu. W tej wersji wyświetla tylko jego wartość.

Kliknij Create pull request.

Od tego momentu Pull Request jest otwarty. Nie zmienił jeszcze zawartości master.

Code review – sprawdzamy własne zmiany


W prawdziwym projekcie ktoś z zespołu dostałby prośbę o sprawdzenie Pull Requesta. Ponieważ pracujemy samodzielnie, przeprowadzimy przegląd kodu we własnym zakresie. Nie zastępuje to formalnej akceptacji innej osoby, ale pozwala przećwiczyć analizowanie zmian przed merge.

Otwórz zakładkę Files changed a następnie przejrzyj plik scripts/disk-monitoring.sh.

THRESHOLD=80

df -h /

echo "Warning threshold: ${THRESHOLD}%"

Na pierwszy rzut oka wszystko wygląda poprawnie. Skrypt uruchamia się, wyświetla wykorzystanie dysku i informuje o progu 80%.

Wróćmy jednak do treści zadania. Skrypt miał ostrzegać, kiedy wykorzystanie dysku osiągnie ustalony próg.

Tymczasem nasza pierwsza wersja w ogóle nie porównuje aktualnego wykorzystania z wartością THRESHOLD.

Nawet gdyby dysk był zajęty w 95%, skrypt wypisałby jedynie:

Warning threshold: 80%

To dobry przykład błędu, który można wychwycić podczas code review. Polecenie działa poprawnie, ale nie realizuje całego wymagania.

Możemy zapisać uwagę klikając niebieski plus obok linii z tekstem THRESHOLD=80

Skrypt pokazuje próg ostrzeżenia, ale nie sprawdza, czy wykorzystanie dysku go osiągnęło. Dodajmy takie porównanie i przetestujmy oba możliwe wyniki.

Kliknij Comment, aby od razu opublikować uwagę. Jeśli wybierzesz Start a review, komentarz pozostanie oczekujący, dopóki nie zakończysz przeglądu przez Submit review. Nie musimy zamykać Pull Requesta. Poprawimy kod na tej samej gałęzi.

Poprawki do otwartego Pull Requesta


Wróć do terminala na Debianie i sprawdź aktualną gałąź, powinniśmy znajdowac się na gałęzi feature/disk-monitoring.

git branch --show-current

Otwórz skrypt:

nano scripts/disk-monitoring.sh

Zastąp jego zawartość:

#!/usr/bin/env bash
set -euo pipefail

THRESHOLD="${THRESHOLD:-80}"

USAGE=$(df -P / | awk 'NR == 2 {gsub(/%/, "", $5); print $5}')

echo "Filesystem /: ${USAGE}% used (threshold: ${THRESHOLD}%)"

if (( USAGE >= THRESHOLD )); then
    echo "WARNING: disk usage has reached the threshold"
else
    echo "OK: disk usage below the threshold"
fi

Przyjrzyjmy się najważniejszym fragmentom.

Polecenie:

df -P /

wyświetla informacje o systemie plików zawierającym /. Opcja -P pozwala uzyskać przewidywalniejszy format wyniku, który łatwiej przetworzyć w skrypcie.

Następnie awk pobiera procent wykorzystania z drugiego wiersza i usuwa znak %. Otrzymujemy liczbę, którą możemy porównać z ustawionym progiem.

Warunek:

if (( USAGE >= THRESHOLD )); then

sprawdza, czy aktualne wykorzystanie dysku osiągnęło lub przekroczyło próg.

Zmieniliśmy również sposób ustawiania THRESHOLD:

THRESHOLD="${THRESHOLD:-80}"

Testowanie poprawionego skryptu

Najpierw uruchom go normalnie:

./scripts/disk-monitoring.sh

U Ciebie procent wykorzystania może być inny. Chcemy jednak sprawdzić również sytuację, w której skrypt powinien wyświetlić ostrzeżenie. Nie będziemy w tym celu zapełniać dysku. Ustawimy tymczasowo próg na 0:

THRESHOLD=0 ./scripts/disk-monitoring.sh

Tym razem powinniśmy otrzymać:

WARNING: disk usage has reached the threshold

Zmiana progu dotyczy tylko tego uruchomienia. Nie modyfikuje pliku skryptu. Sprawdziliśmy więc oba możliwe wyniki bez ingerowania w ilość wolnego miejsca na maszynie.

Zapisanie poprawki

Przygotuj zmianę dodając ją do staging area:

git add scripts/disk-monitoring.sh

Następnie utwórz commit:

git commit -m "Warn when disk usage reaches threshold"

Wyślij go na GitHuba:

git push

Wróć do przeglądarki i odśwież stronę otwartego PR. Zobaczysz dodatkowy commit, a w zakładce Files changed pojawi się poprawiona wersja skryptu.

Pull Request obejmuje aktualne zmiany z feature brancha. Gdy dodajemy nowe commity i wykonujemy git push, GitHub uwzględnia je w istniejącym PR. Właśnie dlatego podczas code review możemy wielokrotnie poprawiać kod bez tworzenia osobnego Pull Requesta dla każdej uwagi.

Akceptacja zmian i merge Pull Requesta


Przejrzyj ponownie zmodyfikowane pliki. Skrypt powinien teraz porównywać wykorzystanie dysku z progiem i wyświetlać odpowiedni komunikat.

Sprawdź też zakładkę z commitami. Na naszej gałęzi powinny znajdować się trzy zapisy:

Add disk monitoring script
Document disk monitoring script
Warn when disk usage reaches threshold

W firmowym repozytorium na tym etapie reviewer mógłby zaakceptować zmianę albo poprosić o kolejne poprawki. W naszym jednoosobowym labie sprawdzamy ją sami. Jeżeli repozytorium nie wymaga zatwierdzenia przez inną osobę i GitHub pozwala wykonać merge, możemy zakończyć ćwiczenie. Wybierz Merge pull request, a następnie potwierdź operację.

GitHub utworzy merge commit, który połączy zmiany z feature/disk-monitoring z gałęzią master.

Po zakończeniu merge otwórz master na GitHubie. Powinieneś znaleźć w nim nowy skrypt oraz zmiany w README.

Dlaczego lokalny master nadal nie ma nowych zmian?


Merge wykonaliśmy na GitHubie, a nie w terminalu naszej maszyny. To oznacza, że zdalny master zawiera już nowe commity, ale lokalny master może nadal wskazywać starszą wersję projektu.

Żeby pobrać wynik merge, wróć na główną gałąź:

git switch master

Następnie pobierz zmiany:

git pull

Ponieważ rozpoczęliśmy ćwiczenie od aktualnego master i nie tworzyliśmy na nim nowych commitów, Git powinien zaktualizować go przez fast-forward.

Sprawdź historię:

git log --oneline --decorate --graph --all -12

Zobaczysz merge commit oraz commity z naszego feature brancha.

Możesz również uruchomić skrypt:

./scripts/disk-monitoring.sh

Działa już na lokalnym master, mimo że wcześniej tworzyliśmy go na osobnej gałęzi.

Usuwanie zakończonego feature brancha

Zmiana została włączona do master. Nie potrzebujemy już gałęzi feature/disk-monitoring.

Usuń ją lokalnie:

git branch -d feature/disk-monitoring

Opcja -d pozwala Gitowi sprawdzić, czy historia gałęzi została połączona, zanim ją usunie.

Usuwanie zdalnej gałęzi

GitHub może sam usunąć feature branch po zakończeniu Pull Requesta. Zależy to od ustawień repozytorium. Jeżeli gałąź nadal istnieje na GitHubie, możesz usunąć ją poleceniem:

git push origin --delete feature/disk-monitoring

Następnie odśwież informacje o gałęziach zdalnych:

git fetch --prune

Sprawdź:

git branch -a

Na liście nie powinno być już feature/disk-monitoring ani jej zdalnego odpowiednika. Dzięki temu nie gromadzimy dziesiątek zakończonych gałęzi, których nikt nie używa.

Pull Request i CI/CD


Na razie nasz Pull Request sprawdzaliśmy ręcznie. Uruchomiliśmy skrypt w terminalu i przejrzeliśmy zmienione pliki na GitHubie. W większych projektach część takich sprawdzeń wykonują automatyczne pipeline’y.

Na przykład po otwarciu Pull Requesta GitHub Actions może uruchomić testy, sprawdzić formatowanie kodu albo zbudować obraz Dockera. Przebieg może wyglądać tak:

git push
   |
   v
Pull Request
   |
   +--> testy
   |
   +--> lint
   |
   +--> Docker build
   |
   +--> security checks
   |
   v
Code review
   |
   v
Merge

Jeżeli repozytorium ma skonfigurowane odpowiednie reguły, GitHub może zablokować merge do czasu uzyskania akceptacji lub poprawnego zakończenia wymaganych testów. To jeden z powodów, dla których zespoły nie pozwalają każdemu wykonywać bezpośredniego git push na główną gałąź.

W naszym devops-lab takich mechanizmów jeszcze nie konfigurowaliśmy. Wrócimy do nich podczas nauki CI/CD.

Zadanie samodzielne: skrypt diagnostyki sieci


Na koniec spróbuj przejść cały proces jeszcze raz, bez przepisywania poprzednich kroków. Tym razem dostajesz zadanie:

DEVOPS-101: Add network diagnostic script

Masz przygotować skrypt:

scripts/network-diagnostics.sh

Powinien wyświetlać nazwę hosta, adresy IP, domyślną trasę sieciową oraz informacje o konfiguracji DNS. Znasz już odpowiednie narzędzia z wcześniejszych ćwiczeń na Linuksie, więc sam wybierz polecenia.

Pracę rozpocznij od aktualnego master:

git switch master
git pull

Następnie utwórz gałąź:

git switch -c feature/network-diagnostics

Przygotuj skrypt i dokumentację. Zapisz je w co najmniej dwóch sensownie podzielonych commitach. Kiedy skończysz, opublikuj gałąź i utwórz Pull Request do master.

Tym razem samodzielnie przejrzyj zmienione pliki. Znajdź przynajmniej jedną rzecz, którą można poprawić: komunikat wyświetlany użytkownikowi, obsługę błędu albo brakujący opis w README. Zapisz poprawkę w kolejnym commicie i wyślij ją na tę samą gałąź.

Po zakończeniu wykonaj merge na GitHubie, zaktualizuj lokalny master i usuń zakończony feature branch.

Kontrola po ćwiczeniu

Sprawdź końcowy stan repozytorium:

git status
git branch -a
git remote -v
git log --oneline --decorate --graph --all -20

Jeżeli cały proces przebiegł poprawnie, lokalny master powinien zawierać obydwa nowe skrypty: disk-monitoring.sh i network-diagnostics.sh.

Najważniejsze polecenia z tej lekcji

PolecenieZastosowanie
git switch masterPrzejście na główną gałąź
git pullPobranie i integracja zmian z gałęzią lokalną
git switch -c feature/xyzUtworzenie gałęzi do nowego zadania
git addPrzygotowanie zmian do commita
git commitZapisanie zmian w historii
git push -u origin feature/xyzPierwsza publikacja feature brancha
git pushWysłanie kolejnych commitów
git fetch originPobranie informacji ze zdalnego repozytorium
git merge origin/masterWłączenie zdalnych zmian z master do aktualnej gałęzi
git branch -d feature/xyzUsunięcie zakończonej gałęzi lokalnej
git fetch --pruneUsunięcie nieaktualnych odniesień do zdalnych gałęzi

Następny krok: Wiesz już, jak przygotować zmianę do code review i włączyć ją do głównej gałęzi. W kolejnej lekcji zajmiemy się bardziej zaawansowaną pracą z historią Git. Przećwiczymy git rebase, git cherry-pick i git commit --amend oraz sprawdzimy, kiedy można poprawiać lokalne commity, a kiedy lepiej pozostawić historię bez zmian.

Kolejna lekcja: Git rebase, cherry-pick i amend – zaawansowana praca z commitami →

← Poprzednia lekcja: Cofanie zmian w Git – restore, reset i revert · Wróć do spisu kursu

Może Cię również zainteresować

Dodaj komentarz