Sari la conținut
← Git & GitHub pentru developeri
Progres curs 0 / 7 lecții (0%)

Rebase pe scurt

Lectură estimată: 4 minute

Estimare pentru text, la un ritm de 180 de cuvinte pe minut. Timpul pentru analizarea codului, exerciții și proiecte se adaugă separat și depinde de ritmul tău.

Rebase are o reputație proastă nemeritată. E o unealtă simplă, cu o singură regulă de siguranță care, dacă e respectată, face istoricul proiectului mult mai ușor de citit.

Ce face rebase

Merge combină două istorii și lasă urma acestei combinări (merge commit). Rebase face altceva: ia commit-urile tale și le rejoacă peste alt punct de plecare, ca și cum ai fi început să lucrezi de acolo.

Înainte:
A---B---C---F   (main)
         \
          D---E (feature)

După git rebase main:
A---B---C---F---D'---E'   (feature)

Observă apostroful: D' și E' nu sunt aceleași commit-uri. Au alt hash, pentru că au alt părinte. Conținutul e același, identitatea nu. Din asta derivă toate regulile de mai jos.

Cum îl folosești

git switch feature/export-facturi
git fetch origin
git rebase origin/main

Dacă apar conflicte, le rezolvi la fel ca la merge, dar continui altfel:

# editezi fișierele, apoi
git add fisier-rezolvat.php
git rebase --continue

# sau, dacă vrei să renunți complet
git rebase --abort

La rebase, conflictele pot apărea de mai multe ori: o dată pentru fiecare commit rejucat. E normal și e motivul pentru care rebase pe un branch cu 30 de commit-uri e obositor.

Regula de aur

Nu faci rebase la commit-uri pe care le-au luat deja alții.

Dacă rescrii istoricul unui branch pe care lucrează și un coleg, la următorul lui pull Git nu mai recunoaște nimic, iar el ajunge cu commit-uri duplicate și o dimineață pierdută.

Practic: rebase pe branch-ul tău, care e doar al tău. Merge pentru ce e public (main, develop, branch-uri partajate).

Push după rebase

Dacă branch-ul era deja publicat, după rebase push-ul normal va fi respins — pe bună dreptate, pentru că istoricul e diferit. Soluția corectă:

git push --force-with-lease

Folosește --force-with-lease, nu --force. Diferența e importantă: --force-with-lease refuză să suprascrie dacă între timp altcineva a împins ceva ce tu nu ai văzut. --force șterge fără să întrebe.

Rebase interactiv: curățenie înainte de review

Asta e partea cu adevărat utilă zilnic. Ai un branch cu commit-uri de lucru:

* 9f1a2b3 fix typo
* 3c4d5e6 inca o incercare
* 7a8b9c0 wip
* 1d2e3f4 Adaugă export PDF pentru facturi

Nimeni nu vrea să vadă asta într-un pull request. Le combini:

git rebase -i HEAD~4

Se deschide editorul:

pick 1d2e3f4 Adaugă export PDF pentru facturi
pick 7a8b9c0 wip
pick 3c4d5e6 inca o incercare
pick 9f1a2b3 fix typo

Schimbi pick în squash (sau s) pe cele care trebuie topite în cel de deasupra:

pick 1d2e3f4 Adaugă export PDF pentru facturi
squash 7a8b9c0 wip
squash 3c4d5e6 inca o incercare
squash 9f1a2b3 fix typo

Salvezi, Git îți cere un mesaj final și rămâi cu un singur commit curat.

Alte comenzi disponibile în lista aceea: reword (schimbi doar mesajul), edit (te oprește ca să modifici commit-ul), drop (îl elimini), fixup (ca squash, dar aruncă mesajul).

Corectarea ultimului commit

Pentru cazul banal — ai uitat un fișier sau ai greșit mesajul — nu ai nevoie de rebase:

git add fisierul-uitat.php
git commit --amend --no-edit      # păstrează mesajul
git commit --amend -m "Mesaj corect"

Și --amend rescrie istoricul, deci aceeași regulă: doar pe commit-uri nepublicate.

Cum arată istoricul, în practică

Diferența dintre cele două abordări se vede cel mai bine pe un proiect real, după câteva săptămâni.

Cu merge la fiecare sincronizare, istoricul lui main arată așa:

*   Merge branch 'main' into feature/facturi
|\
| * Repară afișarea totalului
* | Adaugă export CSV
|/
*   Merge branch 'main' into feature/facturi
|\
| * Actualizează dependențele

Jumătate din linii nu spun nimic despre produs; sunt doar urme ale sincronizărilor. Cu rebase înainte de integrare, aceeași muncă arată așa:

* Adaugă export CSV pentru facturi
* Repară afișarea totalului
* Actualizează dependențele

Al doilea istoric poate fi citit de cineva care caută când s-a introdus un bug. Primul, nu prea.

Un rebase tipic, pas cu pas

git switch feature/facturi
git fetch origin
git rebase origin/main
Auto-merging app/Services/Factura.php
CONFLICT (content): Merge conflict in app/Services/Factura.php
error: could not apply 1d2e3f4... Adaugă export CSV

Deschizi fișierul, rezolvi exact ca la merge, apoi:

git add app/Services/Factura.php
git rebase --continue

Dacă apare din nou conflict, repeți. Când termini, Git îți spune Successfully rebased and updated refs/heads/feature/facturi.

Dacă la un pas constați că un commit a devenit inutil (modificarea lui e deja în main), îl poți sări:

git rebase --skip

Plasa de siguranță înainte de rebase

Dacă rebase-ul te sperie, fă-ți o etichetă temporară. Costă două secunde și îți garantează întoarcerea:

git branch backup/facturi-inainte-de-rebase
git rebase origin/main
# dacă iese prost:
git reset --hard backup/facturi-inainte-de-rebase

Aceeași siguranță o ai și din git reflog, dar un branch de rezervă e mai ușor de găsit când ești sub presiune.

Merge sau rebase? Răspunsul practic

  • Actualizezi branch-ul tău cu ce e nou în main → rebase, ca să nu umpli istoricul de merge commit-uri inutile.
  • Integrezi o funcționalitate terminată în main → merge (de obicei prin pull request).
  • Cureți commit-urile de lucru înainte de review → rebase interactiv cu squash.
  • Branch-ul e partajat cu altcineva → merge, niciodată rebase.

Exercițiu

  1. Creează un branch cu patru commit-uri, dintre care trei cu mesaje inutile („wip", „fix", „iar").
  2. Combină-le într-unul singur cu git rebase -i HEAD~4 și scrie un mesaj corect.
  3. Între timp, adaugă un commit pe main, apoi rulează git rebase main în branch și observă hash-urile noi.
  4. Explică-ți, cu propriile cuvinte, de ce push-ul ar fi respins dacă branch-ul era deja publicat.

Aplicație practică

Sarcina

Compară merge cu rebase într-un repository de laborator.

Rezolvare orientativă și verificare

Desenează istoricul înainte și după. Folosește rebase doar pe istoricul pentru care poți coordona rescrierea.

Greșeală de evitat

Nu rescrie istoricul partajat fără acordul echipei.

Documentație și surse

Verifică-ți înțelegerea

4 întrebări · îți trebuie 70% ca să promovezi și ca lecția să fie marcată parcursă.

Autentifică-te ca să rezolvi testul și să-ți salvezi progresul.

Folosim cookie-uri esențiale pentru funcționarea site-ului și, cu acordul tău, cookie-uri de analiză și publicitate. Partenerii noștri, inclusiv Google, pot folosi cookie-uri pentru a afișa reclame relevante. Detalii în Politica de cookie-uri.