Documente Academic
Documente Profesional
Documente Cultură
Tema 1
Deadline: 11.11.2019, 23:59
Subiect
MiniGit - Sistem de control al versiunii codului.
Motivație
Ionel este student în anul 4 în ATM și se lamentează “că nu știe git”. Nu fi ca Ionel! Echipa POO-ATM
consideră că poți înțelege mai bine “git” dacă încerci să îl implementezi chiar tu.
Tema curentă încearcă acest lucru, provocându-vă să realizați propria versiune de “git”- “MiniGit”. Știm
însă că acest lucru nu este ușor, prin urmare vă venim în ajutor cu o serie de sugestii pentru implementare, la
care adăugăm, bineînțeles, și câteva cerințe, pentru a face provocarea “atractivă”.
The story
Git reprezintă un sistem de control al versiunii codului. Mai exact, când Ionel se apucă să adauge cod la
proiectul lui POO se întreabă dacă noul “feature” la care s-a gândit va funcționa așa cum se așteaptă. Pentru
a nu pierde versiunea actuală, care se întâmplă să fie funcțională, Ionel folosește git ca să creeze un commit,
salvând astfel starea curentă a codului. Aceste commit-uri alcătuiesc o structură de tip listă înlănțuită. De
cele mai multe ori, sistemele de Git folosesc un repository local și un repository remote pentru a salva la
distanță proiectul lui Ionel, cu ajutorul comenzii push. Astfel, Ionel poate lucra de pe altă mașină la
proiectul lui: un commit poate fi adus de pe remote cu ajutorul comenzii pull. Noua funcționalitate atrage
alți contribuitori, care vor să lucreze la proiectul lui Ionel. Apare, deci noțiunea de branch, iar lista
înlănțuită de commit-uri devine o structură arborescentă: mai multe commit-uri pot avea drept commit
precedent același commit. Problemele apar când echipa vrea să unească, prin comanda merge, aceste
branch-uri, însă, cu puțină organizare, pot fi evitate conflictele de la o ramură la alta.
Sugestii de implementare
Pentru implementarea principalelor funcționalități oferite de “git”, vă propunem câteva sugestii. Acestea
sunt orientative, nu obligatorii :-) și vă încurajăm să veniți cu soluții diferite (și mai bune :-D). Sugestiile
le-am ordonat cronologic, pentru a vă crea o imagine de ansamblu mai bună a utilizării aplicației finale.
Așadar, să începem…
Ionel va putea folosi “MiniGit-ul” în directorul în care are fișierele/proiectul pe care dorește să le/îl
versioneze. Prin urmare, primul pas pe care Ionel va trebui să îl facă este să meargă în acel director și să
verifice existența fișierelor dorite a fi administrate de “MiniGit”.
Ca exemplu, noi am mers în directorul tema_poo, unde avem disponibile două fișiere: source1.cpp și
source1.h.
Următorul pas pe care Ionel trebuie să îl facă este să lanseze “MiniGit” și să înceapă cu prima comandă,
MiniGit init, care va instanția procesul de pregătire a directorului pentru versionare (vor fi create două
directoare, local și remote, fiecare având un scop și conținut anume, detaliat în pașii următori). Efectul
comenzii se poate observa în imaginea de mai jos.
Ionel este pregătit să înceapă adăugarea fișierelor pe care dorește să le monitorizeze. Pentru a face acest
lucru, el va executa comanda MiniGit add <filename>, prin care fișierul ales va fi marcat pentru includerea
în următorul commit.
În exemplul următor este prezentat rezultatul execuției comenzii MiniGit add source1.cpp. Fișierul local.git
este creat și gestionat de un proces specific, prin care se realizează administrarea adăugării fișierelor pentru
nou commit și crearea acestuia.
Pentru adăugarea unui alt fișier, Ionel va executa aceeași comandă prezentată anterior. Exemplul următor
prezintă rezultatul execuției comenzii MiniGit add source1.h.
În acest moment, Ionel a terminat de adăugat fișierele pe care vrea să le versioneze, astfel că este pregătit
pentru crearea primului său commit. Comanda folosită pentru această operațiune este MiniGit commit
<commit_name> și va putea fi folosită în acest format și pentru commit-uri viitoare.
Figura de mai jos prezintă rezultatul obținut în urma execuției comenzii MiniGit commit commit_1.
Fiind sigur că fișierele sale sunt salvate, Ionel reia lucrul la tema de la POO și implementează funcționalități
noi, care duc la modificarea fișierelor din proiect. Înainte de a închide calculatorul, Ionel se decide să facă un
nou commit, pentru a fi sigur că nu își va pierde codul scris în ultimele ore. Astfel, el va relua pașii anteriori,
de adăugare a unui fișier pentru commit și va face un commit nou.
Rezultatele acestei secvențe de comenzi sunt redate în următoarele două imagini, astfel:
- Rezultatul execuției comenzii MiniGit add source1.cpp (în exemplul nostru, doar în fișierul
source1.cpp au fost introduse secțiuni noi de cod).
După o pauză de câteva zile, Ionel vrea să reia lucrul la tema POO, însă constată, cu stupoare, că ultimele
modificări făcute nu sunt bune, iar fișierele commit salvate local au fost șterse. Își aduce aminte însă că a
executat un push pe o locație remote, însă nu mai știe exact ce commit-uri are disponibile acolo. “MiniGit” îi
oferă posibilitatea de a afla commit-urile pe care le are salvate, prin intermediul comenzii MiniGit log
<remote_location>, care îi va afișa denumirea tuturor fișierelor commit pe care le are salvate în locația
remote.
Fericit să vadă că are suficiente commit-uri salvate, Ionel vrea să refacă starea proiectului său dintr-un
anumit commit. Pentru acest lucru el execută comanda MiniGit pull <remote_location> <commit_name>.
Această comandă îi va reface starea proiectului pornind de la commit-ul selectat. Ca exemplu, figura de mai
jos prezintă rezultatul execuției comenzii MiniGit pull D:\tema_poo\remote 0_1.commit.
După o discuție cu profesorul coordonator, Ionel este pus într-o echipă cu un coleg pentru a continua
implementarea temei. Pentru a le ușura munca în echipă, “MiniGit” le pune la dispoziție posibilitatea creării
unor branch-uri, prin care pot realiza implementări pentru diferite module, urmând apoi să le unească într-o
singură versiune, după efectuarea a suficiente teste.
Modul în care branch-urile vor fi implementate este lăsat în seama voastră, fiind buni programatori și
prieteni ai lui Ionel. Ceea ce vă putem spune sunt comenzile necesare creării unui branch și mutarea
contextului proiectului pe acest nou branch.
● Comanda MiniGit branch <branch_name> creează un branch nou. Pentru a marca această
operațiune, vă sugerăm introducerea unei linii nou în header-ul fișierului local.git, pentru a putea
monitoriza mai ușor fișierele adăugate pe fiecare branch.
● Comanda MiniGit checkout <branch_name> mută contextul curent de versionare a proiectului pe
branch-ul selectat. Prin urmare, orice modificare a unui fișier și adăugare pentru commit, vor fi
marcate pe acest branch și doar pe acesta.
Dacă veți considera că totul a fost simplu până în acest punct, vă propunem implementarea unei comenzi
suplimentare, anume MiniGit merge <branch_name_1> <branch_name_2>. Această comandă va uni două
branch-uri, ținând cont de fișierele modificate/introduse/șterse, pornind de la parametrul timestamp aferent
fiecărui fișier salvat într-un commit.
Ce se urmărește?
- Aplicarea conceptelor prezentate în primele 5 laboratoare;
- Implementarea corectă a claselor și inițializarea adecvată a obiectelor;
- Identificarea necesității folosirii pattern-ului Singleton și implementarea corectă a acestuia;
- Gruparea eficientă a elementelor în cadrul claselor;
- Aplicarea principiului încapsulării;
- Aplicarea principiului polimorfismului prin funcții supraîncărcate;
- Modularizarea codului sursă - lucrați ca și cum altcineva ar urma să folosească sursele voastre;
- Utilizarea elementelor C++: parametrii impliciți, referințe, membrii și metode statice și constante,
etc.
- Crearea propriilor implementări a elementelor folosite adesea (de ex. vectori, liste, etc.). Este
permisă folosirea tipului de date string;
- NU se recomandă utilizarea bibliotecii STL sau a altor framework-uri C++. Rolul temei este acela de
a vă familiariza cu modul de gândire în programarea orientată pe obiecte și nu de a deveni un simplu
beneficiar al implementărilor altora.
- În corectarea temei o importanță deosebită o are modelarea problemei propuse.