Znajomość podstaw pracy z systemem kontroli wersji jest jedną z umiejętności, którą powinna posiąść każda osoba ucząca się programowania. W przypadku małych projektów osobistych umożliwia ona bardziej swobodną i efektywną pracę. Natomiast w przypadku większych projektów umożliwia sprawne zdążanie równolegle wprowadzanymi zmianami.
Praca nad projektem nie ogranicza się jedynie do implementacji rozwiązań problemów biznesowych. Ważne jest umiejętne zarządzanie stanem kodu i wprowadzanymi w nim zmianami. W przypadku małych projektów osobistych, nad którymi pracuje jedna osoba problem ten nie jest tak zauważalny. Jednak wraz z rozwojem projektu i wzrostem liczby osób nad nim pracujących skala tego problemu staje się znacznie większa. Na szczęście zagadnienie to jest na tyle uniwersalne, że narzędzia do jego rozwiązywania są bardzo dobrze rozwinięte i ogólnodostępne. Takie narzędzia nazywane są systemami kontroli wersji. Wśród najpopularniejszych systemów kontroli wersji znajdują się między innymi:
System kontroli wersji - oprogramowanie pozwalające na zarządzanie zmianami wprowadzanymi do kodu źródłowego aplikacji. Pozwala na równoległe rozwijanie alternatywnych wersji kodu, łącznie zmian w spójną całość, oraz wycofywanie zmian będących wynikiem błędu.
W tym wpisie skupię się na pracy z GIT-em.
W celu rozpoczęcia pracy z GIT-em na początku należy udać się na stronę i zainstalować go na swoim komputerze. W zależnością od systemu operacyjnego na którym pracujemy proces może przebiegać nieco inaczej.
Po zainstalowaniu GIT-a na komputerze można zacząć wykorzystywać go do zarządzania zmianami w wprowadzanymi do projektu. W celu przedstawienia tego procesu stworzyłem nowy projekt składający się z pliku index.html
wraz z podpiętym arkuszem stylów styles.css
i grafiką Git-Logo-2Color.png
wykorzystywana jako tło jednego z elementów.
./index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hello git!</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body class="centered-content">
<h1>Hello</h1>
<img id="git-logo" src="Git-Logo-2Color.png" alt="git logo" />
</body>
</html>
./styles.css
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap");
:root {
--primary: #f34f29;
--secondary: #3d2d00;
--light: #f0f0f0;
}
html,
body {
height: 100%;
width: 100%;
background-color: var(--light);
margin: 0;
padding: 0;
}
.centered-content {
display: flex;
align-items: center;
justify-content: center;
}
h1 {
font-family: "Roboto", sans-serif;
font-size: 144px;
color: var(--secondary);
}
#git-logo {
height: 150px;
margin-left: 20px;
}
Efekt otwarcia pliku index.html
przy pomocy przeglądarki internetowej wygląd tak:
Aby móc zarządzać projektem za pomocą git-a należy zainicjalizować w nim lokalne repozytorium. Można to zrobić za przy pomocy wiersza poleceń. W pokazanym poniżej przykładzie korzystam z narzędzia GitBash. Równie dobrze może być to inny terminal, albo narzędzie pozwalające na pracę z gitem przy pomocy interfejsu granicznego.
Po przejściu do lokalizacji projektu i próbie sprawdzania aktualnego stanu lokalnego repozytorium przy pomocy polecenia git status
git zwraca błąd wynikający z tego, że lokalne repozytorium git-a nie istnieje w tej (ani żadnej z nadrzędnych) lokalizacji.
Lokalne repozytorium - obszar na dysku podlegający systemowi kontroli wersji.
Lokalne repozytorium git-a dla danego projektu można zainicjalizować przy pomocy polecenia git init
. Po wykonaniu tej akcji ponowne wywołanie polecenia git status
zwraca kilka informacji:
W celu stworzenie nowego commit-a zawierającego wprowadzone do tej pory zmiany należy wskazać te pliki przy pomocy komendy git add [względne ścieżki plików]
, lub git add .
w celu dodania wszystkich plików.
Teraz pliki zostały przeniesione do poczekalni, jednak sam commit nie został jeszcze wykonany. W celu wykonania commit-a należy wykonać polecenie git commit -m [opis commit-a]
.
W tym momencie zmiany zostały zapisane w formie commit-a. Listę commit-ów można podejrzeć wpisując polecenie git log
.
Każdy commit posiada swój identyfikator w tym przypadku jest to 3d5c928ac1e3b6f8f075620ca381600c928ab0c1. Przy pomocy tego identyfikatora można wskazać commit w przypadku operacji, które tego wymagają. Przykładem takiej operacji jest podejrzenie zawartości commit-a przy pomocy polecenia git show [id commit-a]
Commit - operacja zapisu zmian dokonanych na repozytorium wraz z opisem i unikalnym identyfikatorem.
Do tej pory wszystkie pokazywane operacje były wykonywane na branch-u master. Jednak praca z gitem zazwyczaj opiera się na zarządzaniu kilkoma brachami. W celu sprawdzenia branchy występujących w naszym lokalnym repozytorium należy wpisać w konsoli polecenie git branch
.
W celu stworzenia nowego branch-a na podstawie aktualnego należy wpisać polecenie git branch [nazwa nowego branch-a]
. Następnie można na niego przejść przy pomocy polecenia git checkout [nazwa istniejącego branch-a]
. Alternatywnie można skorzystać ze skróconej sładki i za pomocą polecenia git checkout -b [nazwa nowego brach-a]
strwożyć nowy branch i od razu na niego przejść.
Branch - stan kodu zapisywany jako odniesienie do ostatniego commit-a.
Zmiany wprowadzane na jednym branch-u nie wpływają na inne branch-e. Dlatego po wprowadzaniu i z-commit-owaniu zmian na branch-u feature/top-navbar będą one występowały tylko tam. Branch-e develop i master będą w takim stanie w jakim je pozostawaliśmy w momencie przełączania się na inny branch. Dlatego po wprowadzaniu i z-commit-owaniu zmian na branch-u feature/top-navbar będą one dostępne tylko z poziomu tego branch-a:
./index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hello git!</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="page-wrapper">
<div id="top-nav">
<a class="nav-link" href="">First</a>
<a class="nav-link" href="">Second</a>
<a class="nav-link primary-link" href="">Primary</a>
</div>
<div id="main-content">
<h1>Hello</h1>
<img id="git-logo" src="Git-Logo-2Color.png" alt="git logo" />
</div>
</div>
</body>
</html>
./styles.css
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap");
:root {
--primary: #f34f29;
--secondary: #3d2d00;
--light: #f0f0f0;
--dark: #3d3d3d;
}
html,
body {
height: 100%;
width: 100%;
background-color: var(--light);
margin: 0;
padding: 0;
}
#page-wrapper {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#top-nav {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
height: 125px;
width: 100%;
background-color: var(--dark);
}
#main-content {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.nav-link {
font-family: "Roboto", sans-serif;
font-size: 36px;
text-decoration: none;
border: 4px solid var(--light);
border-radius: 10px;
padding: 10px;
color: var(--light);
}
.nav-link.primary-link {
border-color: var(--primary);
color: var(--primary);
}
h1 {
font-family: "Roboto", sans-serif;
font-size: 144px;
color: var(--secondary);
}
#git-logo {
height: 150px;
margin-left: 20px;
}
Jednak po przejściu na brach develop powrócimy do stanu z pierwszego commit-a. W celu wprowadzania zmian na branch develop można wykonać polecenie git merge [nazwa branch-a]
.
Merge - operacja łączenia zmian z commit-ów pochodzących z różnych branchy.
W ten sposób zmiany wprowadzone na branch-u feature/top-navbar zostały wprowadzone również na branch-u develop.
Dużą zaletą git-a jest to, że pozwala na wygodne odwracanie zmian. W zależności od tego z jak dawna pochodzi commit, który chcemy cofnąć do tego tematu można podejść na rożne sposoby np:
Reset branch-a do danego commit-a jest wygodnym podejściem, jednak możemy wykonać go w przypadku, gdy chcemy cofnąć ostatni/e commit/y i wiemy, że nikt inny nie pracuje na tym branch-u. Załóżmy, że do aktualnego stanu develop-a został dodany commit modyfikujący kolory zdefiniowane w arkuszach stylów:
Jednak ostatecznie wybrane kolory nie okazały się najlepsze...
Zmiany te były wykonane w ostatnim commit-cie, a dodatkowo nikt inny nie pracuje nad tym projektem, wiec bezpiecznie można zrestartować branch do stanu z poprzedniego commit-a. Można zrobić to przy pomocy komendy git reset --hard [id commit-a]
. Wykonanie polecenia z flagą --hard
spowoduje natychmiastowy powrót branch-a do stanu ze wskazanego commit-a. Z jednej strony jest to wygodne gdyż nie powoduje zaśmiecania historii commit-ów. Z drugiej strony należy zachować ostrożność, aby nie stracić ważnych zmian.
Alternatywnym podejściem może być wykonanie commit-a odwracającego zmiany. W ten sposób git automatycznie przygotuje zmiany przeciwne do tych wprowadzonych we wskazanym commit-cie i stworzy z nich nowy commit. Jest to podejście bardziej elastyczne i bezpieczne, jednak nie pozwala na zachowanie tak czystej historii commit-ów jak wcześniejszy sposób. Można zrobić to wykonując polecenie git revert [id commit-a do wycofania]
Ręczne wpisywanie poleceń w konsoli git-a nie jest jest jedynym sposobem na pracę z tym systemem kontroli wersji. Obecnie istnieje wiele narzędzi pozwalających na zarządzanie gitem za pomocą interfejsu graficznego. Przykładami mogą byc narzędzia zintegrowane w Visual Studio Code, albo Intellij.
Reasumując: w tym wpisie zostały przedstawione podstawy pracy z lokalnym repozytorium git-a takie jak:
git init
git status
git add [względne ścieżki plików]
git add .
git commit -m [opis commit-a]
git log
git show [id commit-a]
git branch
git branch [nazwa nowego branch-a]
git checkout [nazwa istniejącego branch-a]
git checkout -b [nazwa nowego brach-a]
git merge [nazwa branch-a]
git reset --hard [id commit-a]
git revert [id commit-a do wycofania]
Reprezentują one jedynie niewielki wycinek możliwości jakie daje nam git, jednak pozwalają już na w miarę sprawne zarządzanie zmianami wprowadzanymi w lokalnym repozytorium i w razie potrzeby umożliwiają wygodne wycofywanie błędów. Obecnie istnieje wiele narzędzi pozwalających na pracę z git-em przy pomocy interfejsu graficznego (np. Visual Studio Code), a nie linii poleceń.
Źródła: