Istoricul de comitere al lui Git este conceput pentru a fi imuabil (în cea mai mare parte) și pentru a urmări fiecare modificare a proiectului dvs., astfel încât să nu pierdeți niciodată munca. Cu toate acestea, uneori este necesar să rescrieți istoricul Git, astfel încât Git oferă câteva instrumente pentru editarea confirmărilor existente.
Adăugarea de modificări noi la angajamente
Cel mai frecvent caz de utilizare pentru acest lucru este atunci când faci un mesaj de confirmare și apoi, înainte de a trece la telecomandă, îți dai seama că ai încurcat și trebuie să faci o mică modificare. Bineînțeles, ați putea face o a doua comitere, dar asta nu este necesar și vă arată, de asemenea, tuturor colegilor dvs. greșeala voastră mută atunci când în cele din urmă treceți la telecomandă.
Dacă pur și simplu adăugați modificări, puteți utiliza git commit --amend
. Aceasta modifică cea mai recentă validare și se îmbină cu modificările suplimentare pe care le-ați organizat.
Mai întâi, va trebui să vă schimbați etapele:
git add .
Și apoi modificați:
git commit --amend --no-edit
The --no-edit
flag va face ca comanda să nu modifice mesajul de confirmare. Dacă trebuie să clarificați noile modificări într-un mesaj nou, nu lăsați acest semnalizator și vi se va solicita noul mesaj de confirmare.
Sub capotă, comanda de modificare face un nou commit cu modificările suplimentare și apoi înlocuiește complet commit-ul sursă din istoricul Git. Vechiul commit este încă accesibil de la git reflog
(mai multe despre cele de mai jos), dar înainte, noua comitere este singura care există. Când treceți la o repoare la distanță, nu există nicio modalitate de a ști că commit-ul a fost modificat, este o schimbare pur locală.
Din această cauză, nu veți dori să modificați comitetele care au fost deja împinse, deoarece veți întâmpina multe probleme și va trebui să împingeți cu forța către telecomandă, ceea ce nu este bun pentru nimeni.
Schimbarea doar a mesajului Git Commit
Dacă nu trebuie să faceți modificări și doriți doar să remediați o greșeală de greșeală, puteți rula amend
fără niciun fel de modificări:
git commit --amend -m "an updated commit message"
Modificări nesoluționate de la angajamente
Comanda de modificare Git funcționează numai dacă sunteți strict adăugând schimbări. Când spunem „adăugat”, nu ne referim doar la noi linii de cod; modificarea unei linii de cod înseamnă și adăugarea de modificări. Eliminarea unei linii de cod sau a unui întreg fișier este, de asemenea, o modificare adăugată, chiar dacă elimină date din proiect atunci când se aplică această modificare.
Cu toate acestea, există și cazuri în care este posibil să doriți să eliminați modificările din comitere. De exemplu, spuneți că ați fugit:
git add . git commit
Și a adăugat fiecare schimbare în repo la modificările etapizate și a comis-o, înainte de a-ți da seama, „oh, prostii! Nu am vrut să comit acel fișier! ” În acest caz, ar trebui să trimiteți toate modificările înapoi la etapă, apoi să dezinstalați manual fișierele pe care nu doriți să le împingeți.
Soluția este de a efectua o resetare, eliminarea commit-ului și trimiterea modificărilor înapoi. Există câteva tipuri de resetări, dar toate implică preluarea de comitere din istoricul Git și trimiterea lor înapoi fie la înscenare, în directorul local, fie direct la coșul de gunoi.
În acest caz, o resetare soft este ceea ce doriți, care va trimite toate modificările înapoi la etapă. Puteți utiliza următoarea prescurtare pentru a reseta comitetul din spatele HEAD, altfel va trebui să preluați referința de la git reflog
:
git reset --soft HEAD~
Apoi, va trebui să eliminați fișierul pe care nu doriți să îl comiteți. Modul de a face acest lucru este, de asemenea, o resetare, în acest caz, o resetare mixtă pe un anumit fișier:
git reset --mixed filename
Acest lucru funcționează deoarece resetarea acestui fișier va elimina modificările din etapă și nu va fi confirmată atunci când refaceți validarea.
De asemenea, puteți efectua o resetare mixtă pe întreaga repo și git add
toate fișierele, cu excepția celui pe care nu îl doriți. Acest lucru este mai ușor de făcut dacă utilizați un client GUI Git.
Trebuie să anulați / să eliminați un angajament? Utilizați Revenirea
Revenirea unui commit este cel mai simplu mod de a elimina modificările. Practic, ia toate modificările din comiterea țintă și aplică opusul acestora. Dacă ați creat un fișier, acesta este eliminat. Dacă ați eliminat o linie de cod, codul respectiv va fi adăugat înapoi. Este modul aprobat de Git de a „elimina” sau „anula” un commit, deoarece originalul este încă păstrat în istoricul git.
Pentru a-l utiliza, rulați git log
pentru a vizualiza comitetele:
git log
Copiați ID-ul de referință, apoi reveniți la commit:
git revert 62ff517cc7c358eaf0bffdebbbe1b38dea92ba0f
Dacă tocmai te-ai blocat vim
, apăsați Q și poate rulați git config --global core.editor "nano"
.
Folosiți Rebasing pentru orice lucru mai complicat
Rebasing este în esență o metodă de mutare a comitetelor în depozitul dvs. În loc să fuzioneze, rebase rescrie istoricul git pentru a muta angajamentele individuale într-o locație nouă. Comitetele originale sunt lăsate suspendate și sunt eliminate din istoricul oficial Git, deși sunt încă acolo git reflog
.
Nu vom intra în detaliile exacte ale acestuia aici, dar dacă sunteți interesat de modul în care funcționează, puteți citi ghidul nostru de utilizare git rebase
.
Ce se întâmplă dacă vrei să te întorci?
Din fericire, Git ține o evidență a fiecărei modificări, chiar și atunci când încalci regulile și rescrii istoria.
De fiecare dată când sfatul sucursalei dvs. este actualizat din orice motiv, Git stochează starea conținutului directorului înainte de actualizare în Jurnal de referință, sau reflog
. Puteți vizualiza jurnalul cu git reflog
:
git reflog
Multe dintre acestea vor fi confirmări reale, dar includ și alte modificări. Dacă trebuie să reveniți la orice modificare individuală, puteți efectua o resetare hard:
git reset --hard fdb9db9
Aceasta oferă o plasă de siguranță plăcută, dar ar trebui să fiți avertizat că reflog urmărește doar modificările care au fost efectiv comise, nu doar etapizate, și urmărește doar mișcările vârfului de ramură. În plus, reflog păstrează intrările doar 90 de zile. După aceea, veți putea să resetați doar la confirmările reale.