Ghidul avansat Git: Git Stash, Reset, Rebase și multe altele
Publicat: 2022-03-11Fiecare dezvoltator ar trebui să aibă o bună înțelegere a controlului versiunilor, iar Git a devenit standardul de facto pentru controlul versiunilor în dezvoltarea de software.
Deseori însă, dezvoltatorii învață doar câteva comenzi simple și trec cu vederea puterea istoriei Git și celelalte lucruri pe care Git le poate face pentru a vă face mult mai eficient. De exemplu, gestionarea versiunilor este foarte ușoară cu Git folosind git tag
.
Am urmat un curs avansat de Git online (cu Github) și am continuat să predau o clasă de Git pentru începători împreună cu Github. Când am observat că nu există multe articole tehnice despre funcțiile mele favorite Git, am profitat de șansa de a le împărtăși colegilor mei dezvoltatori. În această postare, veți învăța cum să utilizați următoarele funcții Git avansate:
-
git stash
, care face o salvare temporară, locală, a codului dvs -
git reset
, care vă permite să vă ordonați codul înainte de a efectua o comitere -
git bisect
, o funcție care vă permite să urmăriți comiterile proaste -
git squash
, care vă permite să vă combinați commit-urile -
git rebase
, care permite aplicarea modificărilor de la o ramură la alta
Git Stash
Git Stash îți permite să-ți salvezi codul fără a face un commit. Cum este acest lucru util? Imaginează-ți următorul scenariu:
Ați făcut deja trei comiteri ordonate, dar aveți și un cod necommit destul de dezordonat; nu veți dori să-l comiteți fără a elimina mai întâi codul de depanare. Apoi, dintr-un motiv oarecare, trebuie să vă ocupați de o altă sarcină și trebuie să schimbați ramurile. Acest lucru se poate întâmpla adesea dacă vă aflați în ramura dvs. main
și ați uitat să creați o nouă ramură pentru caracteristica dvs. Chiar acum, codul tău arată astfel:
$ git status On branch my-feature Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss no changes added to commit (use "git add" and/or "git commit -a")
$ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; }
Când rulați git stash
, codul necommitat dispare fără a fi comis. Ascunderea este ca și cum ați salva un commit local temporar în sucursala dvs. Nu este posibil să împingeți un depozit într-un depozit de la distanță, așa că un depozit este doar pentru uzul dvs. personal.
$ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color
Ramura dvs. apare acum așa cum era când ați făcut ultima comitere. Acum, puteți schimba în siguranță ramurile fără a vă pierde codul sau a avea un comit dezordonat. Când reveniți la ramură și rulați git stash list
, veți vedea o listă de stash-uri care arată cam așa:
$ git stash list stash@{0}: WIP on my-feature: 49ee696 Change text color
Puteți reaplica cu ușurință conținutul ascuns rulând git stash apply
. Puteți, de asemenea, să aplicați o anumită stash (dacă ați ascuns de mai multe ori) rulând git stash apply stash@{1}
(„1” indică a doua dinaintea ultimei stash). Iată un exemplu de păstrare a mai multor comenzi și aplicarea unei alte stash:
$ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; } $ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color $ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..b63c664 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; } $ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color
$ git stash list stash@{0}: WIP on my-feature: 49ee696 Change text color stash@{1}: WIP on my-feature: 49ee696 Change text color stash@{2}: WIP on my-feature: 49ee696 Change text color $ git stash apply stash@{2} On branch my-feature Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss no changes added to commit (use "git add" and/or "git commit -a")
git stash apply stash@{2}
a aplicat cel mai vechi cod ascuns, când am schimbat culoarea textului în roșu.
$ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; }
Dacă decideți să nu vă angajați munca după ce ați restaurat depozitul, puteți rula git checkout .
, care resetează tot codul necommit.
Ca un alt exemplu de utilizare a Git stash: să presupunem că aveți câteva fișiere noi, dintre care unul are o eroare. Lăsați tot, cu excepția fișierului de eroare suspectat, neînscenat (codul trebuie să fie înscenat pentru a fi ascuns), apoi puteți păstra acel fișier și puteți remedia problema. Dacă fișierul ascuns nu a fost problema, puteți restabili stocarea.
$ git status On branch my-feature Untracked files: (use "git add <file>..." to include in what will be committed) css/colors.scss nothing added to commit but untracked files present (use "git add" to track)
$ git add css/colors.scss $ git stash Saved working directory and index state WIP on my-feature: 0d8deef delete colors $ git status On branch my-feature nothing to commit, working tree clean $ git stash apply stash@{0} On branch my-feature Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: css/colors.scss
Puteți, de asemenea, să transferați commit-urile ascunse la o nouă ramură de caracteristici sau o ramură de depanare utilizând git stash branch
:
$ git status On branch my-feature Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss no changes added to commit (use "git add" and/or "git commit -a") $ git stash Saved working directory and index state WIP on my-feature: 66f3f3b Add colors file $ git stash branch debugging-branch M css/common.scss Switched to a new branch 'debugging-branch' Unstaged changes after reset: M css/common.scss On branch debugging-branch Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss Dropped refs/stash@{0} (d140624f60d8deef7bceb0d11fc80ed4fd47e0a1)
Rețineți că atunci când ați aplicat o rezervă, aceasta nu este ștearsă. Puteți elimina stash-urile individual folosind git drop
sau puteți elimina toate stash-urile folosind git stash clear
:
$ git stash list stash@{0}: WIP on my-feature: 66f3f3b Add colors file stash@{1}: WIP on my-feature: 0d8deef delete colors stash@{2}: WIP on my-feature: 49ee696 Change text color $ git stash drop stash@{2} Dropped stash@{2} (8ed6d2ce101aa2e28c8ccdc94cb12df8e5c468d6) $ git stash list stash@{0}: WIP on my-feature: 66f3f3b Add colors file stash@{1}: WIP on my-feature: 0d8deef delete colors $ git stash clear $ git stash list $
Resetare Git
Dacă vă aflați în situația în care ați comis accidental un cod dezordonat, puteți face o resetare „soft”. Aceasta înseamnă că codul pare ca și cum nu a fost încă comis. Apoi, puteți face ordine în codul dvs. în IDE-ul dvs. înainte de a face un commit mai curat. Pentru a face acest lucru, puteți rula git reset --soft HEAD~1
. Aceasta va reseta cea mai recentă comitere. Puteți reseta mai mult de un comit schimbând numărul după ~
de exemplu git reset --soft HEAD~2
.
$ git reset --soft HEAD~1 $ git status On branch debugging-branch Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: css/common.scss Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss
$ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: $grey; + color: red; background-color: #f00; }
Resetarea Git este puțin mai confuză, mai ales când predați noi utilizatori Git. O resetare soft ar trebui rezervată pentru o greșeală reală, în timp ce o rezervă poate fi folosită pentru a schimba codul.
De asemenea, puteți efectua o resetare hard ( git reset --hard HEAD~1
). Acest tip de resetare șterge, în esență, ultima comitere. Ar trebui să fiți foarte atenți la efectuarea resetărilor hard, mai ales dacă vă împingeți ramura, deoarece nu există nicio modalitate de a vă restabili comiterea.
Git Bisect
Instrumentul meu Git preferat este git bisect
. Am avut nevoie doar de câteva ori, dar când am avut-o, a fost neprețuit! L-am folosit în principal pe baze de cod mari, unde a existat o problemă pentru care nimeni nu a găsit cauza principală, chiar și după o depanare viguroasă.
git bisect
efectuează, în esență, o căutare binară între două comiteri date și apoi vă prezintă detaliile unei anumite comiteri. Mai întâi trebuie să-i dai lui Git un commit bun, în care știi că funcționalitatea ta funcționează și un commit prost. Rețineți că atâta timp cât aveți o comitere bună și una proastă, comiterile pot fi distanțate la ani de distanță (deși cu cât mergeți mai înapoi în timp, cu atât devine mai dificil!).
Cel mai distractiv lucru despre git bisect
este că de obicei nu știi cine a scris buggy commit atunci când pornești. Emoția de a afla unde a fost introdus bug-ul a făcut de mai multe ori câțiva colegi să se înghesuie în jurul computerului meu!
Pentru a începe, verificați ramura buggy și găsiți comite-urile bune. Va trebui să parcurgeți istoricul de comitere și să găsiți hash-ul de comitere, apoi să verificați acel comit specific și să vă testați ramura. Odată ce găsiți un loc bun și rău din care să lucrați, puteți rula un git bisect
.
În acest scenariu, textul este roșu pe acest site web pe care l-am creat (deși ar putea folosi un designer UI), dar nu știm cum sau când a fost făcut roșu. Acesta este un exemplu foarte simplu, într-un scenariu din viața reală, probabil că ați avea o problemă mult mai puțin evidentă, de exemplu, un formular care nu se trimite/funcționează.
Când rulăm un git log
, putem vedea lista de comite din care să alegem.
$ git log commit a3cfe7f935c8ad2a2c371147b4e6dcd1a3479a22 (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Update .gitignore file for .DS_Store commit 246e90977790967f54e878a8553332f48fae6edc Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:51:23 2021 +0100 Change styling of page commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit 032a41136b6653fb9f7d81aef573aed0dac3dfe9 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:42:57 2021 +0100 Change text color commit 246e90977790967f54e878a8553332f48fae6edc Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:41:23 2021 +0100 delete colors commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:07:36 2021 +0100 ...
Dacă îmi deschid pagina web pe cel mai recent commit hash, textul este roșu, așa că știu că am o problemă.
Acum începem bisectul și îi spunem lui Git că avem un commit prost.
$ git bisect start $ git bisect bad 8d4615b9a963ef235c2a7eef9103d3b3544f4ee1
Acum ne întoarcem în timp pentru a încerca să găsim un commit în care textul nu era roșu. Aici încerc să verific primul meu commit...
$ git checkout ce861e4c6989a118aade031020fd936bd28d535b Note: checking out 'ce861e4c6989a118aade031020fd936bd28d535b'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at ce861e4 Add CSS styles
... și reîmprospătând pagina web...
Textul nu mai este roșu, așa că acesta este un commit bun! Cu cât comitetul este mai nou, cu atât este mai aproape de comiterea proastă, cu atât mai bine:
$ git checkout d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Previous HEAD position was ce861e4c6989a118aade031020fd936bd28d535b Add CSS styles HEAD is now at d647ac4 Change text color
Git vă va spune acum câte comiteri trebuie să caute înainte de a-l găsi pe cel potrivit. Numărul de comiteri pe care le va parcurge Git depinde de câte comiteri sunt între comiterea bună și cea greșită (cu cât este mai lungă perioada de timp, cu atât Git trebuie să repete mai multe ori).
Acum, va trebui să vă testați din nou ramura și să vedeți dacă problema dvs. a dispărut. Uneori, acest lucru poate fi puțin greoi dacă actualizați în mod regulat modulele, deoarece poate fi necesar să reinstalați modulele de noduri în depozitul dvs. frontal. Dacă au existat actualizări ale bazei de date, poate fi necesar să le actualizați.
git bisect
verifică automat o comitere în mijlocul comiterilor tale bune și rele. Aici se estimează un pas pentru a găsi comiterea proastă.
$ git bisect good 1cdbd113cad2f452290731e202d6a22a175af7f5 Bisecting: 1 revision left to test after this (roughly 1 step) [ce861e4c6989a118aade031020fd936bd28d535b] Add CSS styles $ git status HEAD detached at ce861e4 You are currently bisecting, started from branch '8d4615b'. (use "git bisect reset" to get back to the original branch)
Actualizează pagina și vezi dacă problema ta a dispărut. Problema este încă acolo, așa că îi spunem lui Git că aceasta este încă o comitere proastă. Nu este nevoie să faceți referire la commit hash de data aceasta, deoarece Git va folosi commit-ul pe care l-ați verificat. Va trebui să repetăm acest proces până când Git a parcurs toți pașii posibili.
$ git bisect bad Bisecting: 0 revisions left to test after this (roughly 0 steps) [cbf1b9a1be984a9f61b79ae5f23b19f66d533537] Add second paragraph to page
Reîmprospătați pagina și problema noastră a dispărut din nou, deci acesta este un commit bun:

În această etapă, Git a găsit prima comitere greșită:
$ git bisect good ce861e4c6989a118aade031020fd936bd28d535b is the first bad commit commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Add CSS styles :000000 100644 0000000000000000000000000000000000000000 092bfb9bdf74dd8cfd22e812151281ee9aa6f01a M css
Acum putem folosi git show
pentru a arăta commit-ul în sine și pentru a identifica problema:
$ git show ce861e4c6989a118aade031020fd936bd28d535b commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Add CSS styles diff --git a/css/base.scss b/css/base.scss index e69de29..26abf0f 100644 --- a/css/base.scss +++ b/css/base.scss @@ -1,7 +1,7 @@ body { background-color: $white; margin: 0px; line-height: 20px; - color: $grey; + color: red; }
Când ați terminat, puteți rula git bisect reset
pentru a vă reseta ramura la starea normală de lucru.
Cu cât commit-urile sunt mai apropiate, cu atât Git va fi mai ușor să găsească problema, dar am făcut-o cu 10 pași înainte și tot găsesc cu ușurință commit-ul rău. Nu este garantat să funcționeze, dar a găsit problema de cele mai multe ori pentru mine. Felicitări, acum ești arheolog cod!
Strângerea angajamentelor dvs
Anterior, am lucrat cu normă întreagă la un proiect cu sursă deschisă pentru o organizație globală și am învățat rapid cât de important este să vă slăbiți sau să vă combinați angajamentele. Cred că este un obicei excelent să intri, chiar dacă angajatorul tău nu o cere. Este deosebit de atent pentru alți dezvoltatori care vor trebui să revizuiască și să editeze funcțiile pe care le-ați creat mai târziu.
De ce să vă striviți comisiile?
- Este mai ușor de citit pentru contributorii la depozitul dvs. Imaginați-vă dacă aveți o listă de commit ca aceasta:
- Implementați glisorul carusel
- Adăugați stil caruselului
- Adăugați butoane în carusel
- Remediați problema ciudată în IE cu carusel
- Ajustați marginile în carusel
Este mult mai ușor să le comprimați într-un singur commit care spune „Adăugați carusel la pagina de pornire”.
- Vă încurajează să păstrați mesajele de comitere înțelese și relevante dacă de fiecare dată când faceți o solicitare de extragere, trebuie să vă strângeți commit-urile într-una. De câte ori ați văzut un commit intitulat „WIP”, „remediere erori pentru pagina de autentificare” sau „remediere greșeală”? Este important să aveți nume de comitere relevante, de exemplu „Bugfix pentru pagina de autentificare #444 - remediați pâlpâirea din cauza lipsei funcției $scope”.
Un motiv pentru care s-ar putea să nu doriți să vă stricați comisioanele ar putea fi faptul că lucrați la o funcție foarte detaliată și lungă și doriți să păstrați un istoric zilnic pentru dvs. în cazul în care întâlniți erori mai târziu. Apoi, funcția dvs. este mai ușor de depanat. Cu toate acestea, atunci când vă verificați caracteristica în ramura dvs. principală și sunteți încrezător că nu există erori, este totuși logic să faceți squash.
În acest scenariu, am făcut cinci comitări, dar toate sunt legate de o caracteristică. Mesajele mele de comitere sunt, de asemenea, prea strâns legate de meritul de a fi separat – toate commit-urile mele se referă la stilarea paginii pentru această nouă caracteristică:
$ git log commit a8fbb81d984a11adc3f72ce27dd0c39ad24403b7 (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 11:16:10 2021 +0100 Import colors commit e2b3ddd5e8b2cb1e61f88350d8571df51d43bee6 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 11:15:32 2021 +0100 Add new color commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit c005d9ceeefd4a8d4e553e825fa40aaafdac446e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 09:59:57 2021 +0100 Add CSS styles commit 9e046b7df59cef07820cc90f694fabc666731bd2 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 09:56:28 2021 +0100 Add second paragraph to page commit 5aff973577d67393d914834e8af4c5d07248d628 Author: Ursula Clarke <[email protected]> Date: Mon Jan 10 16:04:22 2021 +0100 Add colors CSS file and edit background color
De asemenea, puteți utiliza git merge --squash
, dar cred că este mai clar să utilizați rebase
, deoarece atunci când alegeți comit-urile, este mai ușor să vedeți descrierea commit-ului. Dacă rulați un git merge --squash
, mai întâi trebuie să faceți o resetare completă a commit-urilor ( git reset --hard HEAD~1
) și este ușor să vă confundați cu exact cu câte comit-uri trebuie să faceți acest lucru. Găsesc că git rebase
este mai vizual.
Începeți prin a rula git rebase -i --root
și editorul dvs. de text implicit de pe linia de comandă se va deschide cu lista dvs. de comite:
pick eb1eb3c Update homepage pick 5aff973 Add colors CSS file and edit background color pick 9e046b7 Add second paragraph to page pick c005d9c Add CSS styles pick d647ac4 Change text color pick e2b3ddd Add new color pick a8fbb81 Import colors # Rebase a8fbb81 onto b862ff2 (7 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
S-ar putea să doriți doar să vă eliminați ultimele comiteri, caz în care ați putea rula git rebase -i HEAD~3
și să vi se prezinte ultimele trei comenzi:
pick eb1eb3c Update homepage pick 5aff973 Add colors CSS file and edit background color pick 9e046b7 Add second paragraph to page # Rebase b862ff2..9e046b7 onto b862ff2 (3 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
Acum putem squash toate commit-urile în primul commit, așa cum se arată mai jos.
pick eb1eb3c Update homepage squash 5aff973 Add colors CSS file and edit background color squash 9e046b7 Add second paragraph to page # Rebase b862ff2..9e046b7 onto b862ff2 (3 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
Când salvați fișierul, Git va deschide mesajul dvs. de confirmare pentru a-l edita.
# This is a combination of 3 commits. # This is the 1st commit message: Update homepage # This is the commit message #2: Add colors CSS file and edit background color # This is the commit message #3: Add second paragraph to page # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Date: Wed Jan 13 18:31:28 2021 +0100 # # interactive rebase in progress; onto b862ff2 # Last commands done (3 commands done): # squash 5aff973 Add colors CSS file and edit background color # squash 9e046b7 Add second paragraph to page # No commands remaining. # You are currently rebasing branch 'main' on 'b862ff2'. # # Changes to be committed: # new file: .gitignore # new file: css/base.css # new file: css/base.scss # new file: css/colors.css # new file: css/colors.css.map # new file: css/colors.scss # new file: css/common.css # new file: css/common.scss # new file: index.html #
În timp ce facem rebazarea, putem edita și descrierea de comitere, astfel încât să fie mai ușor de citit.
Implement new design for homepage. Add .gitignore file for Sass folder. # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. #
Salvați acest fișier din nou și ați terminat! Când aruncăm o altă privire la jurnalul Git, putem vedea că există doar un singur commit curat.
[detached HEAD 574ec7e] Implement new design for homepage. Add .gitignore file for Sass folder. Date: Wed Jan 13 18:31:28 2021 +0100 10 files changed, 215 insertions(+) create mode 100644 .gitignore create mode 100644 css/base.css create mode 100644 css/base.scss create mode 100644 css/colors.css create mode 100644 css/colors.css.map create mode 100644 css/colors.scss create mode 100644 css/common.css create mode 100644 css/common.scss create mode 100644 index.html create mode 100644 verylargefile.txt Successfully rebased and updated refs/heads/main. $ git log commit 574ec7e5d7d7a96427e049cad9806cdef724aedd (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Wed Jan 13 18:31:28 2021 +0100 Implement new design for homepage. Add .gitignore file for Sass folder.
Git Rebase
De obicei, dezvoltatorii ezită să folosească git rebase
, deoarece știu că o rebase poate fi folosită pentru a șterge definitiv fișierele din baza de cod.
După cum am văzut mai sus, git rebase
poate fi folosit pentru a vă păstra codul și a-l ordona, precum și pentru a-l șterge - dar dacă doriți cu adevărat să eliminați definitiv un fișier din istoric?
Am asistat odată la un scenariu în care un membru al echipei noastre de dezvoltare a comis accidental un fișier foarte mare în baza de cod. Făcea parte dintr-o ramură mult mai mare, așa că fișierul mare a trecut neobservat în revizuirea codului și a fost introdus din greșeală în ramura principală. Aceasta a devenit o problemă ori de câte ori cineva dorea să re-clone depozitul - a durat foarte mult timp pentru a descărca! Și desigur, dosarul în cauză nu era necesar. Nu ar fi fost o problemă dacă fișierul ar fi fost ultimul comit către ramura principală - în acest caz, ați putea pur și simplu să executați o resetare completă ( git reset --hard HEAD~1
) și să forțați împingerea ramurii.
De asemenea, dacă fișierul a fost singura modificare într-un anumit commit, ați putea doar să eliminați întregul comit rulând git reset --hard <commit-id>
. În scenariul nostru, totuși, fișierul mare a fost comis împreună cu alt cod pe care doream să-l păstrăm în istorie, ca a doua până la ultima comitere.
Odată ce găsiți commit-ul supărător, verificați-l folosind git checkout
și commit hash:
$ git checkout ce861e4c6989a118aade031020fd936bd28d535b Note: checking out 'ce861e4c6989a118aade031020fd936bd28d535b'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at ce861e4 Add CSS styles
Eliminați fișierul sau editați codul și lăsați codul (sau fișierele) pe care doriți să le păstrați intact.
$ rm verylargefile.txt $ git status HEAD detached at ce861e4 Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: verylargefile.txt no changes added to commit (use "git add" and/or "git commit -a")
Asigurați-vă că executați git add -A
, astfel încât fișierul dvs. șters să fie pus în scenă și Git să știe să îl elimine. Acum rulați git commit --amend -v
și Git vă va cere să editați mesajul de commit.
După aceasta, rulați git rebase --onto HEAD <commit-id> main
. Aici puteți întâlni unele conflicte de îmbinare, ceea ce înseamnă că există un conflict între noul dvs. commit și vechiul cod. Git vă va cere să rezolvați conflictul:
$ git add -A $ git status HEAD detached at ce861e4 Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: verylargefile.txt $ git commit --amend -v [detached HEAD 7c9516a] Add CSS styles Date: Thu Jan 14 14:43:54 2021 +0100 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 css/common.css.map delete mode 100644 verylargefile.txt $ git status HEAD detached from ce861e4 nothing to commit, working tree clean $ git rebase --onto HEAD ce861e4 First, rewinding head to replay your work on top of it... Fast-forwarded HEAD to HEAD.
Dacă deschideți fișierul în editorul de text, veți vedea că Git a marcat două versiuni ale fișierului index. Trebuie pur și simplu să eliminați unul sau să editați unul pentru a păstra modificările care vă plac.
<p> Toptal was created by engineers. We are entrepreneurs, all passionate about working with top tech talent and exciting companies from all over the world. </p> <<<<<<< HEAD <p> Toptal connects the top 3% of freelance talent all over the world. </p> </main> </body> </html> ======= </main> </body> </html> >>>>>>> Add index file
Codul dintre <<<<<<< HEAD
și linia semnelor egal este o versiune, iar codul dintre semnele egal și >>>>>>> Add index file
este versiunea din comitetul „Adăugați fișierul index”. . Așadar, puteți vedea că o versiune are paragraful suplimentar „Toptal conectează primele 3% dintre talentele independente din întreaga lume”, în timp ce cealaltă nu are.
Salvați fișierul editat și rulați git add filename
urmat de git rebase --continue
. Dacă nu există modificări, puteți rula și git rebase --skip
. Poate dura ceva timp pentru a trece prin rebazare dacă au existat multe comiteri între comiterea „fișierului mare” și cea mai recentă comitere de pe main.
Ai răbdare, iar dacă faci parte dintr-o echipă mare, asigură-te că primești o a doua opinie! Este deosebit de important să vă consultați cu persoana (persoanele) care a scris comite-urile pe care le fuzionați, dacă este posibil.
Amintiți-vă că modificările de îmbinare sunt relevante pentru comiterea specifică din istorie și nu pentru cele mai actualizate modificări ale dvs. Adică, dacă editați un commit de când textul de pe site-ul dvs. era Arial, iar acum este Verdana, ar trebui să păstrați totuși acel commit cu istoricul Arial ca font.
De asemenea, rețineți că, dacă Git vede un spațiu sau un caracter de sfârșit de linie, poate provoca un conflict de îmbinare, așa că aveți grijă!
Mai mult decât să se angajeze și să tragă
Git este mai puternic decât cred mulți dezvoltatori. Dacă se întâmplă să prezentați un începător, asigurați-vă că îi oferiți câteva sfaturi despre aceste caracteristici neprețuite. Face un flux de lucru mai eficient.
Doriți să aflați mai multe despre Git? Aruncă o privire la pagina de Sfaturi și practici Git a Toptal.