Cum (și de ce!) Să vă păstrați curat istoricul de comitere Git

Comitetele sunt una dintre părțile cheie ale unui depozit Git, și mai mult, mesajul de confirmare este un jurnal de viață pentru depozit. Pe măsură ce proiectul / depozitul evoluează în timp (se adaugă noi caracteristici, se remediază erorile, arhitectura se refactorizează), mesajele de confirmare sunt locul unde se poate vedea ce s-a schimbat și cum. Deci, este important ca aceste mesaje să reflecte schimbarea de bază într-o manieră scurtă și precisă.

De ce este important un istoric de comitere Git semnificativ

Ce face Git commit? Mesaje de comitere Git sunt amprentele digitale pe care le lăsați pe codul pe care îl atingeți. Orice cod pe care îl asumați astăzi, peste un an, când vă uitați la aceeași schimbare; ați fi recunoscător pentru un mesaj de confirmare clar și semnificativ pe care l-ați scris și va fi, de asemenea, faceți viața colegilor voștri mai ușori. Când comitetele sunt izolate în funcție de context, un bug introdus de un anumit commit devine mai rapid de găsit și cu atât este mai ușor să reveniți la commit care a cauzat bug-ul în primul rând.

În timp ce lucrăm la un proiect mare, avem de-a face cu multe piese în mișcare care sunt actualizate, adăugate sau eliminate. Asigurarea menținerii mesajelor de confirmare în astfel de cazuri ar putea fi dificilă, mai ales atunci când dezvoltarea se întinde pe parcursul zilei, săptămâni, sau chiar luni. Deci, pentru a simplifica efortul de menținere concisă Istoricul validărilor, acest articol va folosi unele dintre situațiile obișnuite cu care s-ar putea confrunta un dezvoltator în timp ce lucrează la un depozit Git.

  • Situația 1: trebuie să schimb cea mai recentă validare
  • Situația 2: Trebuie să schimb o confirmare specifică
  • Situația 3: Trebuie să adaug, să elimine sau să combină validări
  • Situația 4: Istoricul confirmărilor mele nu face sens, am nevoie de un nou început!

Dar înainte de a ne arunca cu capul, să trecem rapid la modul în care arată un flux de lucru de dezvoltare tipic într-o ipotetică aplicație Ruby.

Notă: Acest articol presupune că sunteți la curent cu elementele de bază ale Git, cum funcționează ramurile, cum să adăugați modificări necompromise ale unei ramuri la etapă și cum să comiteți modificările. Dacă nu sunteți sigur de aceste fluxuri, documentația noastră este un punct de plecare excelent.

O zi în viață

Aici lucrăm la un mic proiect Ruby on Rails unde trebuie să adăugați o vizualizare de navigare pe pagina de pornire și care implică actualizarea și adăugarea mai multor fișiere. Urmează o defalcare pas cu pas a întregului flux:

  • Începeți să lucrați la o caracteristică cu actualizarea unui fișier ; să o numim application_controller.rb
  • Această caracteristică necesită actualizarea unei vizualizări: index.html.haml
  • Ați adăugat un parțial care este utilizat în pagina index: _navigation.html.haml
  • Stilurile pentru pagină trebuie, de asemenea, actualizate pentru a reflecta parțialul pe care l-am adăugat: styles.css.scss
  • Funcția este acum gata cu modificările dorite, timpul pentru actualizarea testelor; fișierele care trebuie actualizate sunt după cum urmează:
    • application_controller_spec.rb
    • navigation_spec.rb
  • Testele sunt actualizate și trec așa cum era de așteptat, acum este timpul să comitem modificările!

Deoarece toate fișierele aparțin diferitelor teritorii ale arhitecturii, noi angajăm modificările izolate unele de altele pentru a se asigura că fiecare comitet reprezintă un anumit context și se face într-o anumită ordine. De obicei prefer backend – > ordinea frontendului în care se efectuează mai întâi cea mai mare parte a modificărilor centrate pe backend, urmată de stratul de mijloc și apoi de modificările centrate pe frontend în lista de comenzi Git.

Acum că avem modificările efectuate, creăm o solicitare de îmbinare cu sucursala. Odată ce ați deschis cererea de îmbinare, aceasta este de obicei revizuită de colegul dvs. înainte ca modificările să fie îmbinate în ramura repo „s master. Acum, să aflăm cu ce situații diferite putem ajunge în timpul revizuirii codului.

Situația 1: trebuie să schimb cea mai recentă confirmare

Imaginați-vă un caz în care examinatorul a analizat styles.css.scss și a sugerat o schimbare. Într-un astfel de caz, este foarte simplu să efectuați modificările, deoarece modificările foii de stil fac parte din ultima comitere din filiala dvs. Iată cum putem gestiona acest lucru;

  • Faceți direct modificările necesare în styles.css.scss în filiala dvs.
  • Odată ați terminat cu modificările, adăugați aceste modificări la etapă; rulați git add styles.css.scss.
  • Odată ce modificările sunt organizate, trebuie să adăugăm aceste modificări la ultimul nostru commit; rulați git commit --amend.
    • Defalcare comandă: aici, solicităm comanda git commit pentru a modifica orice modificări sunt prezente în treceți la cea mai recentă validare.
  • Aceasta vă va deschide ultima validare în editorul de text definit Git care are mesajul de validare Adăugați stiluri pentru navigare.
  • Deoarece am actualizat doar declarația CSS, nu este necesar să modificăm mesajul de confirmare.În acest moment, puteți doar să salvați și să ieșiți din editorul de text pe care Git l-a deschis pentru dvs., iar modificările dvs. vor fi reflectate în commit.

Deoarece ați modificat un commit existent, aceste modificări sunt necesare pentru a fi împins forțat la repo la distanță folosind git push --force-with-lease <remote_name> <branch_name>. Această comandă va suprascrie commit Add styles for navigation pe repo la distanță cu commit actualizat pe care tocmai l-am făcut în repo-ul nostru local.

Un lucru de reținut în timp ce forțați împingerea ramurilor este că, dacă lucrați la aceeași ramură cu mai multe persoane, împingerea forțată poate cauza probleme pentru ceilalți utilizatori atunci când încearcă să împingă în mod normal modificările lor pe o ramură la distanță care are forța de comitere nouă împinsă. Prin urmare, utilizați această caracteristică cu înțelepciune. Puteți afla mai multe despre opțiunile de împingere a forței Git aici.

Situația 2: Trebuie să schimb un commit specific

În situația anterioară, remedierea a fost destul de simplă, deoarece a trebuit să o modificăm doar ultimul nostru commit Git, dar imaginați-vă dacă recenzorul a sugerat să schimbe ceva în _navigation.html.haml. În acest caz, este al doilea commit din partea de sus, așa că schimbarea acestuia nu va fi la fel de directă ca în prima situație. Să vedem cum putem gestiona acest lucru:

Ori de câte ori un commit este realizat într-o ramură, este identificat printr-un șir de hash SHA1 unic. Gândiți-vă la acesta ca la un ID unic care separă o comitere de alta. Puteți vizualiza toate validările, împreună cu hash-urile SHA1 ale acestora într-o ramură executând git log. Cu aceasta, veți vedea o ieșire care arată oarecum după cum urmează, în care cele mai recente confirmări sunt în partea de sus;

Aici intră în joc comanda git rebase. Ori de câte ori dorim să edităm un anumit commit cu git rebase, trebuie mai întâi să rebasăm ramura noastră mutând înapoi HEAD până la punctul chiar înainte de commit-ul pe care dorim să îl edităm. În cazul nostru, trebuie să schimbăm commit-ul care citește Page Navigation View.

Aici, observați hash-ul de commit care este chiar înainte de commit-ul pe care dorim să-l modificăm; copiați hashul și efectuați pașii următori:

  • Reinstalați ramura pentru a trece la commit înainte de commitul țintă; rulați git rebase -i 8d74af102941aa0b51e1a35b8ad731284e4b5a20
    • Defalcare comandă: aici executăm comanda rebase Git cu modul interactiv cu hash SHA1 furnizat ca commit to rebase to.
  • Aceasta va rula comanda rebase pentru Git în modul interactiv și vă va deschide editorul de text afișând toate comitetele dvs. care au venit după comiterea la care ați rebasat . Va arăta oarecum așa:

Observați cum fiecare comitere are un cuvânt pick în fața acestuia și în conținutul de mai jos, există toate cuvintele cheie posibile pe care le putem folosi. Din moment ce dorim să edităm un commit, trebuie să schimbăm pick 4155df1cdc7 Page Navigation View în edit 4155df1cdc7 Page Navigation View. Salvați modificările și ieșiți din editor.

Acum filiala dvs. este rebazată până la momentul exact înainte de comiterea pe care ați făcut-o, care a inclus _navigation.html.haml. Deschideți fișierul și efectuați modificările dorite conform feedbackului recenziei. După ce ați terminat modificările, puneți-le în scenă executând git add _navigation.html.haml.

Deoarece am organizat modificările, este timpul să mutați ramura HEAD înapoi la commit pe care l-am avut inițial (incluzând, de asemenea, noile modificări pe care le-am adăugat), rulați git rebase --continue, acesta vă va deschide editorul implicit în terminal și vă va arăta mesajul de commit pe care l-am editat în timpul rebase-ului; Page Navigation View. Puteți schimba acest mesaj dacă doriți, dar l-am lăsa așa cum este deocamdată, așa că salvați și ieșiți din editor. În acest moment, Git va relua toate comitetele care a urmat după commit-ul pe care tocmai l-ați editat și acum branch HEAD revine la commit-ul de top pe care l-am avut inițial și include, de asemenea, noile modificări pe care le-ați făcut la unul dintre commit-uri.

Deoarece am modificat din nou un commit care „este deja prezent în repo la distanță, trebuie să împingem din nou această ramură folosind git push --force-with-lease <remote_name> <branch_name>.

Situația 3 : Trebuie să adaug, să elimin sau să combin validări

O situație obișnuită este atunci când ați făcut mai multe angajamente doar pentru a remedia ceva comis anterior. Acum, să le reducem cât putem, combinându-le cu comitetele originale.

Tot ce trebuie să faceți este să porniți rebase-ul interactiv așa cum ați face în celelalte scenarii.

Acum imaginați-vă că doriți să combinați toate acele remedieri în c22a3fa0c5c Render navigation partial. Trebuie doar să:

  1. Mutați corecțiile în sus, astfel încât să fie chiar sub comiterea pe care doriți să o păstrați în final.
  2. Schimbați pick la squash sau fixup pentru fiecare dintre remedieri.

Notă: squash păstrează mesajele de confirmare în descriere. fixup va uita mesajele de confirmare ale corecțiilor și va păstra originalul.

Veți termina cu așa ceva:

Salvați modificările, ieșiți din editor și ai terminat! Acesta este istoricul rezultat:

La fel ca înainte, tot ce trebuie să faceți acum este git push --force-with-lease <remote_name> <branch_name> și modificările sunt sus.

Dacă doriți să eliminați complet commitul din ramură, în loc de squash sau fixup, trebuie doar să scrieți drop sau pur și simplu să ștergeți acea linie.

Evitați conflictele

Pentru a evita conflictele, asigurați-vă că vă angajează „Mutați în sus cronologia nu atingeți aceleași fișiere atinse de comitetele rămase după ele.

Pro-tip : Reparări rapide

Dacă știți exact ce comitere doriți să reparați, atunci când comiteți nu trebuie să pierdeți ciclurile cerebrale gândindu-vă la nume temporare bune pentru „Fix 1”, „Fix 2”, …, „Remediați 42”.

Pasul 1: Faceți cunoștință cu --fixup

După ce ați organizat modificările, rezolvând orice ar trebui să fie reparat, doar Git comite toate modificările astfel:

(Rețineți că acesta este hash-ul pentru commit c22a3fa0c5c Render navigation partial)

Aceasta va genera acest mesaj de commit: fixup! Render navigation partial.

Pasul 2: și colegul --autosquash

Reîncărcare interactivă ușoară. Puteți avea git plasarea automată a fixup în locul potrivit.

git rebase -i 4155df1cdc7 --autosquash

Istoricul va fi afișat astfel:

Pregătit revizuiți și continuați.

Dacă vă simțiți aventuros, puteți face un rebase non-interactiv git rebase --autosquash, dar numai dacă vă place să trăiți periculos, așa cum veți fi nu am nicio ocazie să revizuim squash-urile făcute înainte ca acestea să fie „aplicate din nou.

Situația 4: Istoricul meu de comitere Git nu are sens, am nevoie de un nou început!

Dacă „lucrăm la o caracteristică mare, este obișnuit să existe mai multe modificări de corecție și revizuire-feedback care sunt efectuate frecvent. În loc să refaceți în mod constant sucursala, putem lăsa curățarea comitetelor până la sfârșitul dezvoltării. >

Acesta este locul în care crearea fișierelor de patch-uri este extrem de utilă. De fapt, fișierele de patch-uri au fost principala modalitate de a partaja codul prin e-mail în timp ce colaborați pe proiecte mari open source înainte ca serviciile bazate pe Git, cum ar fi GitLab, să fie disponibile dezvoltatorilor. Imaginați-vă că aveți o astfel de ramură (de exemplu; add-page-navigation) în care există tone de confirmări care nu transmit clar modificările de bază. Iată cum puteți crea un fișier patch pentru toate modificările pe care le-ați făcut în această ramură:

  • Primul pas pentru a crea fișierul de corecție este să vă asigurați că ramura dvs. are toate modificările prezente de la master ramură și nu are conflicte cu același lucru.
  • Puteți rula git rebase master sau git merge master în timp ce sunteți „verificat” în add-page-navigation ramură pentru a obține toate modificările de la master la ramura dvs.
  • Acum creați fișierul patch ; rulați git diff master add-page-navigation > ~/add_page_navigation.patch.
    • Defalcare comandă: aici „folosim caracteristica Git” și solicităm o diferență între master branch și add-page-navigation și redirecționarea ieșirii (prin simbolul >) către un fișier numit add_page_navigation.patch în noi er directorul de pornire (de obicei ~/ în sistemele de operare * nix).
  • Puteți specifica orice cale doriți să păstrați acest fișier în și numele fișierului și extensia ar putea fi orice doriți.
  • Odată ce rulați comanda și nu vedeți erori, fișierul de patch-uri este generat.
  • Acum verificați master ramură; rulați git checkout master.
  • Ștergeți ramura add-page-navigation din repo local; rulați git branch -D add-page-navigation. Amintiți-vă, avem deja modificări ale acestei ramuri într-un fișier de corecție creat.
  • Acum creați o nouă ramură cu același nume (în timp ce master este bifat); rulați git checkout -b add-page-navigation.
  • În acest moment, aceasta este o ramură nouă și nu are nicio modificare.
  • În cele din urmă, aplicați modificările dvs. din fișierul de corecție; git apply ~/add_page_navigation.patch.
  • Aici, toate modificările dvs. sunt aplicate într-o ramură și vor apărea ca necomandate, ca și cum toate modificările dvs. unde s-a făcut, dar niciuna dintre modificări nu a fost angajată efectiv în sucursală.
  • Acum puteți continua și comite fișiere individuale sau fișiere grupate în funcție de zona de impact în ordinea dorită cu mesaje de confirmare concise.

La fel ca în situațiile anterioare, am modificat practic întreaga ramură, așa că este timpul să forțăm împingerea!

Concluzie

Deși am acoperit cele mai frecvente situații de bază care apar într-un flux de lucru de zi cu zi cu Git, rescrierea istoricului Git este un subiect vast și pe măsură ce vă familiarizați cu sfaturile de mai sus, puteți afla concepte mai avansate despre subiect în Documentația oficială Git. Happy git „ing!

Fotografie de pan xiaozhen pe Unsplash

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *