Meniu

Curs fulger Git - SVN

Bine ati venit la sistemul de versionare Git! Aici vom invata sa folosim Git bazindu-ne pe cunostintele sistemului Subversion. Veti avea nevoie de ultima versiune Git instalata; De asemenea e posibil sa aveti nevoie de tutorialul din documentatia Git.

În tabelele mici care apar pe parcursul documentului in partea stinga sunt listate comenzile Git, iar in dreapta sunt comenzile corespunzatoare Subversion. Daca va grabiti, o trecere rapida cu vederea peste ele ar trebui sa va dea o idee despre folosirea de baza a Git.

Înainte de a rula vre-o comanda pentru prima data, se recomanda consultarea fugitiva macar a manualului pentru comanda respectiva. Multe comenzi au optiuni interesante si folositoare (pe care nu le vom detalia aici) si uneori sint note adaugatoare care s-ar putea sa va fie de folos. Pentru fiecare comanda se pot vedea instructiuni rapide folosind parametrul -h.

Lucruri care ar trebuie sa cunoasteti

Sunt citeva conceptii importante pe care e bine sa le cunoaste-ti cind incepeti sa lucrati cu Git. Daca totusi sunteti in graba, puteti sari peste sectiunea aceasta si sa va intoarceti la ea cind va simtiti derutat; s-ar putea sa prindeti firul folosind numai intuitia.

  • Repozitorii. Cu Subversion, pentru fiecare proiect exista un singur repozitoriu intr-un anumit loc central unde este toata istoria, de unde luati sursele si unde puneti odificarile. Git lucreaza altfel: fiecare copie a ramificarii proiectului (numita copie de lucru (working copy)) isi are repozitoriul lui in subdirectoriul .git in directorul proiectului. Deci puteti avea ramuri locale si externe (remote). De asemenea puteti avea un asa numit repositoriu singuratic care nu este atasat de o copie de lucru; care este de folos in special la publicarea repozitoriului. Vom ajunge la asta mai tirziu.

  • URL. În Subversion URL-ul identifica locul repozitoriului si calea inauntru repozitoriului, asa ca e bine sa organizati logic repozitoriului. De obicei se creaza directoarele trunk/, ramuri/ si tags/. În Git URL-ul este doar locatia repozitoriului, si mereu contine ramuri si tag-uri. Una din ramuri este implicita (deobicei numita master).

  • Reviziunile. Subversion identifica reviziunile cu id-uri din numere naturale crescatoare care sunt deobicei mici (dar ele pot ajunge deseori foarte repede la sute de mii in cazul proiectelor mari). Asa ceva nu este practicat in sistemul de versionare Git. Git identifica reviziunile cu id-uri SHA1, care sunt numere lungi pe 160 de biti scrise in cod hexazecimal. Poate fi inspaimintator la inceput, dar in practica nu este un mare obstacol - puteti face referinta la ultima revizie cu aliasul HEAD, este parinte al HEAD^ si este parinte al HEAD^^ = HEAD~2 (puteti continua adaugind ^), taie si lipeste (cut'n'paste) ajuta mult si puteti scrie doar citeva cifre de la inceput pentru ca sunt unice, Git v-a ghici restul. (Chiar puteti si lucruri mai avansate cu caracteristicile specificatorii de revizie, vedeti manualul pentru git-rev-parse pentru mai multe detalii.)

  • Commit-urile. Fiecare commit are un cimp author si unu committer, cu inregistrarile cine si cind a creat schimbarile si cine le-a comis (Git este creat pentru a lucra bine cu patch-uri venite prin mail - in acest caz, autorul si cel care incarca v-or fi diferiti). Git v-a incerca sa ghiceasca numele real si e-mail-ul, dar cu e-mail in special ar putea sa mearga gresit. Puteti verifica folosind git config -lsi sa le setati cu:

    git config --global user.name "Ion Gnulinux"
    git config --global user.email ion@gnulinux.ro
    
  • Comenzi. Comenzile Git sunt in forma git command. Puteti folosi si forma git-command pina la versiunea 1.6.

  • Culori. Git poate avea o listare colorata cu unele comenzi; unii urasc culorile altii le adora, implicit afisarea se faca fara culori. Pentru activarea culorilor, executati:

    git config --global color.diff auto
    git config --global color.status auto
    git config --global color.branch auto
    
  • Vizualizare. S-ar putea sa va placa sa priviti repozitoriul folosind gitk, qgit.

Comiterea

Pentru inceput, sa facem un repozitoriu Git pentru un proiect si sa vedem cum facem operatiunile de zi cu zi. Trecem in directorul care contine proiectul si initializam repozitoriul Git:

git init
git add .
git commit

svnadmin create repo
svn import file://repo

git init v-a initializa repozitoriul, git add . v-a adauga fisiere din directorul curent in repozitoriu si git commit v-a crea importul initial.

Acum directorul este versionat de Git. Puteti lista subdirectorul .git daca doriti. Faceti citeva schimbari aleatoare in proiect acum. Sa verificam ce am facut:

git diff

svn diff | less

Este una din cele mai puternice comenzi. Pentru a obtine un diff cu o versiune si o cale:

git diff rev cale

svn diff -rrev cale

Git include informatii in diff-uri despre adaugari, stergeri si schimbarea permisiunilor a fisierelor:

git apply

patch -p0

Aceasta v-a aplica patch-ul.

Exista un mod de reprezentare mai concisa a schimbarilor:

git status

svn status

Asta v-a arata sumarul concis al schimbarilor inclusiv lista fisierelor depsre care Git inca nu stie nimic. În plus, de asemnea va arata ramificarea curenta.

Cu timpul in directorul proiectului vor mai aparea fisiere neversionate. Daca o sa doriti sa le stergeti, puteti folosi comanda git clean, sau, daca doriti sa le lasati acolo, dar Git sa le ignore adaugatile in fisierul .gitignore (functioneaza la fel ca si svn:ignorein SVN).

Pentru a restaura un file din ultima versiune comisa:

git checkout cale

svn revert cale

Puteti restaura tot sau doar un anumit fisier.

Deci, ca si in SVN, trebuie sa spuneti lui Git cind adaugati, mutati sau stergeti fisiere:

git add fisier
git rm fisier
git mv fisier

svn add fisier
svn rm fisier
svn mv fisier

De asemenea puteti adauga/sterge recursiv directoare, etc.; Git este tare!

Deci, e timpul sa comitem modificarile noastre. O mare surpriza cu comanda:

git commit -a

svn commit

pentru a comite toate schimbarile sau, ca si in Subversion, puteti comite doar unele fisiere. Citeva cuvinte la mesajul de comitere: este obisnuit de a avea un sumar scurt al schimbarilor ca prima linie a mesajului, deoarece diferite unelte care listeaza commit-urile deseori arata numai prima linie a mesajului. Puteti specifica mesajul pentru commit folosind parametrul -m, Dvs puteti pune citeva argumente -m si ele vor crea paragrafe separate in mesajul commit-ului:

Daca nu puneti nici un parametru -m sau -e, la executarea comenzii git commit se va porni editorul dumneavoastra din variabila de mediu $EDITOR si veti putea scrie mesajul acolo, ca si la Subversion. În afara de asta, se afiseaza lista fisierilor pentru care urmeaza a fi comise.

Si ca bonus, daca puneti parametrul -v va fi afisat intregul patch care se incarca ca sa puteti revizui rapid.

Apropo, daca ati stricat ceva, cu Subversion nu prea aveti ce face, decit sa folositi niste subcomenzi svnadmin enigmatice. Git face mult mai bine - puteti corecta ultima comitere (reeditati descrierea si chiar fisierele din director) folosind git commit --amend, sau luati ultima incarcare folosind git reset HEAD^, asta nu v-a afecta directorul de lucru.

Explorarea

Acum ca am incarcat cite ceva, puteti vedea istoria schimbarilor:

git log
git blame fisier

svn log | less
svn blame fisier

Comanda log functioneaza similar cu cea din Subversion; iarasi, git log este foarte puternica, vedeti optiunile ei pentru a-i vedea posibilitatile.

Comanda blame este mai puternica deoarece poate detecta miscarea liniilor, chiar cu copii ale fisierilor si redenumirilor. Dar probabil ati vrea sa faceti altceva! Deobicei, cind folositi annotate cautati originea a unei bucati de cod, si asa numita unealta pickaxe al Git-ului este mult mai confortabila pentru acest lucru (git log -Sstring arata comiterile care adauga sau sterge careva fisiere care conrespund cu masca string).

Puteti vedea continutul unui fisier, al unul director sau a unui commit cu:

git show rev:calea/spre/fisier
git show rev:calea/spre/directoriu
git show rev

svn cat url
svn list url
svn log -rrev url
svn diff -crev url

Marcarea cu tag-uri si ramificarea

Subversion marcheaza unele checkpoint-uri in istorie printre copii, copie este plasata deobicei in directoriul numit tags. Tag-urile in Git au cu mult mai mult potential: ele pot avea o descriere arbitrara atasata (prima linie e speciala ca si in cazul commit-ului), unii defapt pastreaza toate anunturile in tag-ul descriptions. Identitatea persoanei care a etichetat este pastrata(iarasi folosind aceleasi reguli ca si identitatea commiter-ului). De obicei etichetati commit-urile dar, daca doriti, puteti sa etichetati fisiere (sau directoarele). si etichetarea poate fi semnata cryptographic PGP pentru a verifica identitatea (dupa natura Git-ului, aceasta semnatura deasemenea confirma validitatea reviziei asociate, istoria ei si ramificarea). Deci:

git tag -a nume_eticheta

svn copy http://example.com/svn/trunk http://example.com/svn/tags/nume_eticheta

Pentru listarea etichetelor si afisarea messajelor lor:

git tag -l
git show eticheta

svn list http://example.com/svn/tags/
svn log --limit 1 http://example.com/svn/tags/tag

Ca si Subversion, Git poate face ramificari (surprize surprize!). În Subversion, de fapt copiati proiectul intr-un subdirector. În Git, ii spuneti... aaaa ...sa creeze o ramificare.

git branch ramura
git checkout ramura

svn copy http://example.com/svn/trunk http://example.com/svn/branches/ramurpbranch
svn switch http://example.com/svn/branches/ramura

Prima comanda creeaza o ramificare, a doua comanda trece directorul de lucru intr-o alta ramificare. Puteti adauga inca un argument la git branch pentru a aduce directorul de lucru la o versiune diferita de cea mai recenta.

Puteti lista ramificarile convinabil folosind comanda git branch fara argumente. Ramura curenta e marcata cu "*".

git branch

svn list http://example.com/svn/branches/

Pentru a trece proiectul la o versiune mai veche, folositi:

git checkout rev
git checkout prevbranch

svn update -r rev
svn update

Sau puteti crea o ramificare temporara. În Git puteti commite in versiuni mai vechi si sa o folositi ca o alta ramificare.

Fuzionarea

Git suporta fuzionarea intre ramificari mai bine decit Subversion - istoria la ambele ramificari se pastreaza in decursul a mai multe fizionari astfel repetarea fuzionilor se face foarte simplu. Asigurati-va ca va aflati in una din ramurile pe care doriti sa le fuzionati si o puteti fuziona cu alta specificind-o ca parametru:

git merge ramura

(presupunind ca ramura a fost creata in versiunea 20 si sinteti in copia de lucru a trunk)
svn merge -r 20:HEAD http://example.com/svn/branches/branch

Daca schimbarile au fost facute numai pe una din ramificari de la ultima fuzionare, ele pur si simplu v-or fi copiate pe cealalta (asa numita fast-forward merge). Daca au fost facute schimbari pe ambele ramificari, ele sunt fuzionate inteligent (asa numit three-way merge): daca oarecare fuzionarea e cu conflict, git merge le va reporta si va va lasa sa le corectati, fuzionind restul fisierelor; puteti executa git commit cind rezolvati conflictele. Daca nu exista nici un conflict, o comiterea e facuta automat cu un mesaj de log convenabil (sau puteti sa faceti git merge --no-commit ramura pentru a revedea rezultatul fuzionarii si dupa aceea sa faceti commit manual).

În afara de fuzionare, uneori e nevoie doar sa scoateti un anumit commit dintr-o alta ramificare. Pentru a aplica schimbarile in versiunea rev si a le comite intr-o ramificare curenta folositi:

git cherry-pick rev

svn merge -c rev url

Lucrul cu repozitoriile la distanta

Pina aici, noi am neglijat faptul ca Git este un sistem distribuit de versionare. Sa incercam sa accesam repozitoriile la distanta.

Daca lucrati la proiectul altcuiva de obicei clonati repozitoriul in loc sa incepeti unul desinestatator. Noi deja am mentionat la inceputul acestui document:

git clone url

svn checkout url

Acum aveti ramificarea implicita a repozitoriului, de obicei numita master, dar mai aveti si alte ramificari la distanta, si etichete. În configuratia implicita a proiectului clonat, ramificarea implicita locala urmareste ramificarea externa origin, care reprezinta ramificarea implicita in repozitoriul la distanta.

Va intrebati ce inseamna repozitoriu la distanta? Pai, pina acum am lucrat numai cu repozitorii locale. Repozitoriile la distanta sint o imagine-oglinda a ramurilor din repozitoriile la distanta si niciodata nu veti face schimbari direct in ele. Nu aveti niciodata treaba cu ramificarile la distanta. Daca vreti sa treceti in una din ele, trebuie sa creati o ramificare locala corespunzatoare care va versiona ramificarea externa:

git checkout --track -b ramura origin/ramura

svn switch url

Daca DVS doriti permanent sa urmariti ramuri externe (si sa uitati de --track) puteti seta:

git config --global branch.autosetupmerge auto

Puteti adauga mai multe ramificari la distanta la un repozitoriu clonat, la fel ca si unul nou initializat, folosind git remote add remote url. Comanda git remote listeaza toate repozitoriile la distanta si git remote show remote arata ramificarile intr-un repozitoriu la distanta.

Acum, cum luati careva schimbari dintr-un repozitoriu la distanta? le descarcati: git fetch. La acest moment ele sint in repozitoriul local si le puteti examina folosind git log origin (git log HEAD..origin pentru a vedea schimbarile care nu le aveti in ramificarea locala), faceti un diff, si evident, fuzionati-le - doar rulati git merge origin. Nota!!! Daca nu specificati o ramificare pentru descarcare, implicit se va considera aceeasi ramificare de la distanta.

Deoarece se intimpla foarte des sa descarcati si fuzionati ramificarea externa, exista o comanda pentru automatizarea acestui lucru:

git pull

svn update

Publicare muncii

Repozitoriul local poate fi folosit de altii pentru a scoate (pull) schimbari, dar normal ati vrea sa aveti un repozitoriu privat si unul public. Cel public este cel in care comiteti si din care ceilalti descarca. Rulam git push remote pentru a publica ramificarile locale in ramificarile la distanta corespunzatoare - aceasta lucreaza de obicei doar prin SSH (sau HTTP dar cu o setare speciala a webserverului). Este recomandat ca sa setati o cheie SSH si un mecanism SSH pentru a nu fi nevoit sa introduceti parola de fiecare data.

Un lucru important este ca de obicei ar trebui sa publicati numai ramificari indepartate care nu sint la moment luate pe de alta parte (din acelasi motiv niciodata nu treceti repozitoriul local la o ramificare de la distanta)! Altfel copia de lucru a ramificarii de la distanta va fi neactualizata si va se va crea o situatie confuza. Cel mai bine pentru a evita aceasta este de a publica numai repozitoriile la distanta care nu contin copii de lucru - asa numitele repozitorii singuratice care este deobicei folosit pentru acces public sau un loc de intilnire pentru programatori - doar pentru a distribui istoria, pentru care descarcarea unei copii de lucru ar fi inutila. Puteti crea un asemenea repozitoriu.

Git poate lucra cu acelasi flux ca si Subversion, cu un grup de programatori folosind un singur schimb de repozitorii al lucrului lor. Unica schimbare este ca schimbarile lor nu sint aplicate automat dar trebuie sa fie comise (oricum, puteti seta un hook post-commit care sa publice de fiecare data cind rulati commit; aceasta pierde flexibilitatea de a corecta commit-urile eronate). Developerii trebuie sa aiba o inregistrare in .htaccess (pentru HTTP DAV) sau un cont UNIX (pentru SSH). Puteti sa-i limitati contul shell numai pentru operatiuni Git folosind git-shell.

De asemenea puteti schimba patch-uri prin e-mail. Git are un suport foarte bun pentru patch-urile primite prin e-mail. Le puteti aplica transmitind e-mail-urile cu patch-uri spre git am. Daca vreti sa trimiteti patch-uri folositi git format-patch si posibil git send-email. Pentru a mentine un set de patch-uri e mai bine sa folositi programul StGIT

John Doe

Articole publicate de la contributori ce nu detin un cont pe gnulinux.ro. Continutul este verificat sumar, iar raspunderea apartine contributorilor.
  • | 340 articole

Nici un comentariu inca. Fii primul!
  • powered by Verysign