https://eduspaces.ro/s/pro-git/capitol/s-3/
🌿 3. Git Branching
Ramurile ca pointeri ieftini, HEAD, fuziunea, conflictele, ramurile la distanță și rebase-ul.
Bază (13)
Ramificarea: te desparți de linia principală de dezvoltare și continui să lucrezi fără să o afectezi. În Git este extrem de ușoară — aproape instantanee — și este considerată „killer feature”-ul lui.
O ramură în Git este doar un pointer ușor și mobil către un commit; la fiecare commit pointerul ramurii curente avansează automat. Fiind un simplu fișier cu SHA-1-ul commit-ului (41 de octeți), se creează și se șterge foarte ieftin.
Creează o ramură nouă — un pointer nou la commit-ul curent — fără să treacă pe ea. Fără argumente listează ramurile ( marchează ramura curentă); -v, --merged, --no-merged, -d / -D (ștergere), --move (redenumire), -vv (urmărirea).
Trece pe o ramură existentă: mută HEAD și readuce fișierele din working directory la snapshot-ul acelei ramuri; git checkout -b <ramură> creează o ramură și trece pe ea.
Fuziunea în care commit-ul de integrat se află direct înaintea celui curent (poate fi atins urmând istoria lui), așa că Git doar mută pointerul înainte — nu există muncă divergentă de combinat.
Integrează în ramura curentă munca altei ramuri: dacă este posibil face fast-forward, altfel o fuziune cu trei căi încheiată cu un merge commit.
Unul dintre cele două moduri principale de integrare a modificărilor dintr-o ramură în alta (celălalt este rebase): ia capetele ramurilor și le combină, fie prin fast-forward, fie printr-o fuziune cu trei căi.
Fuziunea făcută când istoriile au divergent: Git folosește cele două snapshot-uri indicate de capetele ramurilor și strămoșul lor comun, creează un snapshot nou și un merge commit.
Referință locală, pe care nu o poți muta, la starea unei ramuri din depozitul la distanță; Git o actualizează la fiecare comunicare în rețea. Are forma <remote>/<branch>, de exemplu origin/master — un semn de carte pentru ultima conectare.
Ramură locală cu o relație directă cu o ramură la distanță (upstream); se creează automat când extragi o ramură dintr-o ramură remote-tracking (de exemplu cu --track), iar git pull știe de unde să aducă și ce să integreze.
Al doilea mod de integrare: iei modificările introduse de commit-urile unei ramuri și le reaplici, în ordine, peste altă ramură. Rezultatul final e același snapshot ca la merge, dar istoria devine liniară, mai curată.
Merge la strămoșul comun, salvează diff-urile introduse de fiecare commit al ramurii curente, resetează ramura la commit-ul țintă și aplică pe rând modificările; --onto reaplică pe altă bază, -i face rebase interactiv.
Regula rebase-ului: nu face rebase pe commit-uri care există în afara depozitului tău și pe care alții și-au putut baza munca — rebase-ul abandonează commit-uri și creează altele similare, dar diferite, iar colaboratorii trebuie să își reintegreze munca.
Aprofundare (12)
Istoria se bifurcă atunci când pe două ramuri s-au făcut commit-uri noi pornind de la același punct; modificările rămân izolate pe ramuri până când le integrezi.
Din Git 2.23, alternativă la git checkout pentru ramuri: git switch <ramură> trece pe o ramură existentă, -c (--create) creează și trece pe una nouă, git switch - revine la ramura anterioară.
Cel mai recent commit comun al două ramuri, folosit ca bază la fuziunea cu trei căi și la rebase; Git îl găsește automat datorită pointerilor spre părinți.
Markerii <<<<<<<, ======= și >>>>>>> adăugați de Git în fișierele în conflict: deasupra este versiunea din HEAD, dedesubt cea din ramura integrată. După rezolvare se șterg, iar git add marchează fișierul ca rezolvat.
Lansează un instrument vizual de fuziune care te ghidează prin conflicte; la final, dacă fuziunea a reușit, pune fișierul în staging ca rezolvat.
Moduri obișnuite de a folosi ramurile, posibile datorită ramificării ușoare: ramuri de lungă durată pentru niveluri de stabilitate și ramuri de topic pentru fiecare funcționalitate.
Ramură mereu deschisă, folosită pentru o etapă a ciclului de dezvoltare (de exemplu master doar cu cod stabil, develop sau next pentru testare, pu pentru actualizări propuse), în care se integrează regulat alte ramuri.
Ramură aflată într-un depozit la distanță; o ramură locală se publică explicit cu git push <remote> <branch> și se șterge de pe server cu git push <remote> --delete <branch>.
Referințe (pointeri) din depozitele la distanță — ramuri, etichete etc.; lista completă se obține cu git ls-remote <remote> sau git remote show <remote>.
Ramura urmărită de o ramură de urmărire; se setează cu git branch -u (--set-upstream-to) și se poate referi prescurtat cu @{upstream} sau @{u}; git branch -vv arată cu cât ești înainte sau în urmă.
Variantă a lui git pull care face rebase în loc de merge; poate fi făcută implicită cu git config --global pull.rebase true și ajută după ce cineva a forțat un push cu commit-uri rescrise.
Alegerea depinde de ce înseamnă istoria pentru echipă: o înregistrare a ce s-a întâmplat (merge) sau povestea coerentă a proiectului (rebase). Compromisul recomandat: rebase pe modificările locale înainte de push, niciodată pe ce ai publicat.
Detaliu (1)
Niciun concept nu se potrivește filtrului.