Git este un sistem de management și versionare a codului sursă care permite lucrul eficient la un proiect software. De obicei, se lucrează în linia de comandă; pentru Linux și MacOS, nu există probleme însa utilizatorii de Windows nu pot folosi “cmd” și este necesar “Git Bash”.
GitHub este o platformă online, bazată pe Git, pe care dezvoltatorii o pot folosi pentru a stoca și versiona codul lor sursă. Git este utilitarul folosit, iar GitHub este serverul și aplicația web pe care rulează acesta, locul în care păstrăm repository-ul remote.
Dacă aveți deja un cont pe GitHub, fiți siguri ca aveți o poză reală cu voi la profil, numele și prenumele vostru.
Dacă nu aveți cont intrați pe GitHub. Puteți să creați unul fie folosind e-mail de la facultate, fie cel personal.
Introduceți un nume de utilizator (username), adresa voastră de e-mail și o parolă sigură pentru cont. Pentru validarea contului, accesați-vă căsuța de e-mail. Acolo veți găsi un e-mail în care vi se explică cum se poate valida noul cont creat. Verificați și căsuța spam în caz că nu ați primit nimic în inbox.
Accesați link-ul către UPB-FILS-SdE2. Dați “Sign in”, apoi trebuie să vă căutați numele de utilizator, faceți click pe el și “Accept this assignment”. Dați refresh paginii, iar apoi puteți să vă vedeți repository-ul Devoir 0.
Primul pas este să instalați Git. Apoi deschideți Visual Studio Code. În bara de sus se observă Terminal, faceți click pentru a deschide un nou terminal.
Urmați imaginile de mai jos pentru a deschide un terminal Git Bash:
Alegeți Git Bash!
Primul pas pentru a utiliza Git este să facem configurarea cu numele și e-mail-ul vostru cu comenzile următoare:
user:~$ git config --global user.name "Prenume Nume" user:~$ git config --global user.email "adresa_de_email@example.com"
Vom crea un repository pe GitHub, unul local, după care le vom interconecta.
Acum avem un repository creat remote, pe GitHub, numit Sde2-TP1.
În directorul home, vom crea un un director unde vom inițializa repository-ul Git.
După tastarea comenzilor urmatoare, veți avea un output similar cu cel din imagine.
user:~$ mkdir SdE2-TP1 user:~$ cd SdE2-TP1 user:~/SdE2-TP1$ git init user:~/SdE2-TP1$ ls -a
Am inițializat repository-ul local folosind comanda git init, din directorul creat numit SdE2-TP1. Totodată, am folosit comanda ls -a pentru a afișa directoarele ascunse, căci directorul .git, este un director ascuns.
Operația init este una locală și are rolul de a inițializa un repository gol, local. Inițializarea repository-ului local înseamnă crearea, în directorul ales, a mediului pentru a putea lucra la un proiect software versionat Git. Această operare duce la crearea unui director numit .git în care se vor ține ulterior date suplimentare despre repository, numite metadatele repository-ului.
Anterior am creat un repository local și unul remote, iar pentru a lucra cu ele trebuie să le interconectăm, folosind comanda:
user:~/SdE2-TP1$ git remote add origin https://github.com/{username}/SdE2-TP1.git
{username} este utilizatorul pe GitHub, de exemplu conform numele utilizatorului din exemplele anterioare acesta va fi înlocuit cu alexandra2607.
Conectarea celor două repository-uri înseamnă setarea repository-ului origin, adică repository-ului remote la cel local.
În cazul în care suntem mai mulți membri în echipă, fiecare membru va conecta repository-ul său local, la repository-ul remote. Pentru conectarea celor două repository-uri folosim comanda de mai sus, dată în directorul unde este repository-ul local Git.
Working area este directorul în care lucrați, conține multe fișiere, deși nu toate pot să facă parte din proiectul final.
Staging area este ca un spațiu nefinalizat, este locul unde puteți adăuga versiunea unui fișier sau mai multe fișiere pe care doriți să le salvați, adică sa facă parte din proiectul vostru.
Repository aici se află tot ce este în staging area și va reprezenta o nouă versiune a proiectului.
Afișează starea modificărilor locale.
Adaugă modificările în staging area.
Adaugă schimbările aflate deja in staging are in repository-ul local.
“Împinge” schimbările din local către github(remote repository)
Ia schimbările din remote repository.
Clonează un repository într-un director nou.
Odată creat repository-ul, putem să începem să lucrăm la proiect.
Lucrul la proiect înseamnă să adăugăm și să ștergem fișiere sau să modificăm fișiere existente. De obicei este vorba de fișiere text (human-readable), cel mai des fișiere cod sursă. Vrem să salvăm aceste adăugări și modificări; apoi să salvăm din nou alte modificări; și tot așa.
Același lucru îl fac și ceilalți colegi care lucrează la același proiect. Fiecare commit împachetează un set de adăugări și modificări realizate de un dezvoltator al proiectului. Având commiturile în repository putem să gestionăm mai ușor proiectul, adică:
Git se ocupă de păstrarea și gestiunea istoricului repository-ului nostru prin păstrarea listei de commituri făcute. Adică Git păstrează un istoric de versiuni al proiectului.
Salvarea acestor modificări înseamnă crearea unui commit în repository.
Fără a actualiza și repository-ul remote, ceilalți colegi nu vor putea vedea schimbările făcute de noi. Vrem, așadar, ca modificările făcute local să se găsească și remote. Adică să publicăm commiturile din repository-ul local în repository-ul remote. Realizăm publicarea prin operația push.
Vom vedea în următoarele secțiuni care sunt pașii pentru a crea un commit și pentru a-l publica.
Pașii creării unui commit sunt următorii:
Exemplu: Vom crea un fișier README.md pe care-l vom publica în repository-ul SdE2-TP1 de pe GitHub.
user:~/SdE2-TP1$ touch README.md
Prin starea repository-ului înțelegem forma la care am adus proiectul prin modificările noastre. Aceasta include ce fișiere am creat, modificat sau șters de la ultimul commit. Ne interesează întotdeauna starea repository-ului pe care lucrăm.
Pentru a verifica starea repository-ului folosim comanda git status:
user:~/SdE2-TP1$ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) README.md nothing added to commit but untracked files present (use "git add" to track)
Prima linie afișată On branch master se referă la branch-ul master local.
A doua linie afișată No commits yet ne spune că nu am făcut până acum niciun commit, adică am pornit de la un repository gol.
În ultima parte a outputului se află o listă de fișiere untracked, adică lista fișierelor pe care Git le vede ca nou adăugate în repository-ul curent, dar pe care nu le monitorizează încă. Acest lucru înseamnă că, deocamdată, orice modificare vom face asupra acestor fișiere nu va fi urmărită (tracked) de Git. În cazul nostru, fișierul aflat în starea untracked este README.md.
Un commit va conține o listă de modificări: fișiere adăugate, fișiere șterse, conținut modificat. Un pas intermediar în crearea unui commit este pregătirea modificărilor ce vor fi parte din commit. Acest pas de pregătire înseamnă să adăugăm (add) aceste modificări în zona de lucru pentru Git, numită staging area.
În cazul nostru, vrem să adăugăm fișierul README.md vom folosi comanda git add *, care va încărca toate modificarile.
user:~/SdE2-TP1$ git add * user:~/SdE2-TP1$ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: README.md
Primele 2 mesaje afișate au rămas neschimbate. Partea interesantă apare la ultima parte a outputului. Vedem că mesajul a devenit Changes to be commited. Acest lucru înseamnă că acum Git urmărește noile modificări și așteaptă ca modificările să fie adunate într-un commit.
Acum vrem ca modificările de mai sus să ajungă în repository. Pentru aceasta creăm un commit folosind comanda git commit:
user:~/SdE2-TP1$ git commit -m "Add README file" [master (root-commit) b051b88] Add README file 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 README.md user:~/SdE2-TP1$ git status On branch master nothing to commit, working tree clean
Am folosit descrierea Add README file la comanda git commit drept mesaj de commit. Aceasta trebuie să fie punctuale și ușor de înțeles.
Creați un fișier _exemple.py, urmați pașii anteriori și puneți ca și mesaj pentru commit “Add exemple.py”.
Pentru a vedea istoricul de commit-uri folosiți comanda git log.
Până acum am facut modificări locale, dacă intram pe pagina de GitHub la repository-ul “SdE2-TP1” nu putem vedea modficarile, pentru asta este necesară comanda git push.
user:~/SdE2-TP1$ git push origin master Username for 'https://github.com': alexandra2607 Password for 'https://alexandra2607@github.com': Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Writing objects: 100% (3/3), 230 bytes | 230.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To https://github.com/alexandra2607/SdE2-TP1.git * [new branch] master -> master
Acum, dacă intrați pe GitHub, la repository-ul “SdE2-TP1” puteți vedea modificările și numărul de commit-uri.
Dacă nu aveți deja instalat Visual Studio Code îl puteți instala de aici.
Pentru a aduce în Visual Studio Code, repository-ul pe care l-am creat în prima parte a laboratorului vom folosi comanda git clone urmată de link-ul către repository.
Creați un director cu cu numele SdE2-TP1-vsc și deschideți-l în Visual Studio Code. În continuare ne vom folosi de terminalul din Visual Studio Code, dacă întâmpinați dificultăți în a-l folosi, accesați acest link.
Tastați comanda:
git clone https://github.com/{username}/SdE2-TP1.git
Dacă este prima dată cand utilizați Git în Visual Studio Code imediat după aceasță comandă trebuie să urmați pașii următori:
Faceți click pe “Sign in with your browser”
Din browser, faceți click pe Authorize GitCredentialManager, iar apoi vă puteti întoarce în VSCode.
Vom modifica conținutul celor două fișiere și le vom pune apoi pe GitHub.
Scrieți în fișierul README.md textul ”# SdE2-TP1”, iar în exemple.py:
print("Hello")
După modificări se poate observa că în partea stângă la iconița pentru “Source Control” apare cifra 2, care reprezintă numarul de modificări. Dacă faceți click pe el veți vedea o listă cu modifcări, apăsați unul dintre ele iar VSCode va arăta două versiuni ale fișierul moficicat și cel inițial.
Pentru a salva versiunea nouă a proiectului și pentru a o pune pe GitHub, trebuie să facem commit, apoi push. Ne putem folosi de comenzile învățate în prima parte însa VSCode vine cu Git source control manager.
În acest exemplu am ales ca mesajul commit-ului să fie “Update”, care se scrie în câmpul de text, așa cum se vede în imaginea de mai jos. Apoi se apasă pe iconița încercuită de mai jos pentru a se reazliza commit-ul.
Pentru a face “push” facem click pe “More actions”, cele 3 puncte din colț, iar apoi se deschide un tab unde putem vizualiza mai multe comenzi. Facem click pe “push”, iar modificările au fost încărcate pe GitHub, intrați pe site la repository-ul vostru și veți vedea modificările.
GitHub oferă posibilitatea de a edita fișierele direct din repository. În acest exemplu vom modficica fișierul exemple.py, punând codul:
print("Hello SdE2")
Faceți scoll în josul paginii și veți vedea un buton “Commit changes”, apăsați-l pentru a salva noua versiune.
Pentru mai multe informații citiți aici.
Intrați în VSCode și puteți observa ca fișierul exemple.py nu are noile modificări. Dacă modifcăm fișierul fară a-l aduce la zi și local după commit, push-ul cu noile modificări va fi respins.
Branch-urile se folosesc atunci când un dezvoltator vrea să lucreze la o funcționalitate nouă pe care poate face commit-uri noi, care poate destabiliza proiectul.Ulterior, dacă funcționalitatea este utilă, va fi adăugată în proiect prin unificarea acestui branch (merge); altfel branch-ul va fi șters.
Un repository Git are un branch principal de dezvoltare, numit master. Branch-ul master este branch-ul implicit cu care lucrăm, în care adăugăm commituri și în care vedem istoricul de commituri.
Pentru a vedea istoricul de commit-uri se folosește comanda git log.
Exemplu de reprezentare grafică a commit-urilor.
Root-commit-ul este primul commit din istoric. Toate celelalte commituri vin în continuarea acestuia.
În acest moment, pe repository-ul nostru aveți un singur branch - master. În continuare vom lucra la proiectul nostru SdE2-TP1.
În următoarea secțiune vom adăuga un fișier .gitignore proiectului.
Fișier .gitignore va fi adaugat repository-ului de pe un alt branch pe care îl numim add-gitignore ca să ne obișnuim să folosim branch-uri.
În această secțiune vom face modificări pe un nou branch, nu pe branch-ul master.
Spre exemplu, nu punem fișiere obiect și fișiere executabile în repository pentru că sunt fișiere generate pentru un anumit tip de sistem. Având codul sursă, putem genera fișierele obiect și executabile pe sistemul nostru.
Verificăm branch-ul pe care ne aflăm folosind comanda git branch:
user:~/SdE2-TP1$ git branch * master
Creăm un nou branch folosind comanda:
user:~/SdE2-TP1$ git branch add-gitignore user:~/SdE2-TP1$ git branch add-gitignore * master
Acum avem 2 branch-uri add-gitignore și master și ne aflăm pe branch-ul master.
Trecem pe branch-ul add-gitignore folosind comanda git checkout:
user:~/SdE2-TP1$ git checkout add-gitignore Switched to branch 'add-gitignore' user:~/SdE2-TP1$ git branch * add-gitignore master
În acest moment branch-ul add-gitignore nu diferă de branch-ul master. Când vom face schimbări (în formă de commituri), cele două branch-uri vor diverge.
Nu dorim să avem fișiere obiect în repository așa că vom configura Git să ignore aceste fișiere. Facem acest lucru prin adăugarea șirului *.o în fișierul .gitignore:
user:~/SdE2-TP1$ echo "*.o" > .gitignore andra@ubuntu:~/SdE2-TP1$ ls -a . .. exemple.py .git .gitignore README.md user:~/SdE2-TP1$ git status On branch add-gitignore Untracked files: (use "git add <file>..." to include in what will be committed) .gitignore
Creăm un commit cu această modificare (git add și git commit) și îl publicăm (git push):
user:~/SdE2-TP1$ git add .gitignore andra@ubuntu:~/SdE2-TP1$ git status On branch add-gitignore Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: .gitignore user:~/SdE2-TP1$ git commit -m "Add .gitignore file" [add-gitignore a34fa81] Add .gitignore file 1 file changed, 1 insertion(+) create mode 100644 .gitignore user:~/SdE2-TP1$ git push origin add-gitignore Username for 'https://github.com': alexandra2607 Password for 'https://alexandra2607@github.com': Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 332 bytes | 332.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) remote: remote: Create a pull request for 'add-gitignore' on GitHub by visiting: remote: https://github.com/alexandra2607/SdE2-TP1/pull/new/add-gitignore remote: To https://github.com/alexandra2607/SdE2-TP1.git * [new branch] add-gitignore -> add-gitignore
Am publicat commitul în repository-ul remote pe branch-ul add-gitignore. Odată cu publicarea commitului pe GitHub, a fost creat și branch-ul add-gitignore în repository-ul remote.
În secțiunea anterioară de mai sus am creat un commit pe branch-ul add-gitignore.
Vrem ca modificarea făcută de noi, în acest caz crearea unui fișier gitignore, să se regăsească și pe branch-ul master. Facem acest lucru prin intermediul operației merge, operație care unește două branch-uri: adică aduce conținutul unui branch pe un alt branch, în cazul nostru de pe add-gitignore pe master. Pentru a face acest lucru trebuie să fim pe branch-ul master, adică pe branch-ul în care vrem să integrăm schimbările.
Trecem pe branch-ul master local folosind comanda git checkout, apoi pentru a ne sincroniza cu master remote :
user:~/SdE2-TP1$ git checkout master Switched to branch 'master' Your branch is up to date with 'origin/master'. user:~/SdE2-TP1$ git pull origin master From https://github.com/alexandra2607/SdE2-TP1 * branch master -> FETCH_HEAD Already up to date.
Branch-ul master local este sincronizat cu cel remote. Integrăm branch-ul add-gitignore în branch-ul master folosind comanda git merge:
user:~/SdE2-TP1$ git merge add-gitignore Updating 0ee4397..a34fa81 Fast-forward .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore user:~/SdE2-TP1$ git status On branch master Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working tree clean
Acum avem pe repository-ul local un commit în plus față de repository-ul origin (Your branch is ahead of 'origin/master' by 1 commit), adică avem un commit care nu a fost publicat. Verificăm istoricul de commituri pentru a-l vedea folosind comanda git log. Apoi, trebuie să-l publicăm în repository-ul origin folosinf comanda git push origin master.
Dacă intrăm pe pagina de GitHub la repository-ul nostru putem vedea ca fișierul .gitgnore a fost adăugat pe master.
În acestă secțiune vom șterge branch-ul add-gitignore atât din repository-ul local cât și din interfața GitHub, folodind comanda git branch -d, apoi vom face push.
user:~/SdE2-TP1$ git branch add-gitignore * master user:~/SdE2-TP1$ git branch -d add-gitignore Deleted branch add-gitignore (was a34fa81). user:~/SdE2-TP1$ git branch * master user:~/SdE2-TP1$ git push origin --delete add-gitignore Username for 'https://github.com': alexandra2607 Password for 'https://alexandra2607@github.com': To https://github.com/alexandra2607/SdE2-TP1.git - [deleted] add-gitignore user:~/SdE2-TP1$
În această subsecțiune vom relua pașii prezentați în subsecțiunile anterioare. Vom lucra în continuare pe branch-uri. Vom adăuga o nouă linie în fișierul .gitignore, vom crea un commit cu această schimbare și vom integra schimbările din branch-ul secundar în branch-ul master prin operația merge.
Se crează un nou branch apăsând pe numele branch-ului actual, iar apoi VSCode ne oferă opțiunea de a crea unul nou tot ce rămane de facut este doar să introducem numele.
Creăm un branch numit update-gitiginore și VSCode ne mută automat în el. Putem folosi terminalul și comanda git checkout pentru a ne muta dintr-un branch în altul sau apăsam pe numele branc-ului și-l selectam pe cel nou.
Suntem pe branch-ul update-gitignore și adăugăm linia: build/ în fișierul .gitignore. Apoi, facem commit la fel ca în secțiune anterioară Commit in VSCode. Pentru a vedea modificările pe noul branch este obligatoriu să facem push.
Revenim pe branch-ul master doar apăsând pe numele branch-ului curent, apoi apăsăm pe “master”. În continuare, efectuăm operația merge între branch-ul update-gitignore și master.
Fiți siguri că v-ați mutat pe branch-ul master, apoi trebuie să faceți merge, ca în imaginea de mai jos.
Ultimul pas pentru a face modificările în repository este să faceți push.