====== Laborator 01. Introducere în Programarea Android ======
===== Sistemul de Operare Android =====
==== Android - Prezentare Generală =====
Android este un sistem de operare mobil bazat pe o versiune modificată de Linux (pentru gestiunea componentelor hardware, a proceselor și a memoriei) și biblioteci Java (pentru telefonie (audio/video), conectivitate, grafică, programarea interfețelor cu utilizatorul). Este un produs open-source (putând fi dezvoltat de producătorii de dispozitive mobile cu extensii proprietare pentru a-și particulariza platforma), dezvoltat în prezent de compania Google, conceput pe ideea transformării dispozitivelor mobile în adevărate mașini de calcul. Google încearcă totuși să realizeze tranziția de la AOSP (Android Open Source Project) către GMS (Google Mobile Services), peste care sunt construite cele mai multe aplicații, în încercarea de a-și apăra acest proiect în fața concurenței. În acest sens, a fost dezvoltat **proiectul Google One**, prin care este oferit un set de specificații (ecran de 4.5 inchi - 845x480 pixeli, procesor quad-core, memorie 1GB RAM, spațiu de stocare 4GB, suport pentru dual sim) pe care producătorii de dispozitive mai ieftine trebuie să le respecte astfel încât acestea să fie compatibile cu un sistem Android, fără a întâmpina probleme de performanță. Acesta include toate aplicațiile și serviciile Google, la care se pot adăuga și altele, furnizate de producător sau operatorul de telefonie mobilă. În acest fel, se asigură calitatea (păstrând renumele Android) și controlul asupra veniturilor. Comunitatea Android este în creștere, mai multe companii renunțând la propriul sistem de operare în favoarea acestuia, pentru a putea face față fenomenului iPhone.
În condițiile în care pe piața dispozitivelor mobile aplicațiile sunt cele care aduc avantajul competițional, beneficiul Android este reprezentat de abordarea unitară pentru dezvoltarea aplicațiilor. Cu alte cuvinte, o aplicație dezvoltată conform API-ului Android va putea rula pe mai multe dispozitive mobile pe care este instalat sistemul de operare respectiv.
==== Versiuni Android ====
^ Versiune Android ^ Nivel API ^ Data Lansării ^ Nume de Cod ^ Cota de Piață ^
| 6.0 - 6.0.1 | 23 | 05.10.2015 | Marshmellow | 1.2% |
| 5.1 - 5.1.1 | 22 | 09.03.2015 | Lollipop | 17.1% |
| 5.0 - 5.0.2 | 21 | 12.11.2014 | Lollipop | 17.0% |
| 4.4W - 4.4W.2 | 20 | 25.06.2014 | KitKat with wearable extensions | |
| 4.4 - 4.4.4 | 19 | 31.10.2013 | KitKat | 35.5% |
| 4.3 | 18 | 24.07.2013 | Jelly Bean | 3.4% |
| 4.2.x | 17 | 13.11.2012 | Jelly Bean | 11.7% |
| 4.1.x | 16 | 09.07.2012 | Jelly Bean | 8.8% |
| 4.0.3 - 4.0.4 | 15 | 16.12.2011 | Ice Cream Sandwich | 2.5% |
| 4.0 - 4.0.2 | 14 | 19.10.2011 | Ice Cream Sandwich | |
| 3.2 | 13 | 15.07.2011 | Honeycomb | |
| 3.1 | 12 | 10.05.2011 | Honeycomb | |
| 3.0 | 11 | 22.02.2011 | Honeycomb | |
| 2.3.3 - 2.3.7 | 10 | 09.02.2011 | Gingerbread | 2.7% |
| 2.3 - 2.3.2 | 9 | 06.12.2010 | Gingerbread | |
| 2.2 - 2.2.3 | 8 | 20.05.2010 | Froyo | 0.1% |
| 2.1 | 7 | 12.01.2010 | Eclair | |
| 2.0.1 | 6 | 03.12.2009 | Eclair | |
| 2.0 | 5 | 26.10.2009 | Eclair | |
| 1.6 | 4 | 15.09.2009 | Donut | |
| 1.5 | 3 | 30.04.2009 | Cupcake | |
| 1.1 | 2 | 09.02.2009 | | |
| 1.0 | 1 | 23.09.2008 | | |
Pentru identificarea versiunilor se folosesc, de regulă, trei sisteme:
* un număr, ce respectă formatul major.minor[.build], desemnând dacă modificările aduse sunt substanțiale sau reprezintă ajustări ale unor probleme identificate anterior; versiunea curentă este 6.0.1, lansată la sfârșitul anului 2015;
* un nivel de API (același putând grupa un număr de mai multe versiuni), prin care se indică funcționalitățile expuse către programatori; versiunea curentă are nivelul de API 23;
* o denumire, având un nume de cod inspirat din lumea dulciurilor; termenii respectivi încep cu inițiale care respectă ordinea alfabetică; versiunea curentă este Marshmellow.
În momentul în care se ia decizia cu privire la versiunea pentru care se dezvoltă o aplicație Android, trebuie avute în vedere și cotele de piață ale dispozitivelor mobile. Dezvoltarea unei aplicații Android pentru cea mai nouă versiune are avantajul de a se putea utiliza cele mai noi funcționalități expuse prin API. Dezvoltarea unei aplicații Android pentru cea mai veche versiune are avantajul unei adresabilități pe scară largă. Un compromis în acest sens poate fi obținut prin intermediul **bibliotecilor de suport**, dezvoltate pentru fiecare versiune, prin intermediul cărora pot fi utilizate la niveluri de API mai mici funcționalități din niveluri de API mai mari (în limita capabilităților dispozitivului mobil respectiv). Utilizarea acestora reprezintă o practică recomandată în dezvoltarea aplicațiilor Android.
==== Arhitectura Android ====
Arhitectura sistemului de operare Android cuprinde cinci secțiuni grupate pe patru niveluri:
{{ :laboratoare:laborator01:android_architecture.png?nolink&600 }}
- **Kernelul Linux** (cu unele modificări) conține driver-ele pentru diferitele componente hardware (ecran, cameră foto, tastatură, antenă WiFi, memorie flash, dispozitive audio), fiind responsabil cu gestiunea proceselor, memoriei, perifericelor (audio/video, GPS, WiFi), dispozitivelor de intrare/ieșire, rețelei și a consumului de energie; de asemenea, au fost implementate și unele îmbunătățiri:
- **Binder**, sistemul de comunicație inter-proces, a fost adaptat, întrucât reprezintă mediul de comunicație principal dintre aplicații și sistemul de operare, inclusiv funcțiile (serviciile) dispozitivului mobil; expunerea sa este realizată prin intermediul AIDL (Android Interface Definition Language) prin care pot fi manipulate obiecte transformate în primitive utilizate la comunicația propriu-zisă dintre aplicații și sistemul de operare;
- **Logger**, sistemul de jurnalizare, este esențial în cazul în care trebuie realizată depanarea aplicațiilor, în special pentru a detecta anumite situații particulare (informații cu privire la rețea, senzori); acesta este capabil să agrege datele provenite atât de la aplicația propriu-zisă cât și de la sistemul de operare, datele fiind disponibile prin intermediul unor utilitare specializate;
- sistemul prin intermediul căruia se previne transferul sistemului de operare într-o stare de latență (**wake locks**), în care consumul de energie este redus, întrucât se blochează execuția oricărei aplicații; utilizarea unui astfel de mecanism trebuie realizată cu precauție, întrucât poate determina epuizarea bateriei;
- sistemul de **alarme** oferă posibilitatea ca anumite sarcini să fie planificate la anumite momente de timp, putând fi executate, chiar dacă sistemul de operare se găsește într-o stare de latență;
- **Viking Killer** este un mecanism prin care sistemul de operare revendică memoria utilizată, atunci când nivelul acesteia atinge un anumit prag (aplicațiile Android care au fost rulate anterior sunt de regulă stocate în memorie pentru a se putea comuta rapid între ele, de vreme ce încărcarea în memorie este o operație costisitoare);
- **YAFFS2** (Yet Another Flash File System) este un sistem de fișiere adecvat pentru cipuri flash bazate pe porți NAND; platforma Android este stocată pe mai multe partiții, ceea ce îi conferă flexibilitate la actualizări, împiedicând modificarea sa în timpul rulării (''/boot'' - conține secvența de pornire, ''/system'' - stochează fișierele de sistem și aplicațiile încorporate, ''/recovery'' - deține o imagine din care se poate restaura sistemul de operare, ''/data'' - include aplicațiile instalate și datele aferente acestora, ''/cache'' - utilizată pentru fișiere temporare, folosind memoria RAM, pentru acces rapid).
- **Bibliotecile** (user-space) conțin codul care oferă principalele funcționalități a sistemului de operare Android, făcând legătura între kernel și aplicații. Sunt incluse aici motorul open-source pentru navigare WebKit, biblioteca FreeType pentru suportul seturilor de caractere, baza de date SQLite utilizată atât ca spațiu de stocare cât și pentru partajarea datelor specifice aplicațiilor, biblioteca libc (Bionic), biblioteca de sistem C bazată pe BSD și optimizată pentru dispozitive mobile bazate pe Linux, biblioteci pentru redarea și înregistrarea de conținut audio/video (bazate pe OpenCORE de la PacketVideo), biblioteci SSL pentru asigurarea securității pe Internet și Surface Manager, bibliotecă pentru controlul accesului la sistemul de afișare care suportă 2D și 3D. Aceste biblioteci nu sunt expuse prin API, reprezentând detalii de implementare Android.
- **Motorul Android** rulează serviciile de platformă precum și aplicațiile care le utilizează, fiind reprezentat de:
- **ART (Android Runtime)** este mașina virtuală Java care a fost implementată începând cu versiunea 5.0, folosind un tip de compilare AOH (Ahead of Time), în care bytecode-ul este transpus în cod mașină la momentul instalării, astfel încât acesta este executat direct de mediul dispozitivului mobil; compatibilitatea cu versiuni anterioare (care folosesc mașina virtuală Dalvik, ce se bazează pe un compilator JIT - Just in Time) este asigurată prin transformarea pachetelor în format .dex (Dalvik Executable) la momentul compilării, urmând ca translatarea în format .oat să se realizeze la momentul instalării; fiecare aplicație Android rulează în procesul propriu, într-o instanță a mașinii virtuale ART, izolând astfel codul și datele sale prin intermediul unor permisiuni, care se aplică inclusiv la comunicația prin intermediul interfețelor de comunicare oferite de sistemul de operare Android;
- **Zygote** este procesul care gestionează toate aplicațiile, fiind lansat în execuție odată cu sistemul de operare:
- inițial, creează o instanță a mașinii virtuale Java pentru sistemul de operare Android, în contextul căreia plasează serviciile de bază: gestiunea energiei, telefonie, furnizori de conținut, gestiunea pachetelor, serviciul de localizare, serviciul de notificări;
- atunci când este necesar să lanseze în execuție o anumită aplicație, se clonează, partajând astfel componentele sistemului de operare Android, astfel încât să se asigure performanța (timp de execuție) și eficiența (memorie folosită), de vreme ce fiecare aplicație trebuie rulată în propria sa instanță a mașinii virtuale Java;
- **Cadrul pentru Aplicații** expune diferitele funcționalități ale sistemului de operare Android către programatori, astfel încât aceștia să le poată utiliza în aplicațiile lor.
- La nivelul de **aplicații** se regăsesc atât produsele împreună cu care este livrat dispozitivul mobil (Browser, Calculator, Camera, Contacts, Clock, FM Radio, Launcher, Music Player, Phone, S Note, S Planner, Video Player, Voice Recorder), cât și produsele instalate de pe Play Store sau cele dezvoltate de programatori.
==== Funcționalități Android ====
De vreme ce Android este un produs open-source, producătorii având posibilitatea de a-l modifica în mod gratuit, nu există configurații hardware sau software standard. Totuși, Android implementează următoarele funcționalități:
* **stocare** - folosește SQLite, o bază de date relațională ce utilizează resurse puține
* **conectivitate** - suportă GSM/CDMA, GPRS, EDGE, 3G, IDEN, EV-DO, UMTS, Bluetooth (inclusiv A2DP si AVRCP), WiFi, LTE, WiMAX
* **WiFi Direct** - tehnologie care permite aplicațiilor să se descopere și să se interconecteze peste o conexiune punct-la-punct având lățime de bandă mare
* **Android Beam** - o tehnologie bazată pe NFC (Near Field Communication) care permite utilizatorilor să partajeze conținut instant, prin apropierea dispozitivelor mobile respective
* **mesagerie** - atât SMS cât și MMS
* **navigare pe Internet** - bazat pe motorul open source pentru navigare WebKit impreună cu motorul JavaScript de la Chrome V8 suportând HTML5 și CSS3
* **multimedia** - suportă formatele H.263, H.264 (într-un container 3GP sau MP4), MPEG-4 SP, AMR, AMR-WB (într-un container 3GP), AAC, HE-AAC (într-un container MP4 sau 3GP), MP3, MIDI, Ogg Vorbis, WAV, JPEG, PNG, GIF si BMP
* **grafică** - 2D optimizată, 3D (OpenGL ES)
* **senzori** - accelerometru, cameră foto, busolă digitală (magnetometru), senzor de proximitate, GPS / AGPS
* **multi-touch** - suportă ecrane cu posibilitate de contact în mai multe puncte concomitent
* **multi-tasking** - permite rularea de aplicații cu mai multe fire de execuție
* **GCM (Google Cloud Messaging)** - serviciu ce permite dezvoltatorilor să trimită date de dimensiuni mici către utilizatori pe dispozitive Android, fără a avea nevoie de o soluție de sincronizare proprietară
* **multi-Language** - suport pentru text unidirecțional și bidirecțional
* **suport pentru aplicații Flash** (până în versiunea 4.3)
* **legătură la Internet** - suportă partajarea conexiunilor la Internet ca punct de distribuție cu fir / fără fir
==== Android vs. iPhone ====
Piața de telefoane inteligente este dominată de Android (care - potrivit estimărilor - își va menține supremația până în 2018), cu 82.8% (peste un miliard de dispozitive vândute) pe întreg anul 2015, în timp ce Apple deține doar 13.9%, la nivel mondial.
În 2015, numărul de aplicații disponibile pentru platforma Android le-a depășit pe cele destinată dispozitivelor Apple (1.6 milioane, comparativ cu 1.5 milioane). Și în privința numărului de descărcări Android se află în fața Apple cu aproximativ 25%. Totuși, politica de distribuție a aplicațiilor (faptul că aplicațiile iPhone pot fi instalate numai prin intermediul App Store, în timp ce Android pune la dispoziție mai multe posibilități - Play Store, Amazon App Store, prin conexiune USB de la calculator, prin email sau prin pagina Internet a organizației), la care se adaugă numărul mare de programe gratuite și posibilitatea de piratare mai ușoară se traduce prin încasările obținute, Apple generând un profit mult mai mare din aplicații decât Google (cifrele oficiale nu sunt disponibile încă). O altă explicație a acestei situații este dată și de potența financiară a posesorilor de produse Apple (valoarea unui iPhone fiind de aproximativ 600$) față de puterea de cumpărare a persoanelor ce dețin un telefon Android (al cărui preț mediu este de 200-300$), existând o corespondență directă cu disponibilitatea de a achiziționa aplicații. De asemenea, statisticile arată că utilizatorii Apple își folosesc mult mai intens dispozitivele pentru accesarea de conținut Internet decât cei cumpărătorii de produse echipate cu Android.
Aplicațiile destinate dispozitivelor mobile reprezintă un segment extrem de productiv al economiei, doar vânzările din AppStore depășind încasările obținute din producția de filme de la Holywood. Ca tematică, cele mai multe aplicații aparțin domeniului social (jocuri, fotografie, muzică, aplicații culinare, stil de viață), urmate de cele destinate gestionării unor segmente ale unor afaceri.
În privința limbajului de programare utilizat pentru dezvoltarea de aplicații mobile, iPhone folosește **Objective-C**, similar cu C++, care nu se bucură însă de o răspândire prea largă (cu excepția aplicațiilor pentru iPhone), în timp ce Android utilizează **Java** (limbajul de programare cel mai adoptat pe scară largă în cadrul corporațiilor) dar și **C/C++**, prin care se pot apela (cu o oarecare dificultate) aplicații native, prin suport JNI (numărul bibliotecilor disponibile în cazul C/C++ este mai redus decât în Java, însă viteza aplicațiilor este mai mare). Dezvoltarea aplicațiilor pentru iPhone se poate realiza numai folosind mașini Mac (echipate cu MacOS), în timp ce aplicațiile Android pot fi scrise în orice sistem de operare cu Java și Eclipse (atât PC-uri cât și Mac-uri echipate cu Windows, Linux sau MacOS). În această situație, se pune problema cotelor de piață ale sistemelor de operare în cadrul companiilor dezvoltatoare de software, care creează sau nu oportunități pentru dezvoltarea unui anumit tip de aplicații (la începutul lui 2016, sistemele de operare Windows dețineau 90,60% din piață, OS X 7,68%, sistemele de operare cu kernel Linux 1,71%, iar alte sisteme de operare 0,01%).
Așadar, dacă pentru utilizare personală nu se poate stabili un câștigător clar între Android și iPhone (deși produsul celor de la Apple pare să aibă un ușor avantaj printr-un număr mai mare de aplicații și prin loialitatea clienților), în cazul aplicațiilor dezvoltate de corporații situația este inversă, date fiind posibilitățile de instalare și limbajul de programare folosit.
==== Comunitatea programatorilor Android ====
Ajunsă deja la a cincea versiune, Android este o platformă care beneficiază de experiența a numeroși dezvoltatori ce poate fi exploatată:
* [[http://developer.android.com/training/index.html|Google Android Training]] conține o serie de tutoriale și exemple de clase grupate în funcție de diferite subiecte, utile pentru deprinderea cunoștințelor de bază pentru dezvoltarea aplicațiilor Android.
* [[http://www.stackoverflow.com/questions/tagged/android|Stack Overflow]] este un forum pentru programatori editat în mod colaborativ, conținând întrebări și răspunsuri la acestea (cele mai bune putând fi identificate cu ușurință prin voturile primite de la participanți). Este destul de probabil ca o întrebare să își găsească deja răspunsul pe acestă resursă.
* [[http://groups.google.com/group/android-discuss|Android Discuss]] este o listă de discuții monitorizată îndeaproape de echipa Android de la Google astfel încât reprezintă un loc unde pot fi clarificate numeroase nelămuriri putând fi însușite diferite sfaturi și trucuri.
===== Cerințe pentru dezvoltarea unei aplicații Android (obligatoriu) =====
Pentru dezvoltarea unei aplicații Android sunt necesare:
- [[tutoriale:java|kit-ul de dezvoltare pentru limbajul de programare Java]]
- [[tutoriale:sdk_android|SDK-ul de Android]], pentru care se descarcă definițiile corespunzătoare unuia sau mai multor niveluri de API
- un mediu integrat de dezvoltare (IDE)
- [[tutoriale:eclipse|Elipse Mars 1 (4.5.1)]], cu plugin-ul ADT (Android Developer Tools)
- [[tutoriale:android_studio|Android Studio]]
- un dispozitiv pe care să se ruleze aplicațiile
- un emulator
- [[tutoriale:genymotion|Genymotion]]
- [[tutoriale:android_virtual_device|Android Virtual Device]] (livrat împreună cu SDK-ul de Android)
- un telefon mobil cu sistemul de operare Android pentru care s-a dezvoltat aplicația\\ \\ Pentru a se putea rula o aplicație pe un dispozitiv mobil fizic, trebuie să se activeze posibilitatea de depanare prin USB, din //Settings// → //System// → //Developer Options//. Această opțiune trebuie activată, ca de altfel și opțiunea //Debugging// → //Android Debugging// (pe unele sisteme poate apărea ca //USB Debugging//).\\ \\ {{ :laboratoare:laborator01:android_debugging01.png?nolink&400 }}\\ \\ În situația în care opțiunea //Developer Options// nu este disponibilă, aceasta poate fi vizualizată prin intermediul modului //Developer//, obțiunut prin apăsarea de mai multe ori asupra opțiunii //Build Number// din secțiunea //Settings// → //System// → //About Phone//.\\ \\ {{ :laboratoare:laborator01:android_debugging02.png?nolink&400 }}
Dacă telefonul nu este recunoscut la conectarea prin USB, trebuie instalate niște reguli pentru udev, conform instrucțiunilor de pe [[http://unix.stackexchange.com/questions/119128/linux-mint-16-android-device-not-listed-with-lsusb|stackexchange]]:
student@eim2016:~$ sudo bash
student@eim2016:~# lsusb
După ce s-a identificat dispozitivul mobil (prin intermediul comenzii ''lsusb''), se precizează o regulă pentru acesta:
student@eim2016:~# gedit /etc/udev/rules.d/51-android.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="d002", MODE="0660", GROUP="plugdev", SYMLINK+="android%n"
Se reîncarcă dispozitivele conectate prin USB:
student@eim2016:~# /etc/init.d/udev restart
Mai multe informații sunt disponibile și la [[http://blog.janosgyerik.com/adding-udev-rules-for-usb-debugging-android-devices/]].
===== Sisteme de control a versiunilor =====
==== Ce este un sistem de control al versiunilor? ====
Un sistem de control al versiunilor (//eng.// VCS - Version Control System) este un mecanism prin intermediul căruia sunt gestionate fișiere / proiecte în dinamică (pe măsură ce sunt modificate), în scopul de a se putea realiza revenirea la o anumită stare în caz de eroare (restaurarea unei versiuni stabile) și pentru a permite colaborarea între mai multe echipe care lucrează concomitent la diferite funcționalități ale unui același proiect.
Deși în mod curent astfel de produse sunt folosite pentru dezvoltarea de aplicații (urmărindu-se o gestionare eficientă a codului sursă și a utilizatorilor care implementează anumite funcționalități sau corectează defecte), ele pot fi folosite și pentru alte tipuri de proiecte, ce implică lucrul cu fișiere binare, pentru care diferențele între diferite versiuni se realizează mai dificil.
==== Clasificarea sistemelor de control al versiunilor ====
În prezent, sunt folosite trei tipuri de sisteme de control a versiunilor, fiecare dintre acestea fiind adecvate unei anumite situații:
- **sisteme locale de control a versiunilor**, în cazul în care se dorește monitorizarea variantelor unui fișier exclusiv pe discul local; în baza de date, versiunile sunt reținute sub forma diferențelor (rezultatul comenzii ''diff'') dintre versiuni succesive, astfel că se poate reveni oricând la o stare anterioară (exemplu: rcs);
- **sisteme centralizate de control a versiunilor** implică stocarea diferențelor dintre versiuni într-o bază de date rezidentă pe un server dedicat, la care au acces toți utilizatorii implicați, astfel încât fiecare poate consulta versiunea curentă (exemple: CVS, Subversion, Perforce);
* avantaje: posibilitatea de colaborare între echipe care lucrează la același proiect, stabilirea de drepturi cu privire la fișierele ce pot fi încărcate pe server de fiecare utilizator în parte;
* dezavantaje: în cazul când serverul dedicat pe care găsește baza de date cu tot istoricul versiunilor se defectează, există riscul de a se pierde toate aceste informații (dacă nu există copii de siguranță), păstrându-se doar versiunile salvate pe mașinile utilizatorilor; mai mult, într-o astfel de situație utilizatorii se află în incapacitatea de a mai transmite propriile modificări și de a consulta modificările celorlalți;
- **sisteme distribuite de control a versiunilor** în care consultarea stării actuale a unui fișier presupune și descărcarea, pe discul local, a întregului istoric de modificări astfel încât acesta să poată fi reconstituit în situații precum defectarea serverului; de asemenea, acestea au capacitatea de a gestiona mai multe depozite aflate la distanță, chiar în cazul în care acestea conțin același proiect, permițând stabilirea unor anumite fluxuri de transmitere a informației (exemple: Git, Mercurial, Bazaar, Darcs);
===== GIT =====
==== Istoric ====
Apariția Git în 2005 este strâns legată de dezvoltarea kernelului pentru Linux, proiect open-source la care lucra o comunitate destul de numeroasă de programatori. Dacă anterior actualizările erau distribuite sub forma unor arhive ce conțineau modificările (1991-2002), respectiv prin intermediul unui sistem distribuit de control al versiunilor denumit BitKeeper (2002-2005), pe măsură ce proiectul a devenit mai complex și din ce în ce mai multe persoane și-au exprimat disponibilitatea de a contribui la dezvoltarea acestuia, s-a pus problema conceperii unui produs care să satisfacă cerințele legate de viteză, arhitectură scalabilă, suport pentru dezvoltare non-liniară (numeroase ramificații la care se lucrează concomitent), distribuire totală, capacitate de a gestiona proiecte de dimensiuni mari.
==== Caracteristici (obligatoriu) ====
Git se diferențiază de alte sisteme de control al versiunilor prin câteva caracteristici:
- actualizările aduse fișierelor din cadrul proiectului nu se rețin sub forma unui set de diferențe între versiuni succesive, ci ca **instantanee** ale acestora la momentul respectiv (pentru eficiență, în situația în care nu există modificări ale unui fișier între versiuni succesive, se va reține o legătură către original); în acest fel, Git se aseamănă foarte mult cu un sistem de fișiere, peste care sunt implementate mai multe utilitare.\\ \\ Pentru fiecare operație de consemnare, Git stochează un obiect de tip ''commit'' ce conține o referință către părintele sau părinții săi (consemnarea / consemnările anterioare, din care a fost obținut, prin modificarea fișierelor) și o referință către instantaneul propriu-zis. De asemenea, în cadrul acestui obiect se rețin și informații despre dimensiunea totală și suma de control SHA-1, autor și contributor (nume și adresă de poștă electronică), data la care a fost realizată consemnarea, mesajul asociat.\\ \\ {{ :laboratoare:laborator01:git02.png?nolink&600x306 }} \\ Structura unui instantaneu este formată din:
* un obiect de tip ''tree'', o structură de date ce conține referințe spre fiecare resursă ce au fost modificată, aceasta fiind identificată prin denumire și sumă de control SHA-1; și în cazul unui astfel astfel de obiect se rețin dimensiunea totală și suma de control SHA-1;
* mai multe obiecte de tip ''blob'', corespunzătoare fiecărei resurse din cadrul consemnării respective; acestea sunt identificate prin denumire, dimensiune și suma de control SHA-1.\\
- **majoritatea operațiilor se realizează local**, astfel încât nu este necesară o conexiune la Internet pentru a putea consemnate anumite actualizări sau pentru a consulta istoricul modificărilor; acest fapt este posibil datorită stocării pe discul local a bazei de date care conține toate versiunile proiectului; se îmbunătățește astfel viteza, iar încărcarea/descărcarea informațiilor (de) pe server se realizează numai atunci când aceasta este posibilă;
- **integritatea** informațiilor este asigurată prin intermediul sumelor de control folosind algoritmul SHA-1; astfel, un fișier / director este reținut în baza de date printr-un șir de 40 de caractere hexazecimale calculat pe baza conținutului acestuia; în acest mod, este imposibil să nu se detecteze coruperea unui fișier / director, în situația în care aceasta se produce;
- majoritatea operațiilor implică în principiu adăugarea de informații în baza de date care conține toate versiunile proiectului, ceea ce face ca **probabilitatea de a pierde fișiere să fie extrem de redusă**, odată ce acestea au fost consemnate;
- **cele trei stări** în care se pot găsi datele monitorizate prin sistemul de control al versiunilor Git sunt:
* **consemnat** (//eng.// committed): modificările aduse au fost stocate în **directorul GIT** (//eng.// GIT directory/repository); în acesta sunt reținute toate metadatele și obiectele bazei de date locale conținând istoricul tuturor versiunilor, elemente preluate de fiecare dată când sunt descărcate actualizări ale proiectului;
* **modificat** (//eng.// modified): modificările aduse nu au fost stocate în baza de date locală; astfel de fișiere se regăsesc în **zona de lucru** (//eng.// working area), de pe discul local, în care a fost descărcată o anumită versiune a proiectului, spre a fi modificată;
* **în așteptare** (//eng.// staged): modificările aduse au fost consemnate spre a fi incluse într-un instantaneu ce va fi stocat în baza de date locală; acestea sunt reținute în **zona de așteptare** (//eng.// staging area), un fișier (denumit și index) din directorul GIT care conține toate modificările ce vor fi consemnate în următoarea versiune.\\ \\ {{ :laboratoare:laborator01:git01.png?nolink&600x297 }} \\ Utilizatorul poate alege să ignore anumite date generate (fișiere binare, executabile), care se regăsesc în zona de lucru, dar care nu vor fi monitorizate și nu vor fi consemnate în baza de date, chiar dacă se marchează întregul director din care fac parte în acest scop.
Un scenariu tipic de utilizare a sistemului de versiune Git implică:
- descărcarea unei versiuni din directorul GIT în zona de lucru;
- modificarea fișierelor corespunzătoare din zona de lucru;
- marcarea informațiilor actualizate din zona de lucru ca fiind în așteptare, în vederea consemnării lor;
- consemnarea propriu-zisă a datelor din zona de așteptare înapoi în directorul Git.
==== Instalare & Configurare (obligatoriu) ====
Instrucțiunile pentru instalarea și configurarea Git sunt disponibile [[:tutoriale:git|aici]].
Informații suplimentare cu privire la comenzile Git și sintaxa acestora pot fi obținute folosind paginile de manual:
student@eim2016:~$ git help
student@eim2016:~$ git --help
student@eim2016:~$ man git-
==== Moduri de Lucru (obligatoriu) ====
=== Local ===
În cazul în care se dorește monitorizarea unui proiect nou / existent prin sistemul de control al versiunilor Git, directorul în care se găsește acesta va trebui inițializat folosind comanda:
student@eim2016:~$ git init
Astfel, se creează un director ''.git'' în care vor fi plasate toate versiunile fișierelor care sunt monitorizate. Inițial, acesta este vid.
Indicarea fișierelor care sunt monitorizate se face prin intermediul comenzii ''git add '', fiind permisă și folosirea de expresii regulate folosind măști pentru a indica conținutul unui întreg director. Prin intermediul acestei comenzi, fișierele sunt transferate din directorul de lucru în zona de așteptare.
Consemnarea propriu-zisă a fișierelor se face rulând comanda ''%%git commit -m ""%%'', mesajul care o însoțește trebuind să fie relevant pentru modificările care au fost realizate. Se recomandă ca această operație să fie realizată cât mai des pentru actualizări de dimensiuni relativ reduse ale codului sursă. În acest moment, fișierele trec din zona de așteptare în directorul Git.
Pașii descriși vor fi repetați în situația în care aceleași fișiere care au fost consemnate într-o versiune anterioare sunt modificate din nou. Odată ce se realizează operația de consemnare, zona de așteptare devine goală și fișierele modificate nu vor fi prelate în directorul Git chiar dacă sunt marcate ca fiind monitorizate.
=== La Distanță ===
În situația în care utilizatorul vrea să lucreze pe un proiect găzduit pe un server la distanță, poate descărca întregul conținut în zona de lucru, inclusiv istoricul complet al versiunilor anterioare (care poate fi ulterior reconstituit după această copie, în cazul coruperii informațiilor stocate pe serverul la distanță), prin intermediul comenzii:
git clone []
unde:
* ''URL'' - reprezintă adresa serverului la distanță care găzduiește proiectul, putând fi utilizate în acest sens mai multe protocoale pentru transferul de informație
* git
student@eim2016:~$ git clone git://github.com/eim2016/Laborator01.git
* https
student@eim2016:~$ git clone https://github.com/eim2016/Laborator01
* ssh
student@eim2016:~$ git clone git@github.com:eim2016/Laborator01.git
* ''local_directory'' (opțional) - denumirea directorului local în care va fi stocată versiunea curentă a proiectului (precum și istoricul din directorul Git), în cazul în care se dorește schimbarea acestuia
Fișierele astfel descărcate, aflate atât în zona de lucru cât și în directorul Git pot fi modificate în funcție de necesități și transferate, succesiv, în zona de așteptare (prin ''git add'') și în baza de date locală (prin ''git commit -m'').
Dacă este necesar ca fișierele modificate să fie încărcate pe serverul de unde au fost preluate, trebuie ca mai întâi să se actualizeze modificările care se vor fi produs pe acesta între timp (folosind comanda ''%%git pull --rebase%%'') - rezolvând eventualele conflicte - și apoi să se transfere efectiv prin intermediul comenzii ''git push origin master''.
==== Operații Git (obligatoriu) ====
=== Determinarea stării fișierelor din zona de lucru ===
Comanda **''git status''** furnizează informații cu privire la starea fișierelor aflate în zona de lucru, fie că este vorba de resurse deja monitorizate (care se găsesc în directorul Git) care au fost modificate între timp, fie că este vorba despre date care au fost adăugate (și care nu au fost marcate în mod explicit pentru a fi ignorate). De asemenea, comanda indică și ramificația (//eng.// branch) pe care se găsește utilizatorul în mod curent.
O astfel de comandă poate întoarce mai multe rezultate:
* toate fișierele din directorul de lucru se regăsesc întocmai și în directorul Git (nu au fost realizate modificări
student@eim2016:~$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
* există date în zona de lucru care nu sunt monitorizate (nu au făcut parte dintr-un instantaneu anterior), care vor fi consemnate numai în situația în care se specifică acest lucru în mod explicit; acest mecanism urmărește ca fișierele generate să nu fie incluse în mod eronat în directorul Git
student@eim2016:~$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add ..." to include in what will be committed)
MyFirstAndroidApplication/
nothing added to commit but untracked files present (use "git add" to track)
Monitorizarea acestor date se face prin intermediul comenzii **''git add ''**, care suportă specificarea de expresii regulate desemnând măști pentru indicarea mai multor fișiere/directoare.
* există informații în zona de așteptare care vor fi incluse în următorul instantaneu în momentul în care se va realiza consemnarea (trecute în secțiunea ''Changes to be committed''); eventualele fișiere care au existat în instantanee anterioare și au fost modificate în directorul de lucru nu vor fi marcate ca făcând parte din zona de așteptare (trecute în secțiunea ''Changes not staged for commit'') dacă versiunile respective nu vor fi incluse în mod explicit prin comanda **''git add ''**
student@eim2016:~$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD ..." to unstage)
new file: MyFirstAndroidApplication/.classpath
new file: MyFirstAndroidApplication/.project
new file: MyFirstAndroidApplication/.settings/org.eclipse.jdt.core.prefs
new file: MyFirstAndroidApplication/AndroidManifest.xml
new file: MyFirstAndroidApplication/ic_launcher-web.png
new file: MyFirstAndroidApplication/libs/android-support-v4.jar
new file: MyFirstAndroidApplication/proguard-project.txt
new file: MyFirstAndroidApplication/project.properties
new file: MyFirstAndroidApplication/res/drawable-hdpi/ic_launcher.png
new file: MyFirstAndroidApplication/res/drawable-mdpi/ic_launcher.png
new file: MyFirstAndroidApplication/res/drawable-xhdpi/ic_launcher.png
new file: MyFirstAndroidApplication/res/drawable-xxhdpi/ic_launcher.png
new file: MyFirstAndroidApplication/res/layout/activity_main.xml
new file: MyFirstAndroidApplication/res/menu/main.xml
new file: MyFirstAndroidApplication/res/values-v11/styles.xml
new file: MyFirstAndroidApplication/res/values-v14/styles.xml
new file: MyFirstAndroidApplication/res/values-w820dp/dimens.xml
new file: MyFirstAndroidApplication/res/values/dimens.xml
new file: MyFirstAndroidApplication/res/values/strings.xml
new file: MyFirstAndroidApplication/res/values/styles.xml
new file: MyFirstAndroidApplication/src/ro/pub/cs/systems/eim/lab01/MainActivity.java
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: README.md
Fișierele care nu au existat într-un instataneu anterior sunt marcate prin ''new file'', iar cele care au fost modificate față de versiunile precedente sunt marcate prin ''modified''.
Un același fișier se poate găsi simultan în secțiunile ''Changes to be committed'', respectiv ''Changes not staged for commit'' în situația în care au mai fost realizate modificări asupra acestuia după rularea comenzii ''git add ''.
=== Transferul fișierelor din zona de lucru în zona de așteptare ===
Prin intermediul comenzii **''git add ''** se specifică fișiere / directoare care vor fi transferate din zona de lucru în zona de așteptare, pentru a fi incluse în următorul instantaneu în momentul în care se va realiza consemnarea acestora.
La consemnare vor fi incluse fișierele / directoarele în starea în care acestea se aflau la momentul la care a fost emisă comanda ''git add''. Dacă ele sunt modificate după precizarea acestei comenzi, actualizările nu vor fi consemnate în directorul Git decât dacă se rulează din nou comanda ''git add''.Dacă argumentul este un director, conținutul acestuia va fi inclus în mod recursiv.
student@eim2016:~$ git add MyFirstAndroidApplication/*
În cazul în care un fișier este transferat din greșeală din zona de lucru în zona de așteptare, parcursul invers poate fi realizat prin intermediul comenzii **''git reset HEAD ''**.
Dacă se dorește eliminarea modificărilor realizate asupra unui fișier din zona de lucru, se poate folosi comanda **''%%git checkout -- %%''** (disponibilă începând cu versiunea 1.6.1). O astfel de operație este totuși periculoasă, în sensul că actualizările respective sunt pierdute fără posibilitatea de a mai putea fi recuperate (întrucât nu au fost consemnate niciodată în directorul Git).
Alte operații care pot fi realizate asupra fișierelor din zona de lucru / zona de așteptare sunt mutarea (redenumirea), respectiv ștergerea acestora.
Comanda **''git mv