La guida avanzata di Git: Git Stash, Reset, Rebase e altro

Pubblicato: 2022-03-11

Ogni sviluppatore dovrebbe avere una buona conoscenza del controllo della versione e Git è diventato lo standard de facto per il controllo della versione nello sviluppo del software.

Spesso, però, gli sviluppatori imparano solo pochi semplici comandi e trascurano il potere della cronologia di Git e le altre cose che Git può fare per renderti molto più efficiente. Ad esempio, la gestione delle versioni è molto semplice con Git che utilizza git tag .

Ho seguito un corso avanzato in Git online (con Github) e ho continuato a tenere una lezione di Git per principianti insieme a Github. Quando ho notato che non c'erano molti articoli tecnici sulle mie funzionalità Git preferite, ho colto al volo l'occasione di condividerlo con i miei colleghi sviluppatori. In questo post imparerai come sfruttare le seguenti funzioni Git avanzate:

  • git stash , che effettua un salvataggio locale temporaneo del tuo codice
  • git reset , che ti consente di riordinare il tuo codice prima di eseguire un commit
  • git bisect , una funzione che ti consente di scovare commit errati
  • git squash , che ti consente di combinare i tuoi commit
  • git rebase , che consente di applicare le modifiche da un ramo all'altro

Git Stash

Git stash ti consente di salvare il tuo codice senza effettuare un commit. Come è utile? Immagina il seguente scenario:

Hai già eseguito tre commit accurati e ordinati, ma hai anche del codice non sottoposto a commit che è piuttosto disordinato; non vorrai commetterlo senza prima rimuovere il codice di debug. Quindi, per qualche motivo, all'improvviso devi occuparti di un'altra attività e devi cambiare filiale. Questo può accadere spesso se sei sul tuo ramo main e hai dimenticato di creare un nuovo ramo per la tua funzione. In questo momento, il tuo codice è simile a questo:

 $ 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; }

Quando esegui git stash , il codice non sottoposto a commit scompare senza essere sottoposto a commit. Stashing è come salvare un commit locale temporaneo nel tuo ramo. Non è possibile inviare una scorta a un repository remoto, quindi una scorta è solo per uso personale.

 $ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color

Il tuo ramo ora appare com'era quando hai effettuato l'ultimo commit. Ora puoi cambiare in sicurezza i rami senza perdere il tuo codice o avere un commit disordinato. Quando torni al tuo ramo ed esegui git stash list , vedrai un elenco di stash che assomigliano a questo:

 $ git stash list stash@{0}: WIP on my-feature: 49ee696 Change text color

Puoi facilmente riapplicare il contenuto nascosto eseguendo git stash apply . Puoi anche applicare una scorta specifica (se hai nascosto più di una volta) eseguendo git stash apply stash@{1} (l'"1" indica la penultima prima dell'ultima scorta). Ecco un esempio di riporre più di un commit e applicare una scorta diversa:

 $ 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} ha applicato il codice nascosto più vecchio, quando abbiamo cambiato il colore del testo in rosso.

 $ 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; }

Se decidi di non impegnare il tuo lavoro dopo aver ripristinato la scorta, puoi eseguire git checkout . , che reimposta tutto il codice non sottoposto a commit.

Come altro esempio di come usare Git stash: supponiamo che tu abbia dei nuovi file, uno dei quali ha un bug. Lascia tutto tranne il file di bug sospetto non gestito (il codice deve essere messo in scena per essere nascosto), quindi puoi riporre quel file e risolvere il problema. Se il file nascosto non era il problema, puoi ripristinare lo stash.

 $ 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

Puoi anche trasferire i tuoi commit nascosti su un nuovo ramo di funzionalità o su un ramo di debug usando 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)

Nota che quando hai applicato una scorta, la scorta non viene eliminata. Puoi rimuovere gli stash individualmente usando git drop o rimuovere tutti gli stash usando 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 $

Vai Reset

Se ti trovi nella situazione in cui hai commesso accidentalmente del codice disordinato, puoi eseguire un ripristino "soft". Ciò significa che il codice appare come se non fosse stato ancora eseguito il commit. Quindi puoi riordinare il tuo codice nel tuo IDE prima di fare un commit più pulito. Per fare ciò puoi eseguire git reset --soft HEAD~1 . Questo ripristinerà il commit più recente. Puoi ripristinare più di un commit modificando il numero dopo ~ es. 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; }

Git reset è un po' più confuso, specialmente quando si insegna ai nuovi utenti Git. Un soft reset dovrebbe essere riservato a un errore reale, mentre una scorta può essere utilizzata per scambiare codice in entrata e in uscita.

Puoi anche eseguire un hard reset ( git reset --hard HEAD~1 ). Questo tipo di ripristino essenzialmente cancella il tuo ultimo commit. Dovresti fare molta attenzione nell'eseguire hard reset, specialmente se spingi il tuo ramo, poiché non c'è modo di ripristinare il tuo commit.

Git Bisetta

Il mio strumento Git preferito è git bisect . Ne ho avuto bisogno solo una manciata di volte, ma quando l'ho fatto, è stato inestimabile! L'ho usato principalmente su basi di codice di grandi dimensioni in cui c'era un problema per il quale nessuno ha trovato la causa principale, anche dopo un po 'di debug vigoroso.

git bisect esegue essenzialmente una ricerca binaria tra due commit dati e quindi ti presenta i dettagli di un commit specifico. Devi prima dare a Git un buon commit, dove sai che la tua funzionalità stava funzionando, e un cattivo commit. Nota che finché hai un commit buono e uno cattivo, i commit possono essere distanziati di anni (anche se più vai indietro nel tempo, più diventa difficile!).

La cosa più divertente di git bisect è che di solito non sai chi ha scritto il commit buggy quando inizi. L'eccitazione di scoprire dove è stato introdotto il bug ha indotto più di una volta alcuni colleghi a stringersi attorno al mio computer!

Per iniziare, controlla il ramo buggy e trova i buoni commit. Dovrai esaminare la cronologia dei commit e trovare l'hash del commit, quindi controllare quel commit specifico e testare il tuo ramo. Una volta trovato un punto buono e uno cattivo da cui lavorare, puoi eseguire un git bisect .

In questo scenario, il testo è rosso su questo sito Web che abbiamo creato (anche se potrebbe utilizzare un designer dell'interfaccia utente) ma non sappiamo come o quando è stato reso rosso. Questo è un esempio molto semplice, in uno scenario di vita reale probabilmente avresti un problema molto meno ovvio, ad esempio un modulo che non viene inviato/funzionante.

Quando eseguiamo un git log , possiamo vedere l'elenco dei commit da cui scegliere.

 $ 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 ...

Se apro la mia pagina web sull'hash di commit più recente, il testo è rosso, quindi so di avere un problema.

Git bisect, passaggio 1: una pagina web con testo rosso.

Ora iniziamo il bisetto e diciamo a Git che abbiamo un commit errato.

 $ git bisect start $ git bisect bad 8d4615b9a963ef235c2a7eef9103d3b3544f4ee1

Ora torniamo indietro nel tempo per cercare di trovare un commit in cui il testo non fosse rosso. Qui provo a controllare il mio primo 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

…e aggiornando la pagina web…

Git bisect, passaggio 2: una pagina web con testo nero.

Il testo non è più rosso, quindi questo è un buon commit! Più nuovo è il commit, più vicino al commit errato, meglio è:

 $ git checkout d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Previous HEAD position was ce861e4c6989a118aade031020fd936bd28d535b Add CSS styles HEAD is now at d647ac4 Change text color

Git ora ti dirà quanti commit deve cercare prima di trovare quello giusto. Il numero di commit che Git attraverserà dipende da quanti commit ci sono tra il commit buono e quello cattivo (più lungo è il tempo, più volte Git ha bisogno di iterare).

Ora dovrai testare di nuovo il tuo ramo e vedere se il tuo problema è scomparso. A volte questo può essere un po' ingombrante se aggiorni regolarmente i moduli, poiché potrebbe essere necessario reinstallare i moduli del nodo sul tuo repository front-end. Se ci sono stati aggiornamenti del database, potrebbe essere necessario aggiornare anche questi.

git bisect controlla automaticamente un commit nel mezzo dei tuoi commit buoni e cattivi. Qui sta stimando un passaggio per trovare il commit errato.

 $ 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)

Aggiorna la pagina e verifica se il problema è scomparso. Il problema è ancora lì, quindi diciamo a Git che questo è ancora un cattivo commit. Questa volta non è necessario fare riferimento all'hash del commit poiché Git utilizzerà il commit che hai estratto. Dovremo ripetere questo processo finché Git non avrà completato tutti i passaggi possibili.

 $ git bisect bad Bisecting: 0 revisions left to test after this (roughly 0 steps) [cbf1b9a1be984a9f61b79ae5f23b19f66d533537] Add second paragraph to page

Aggiorna la pagina e il nostro problema è sparito di nuovo, quindi questo è un buon commit:

Git bisect, passaggio 3: la stessa pagina web con del testo nero aggiuntivo.

A questo punto Git ha trovato il primo commit errato:

 $ 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

Ora possiamo usare git show per mostrare il commit stesso e identificare il 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; }

Quando hai finito, puoi eseguire git bisect reset per ripristinare il tuo ramo al suo normale stato di lavoro.

Più i commit sono vicini, più facilmente Git sarà in grado di trovare il problema, ma ho fatto eseguire 10 passaggi prima e trovare ancora facilmente il commit errato. Non è garantito che funzioni, ma ha riscontrato il problema la maggior parte delle volte per me. Congratulazioni, ora sei un archeologo del codice!

Distruggere i tuoi impegni

In precedenza ho lavorato a tempo pieno su un progetto open source per un'organizzazione globale e ho imparato rapidamente quanto sia importante eliminare o combinare i propri impegni. Penso che sia un'ottima abitudine da prendere, anche se il tuo datore di lavoro non lo richiede. È particolarmente premuroso per gli altri sviluppatori che dovranno rivedere e modificare le funzionalità che hai creato in seguito.

Perché schiacciare i tuoi impegni?

  • È più facile da leggere per i contributori al tuo repository. Immagina di avere un elenco di commit in questo modo:
    • Implementare il dispositivo di scorrimento del carosello
    • Aggiungi lo stile alla giostra
    • Aggiungi pulsanti al carosello
    • Risolvi uno strano problema in IE con carosello
    • Regola i margini nel carosello

    È molto più facile schiacciarli in un unico commit che dice "Aggiungi carosello alla home page".

  • Ti incoraggia a mantenere i tuoi messaggi di commit comprensibili e pertinenti se ogni volta che fai una richiesta pull, devi schiacciare i tuoi commit in uno solo. Quante volte hai visto un commit intitolato "WIP", "correzione di bug per la pagina di accesso" o "correzione di errore di battitura"? È importante avere nomi di commit pertinenti, ad esempio "Bugfix per la pagina di accesso n. 444 - corretto lo sfarfallio dovuto alla mancanza della funzione $scope".

Un motivo per cui potresti non voler annullare i tuoi impegni potrebbe essere perché stai lavorando su una funzionalità molto dettagliata e lunga e vuoi tenere una cronologia quotidiana per te nel caso in cui ti imbatti in bug in seguito. Quindi è più facile eseguire il debug della tua funzione. Tuttavia, quando controlli la tua funzione nel tuo ramo principale e sei sicuro che sia privo di bug, ha comunque senso schiacciare.

In questo scenario, ho effettuato cinque commit, ma tutti sono correlati a una funzionalità. I miei messaggi di commit sono anche troppo strettamente correlati al merito di essere separati: tutti i miei commit riguardano lo stile della pagina per questa nuova funzionalità:

 $ 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

Puoi anche usare git merge --squash , ma penso che sia più chiaro usare rebase perché quando scegli i tuoi commit è più facile vedere la descrizione del commit. Se esegui un git merge --squash , devi prima eseguire un hard reset dei tuoi commit ( git reset --hard HEAD~1 ), ed è facile confondersi con esattamente quanti commit devi farlo. Trovo che git rebase sia più visivo.

Inizia eseguendo git rebase -i --root e il tuo editor di testo predefinito sulla riga di comando si aprirà con il tuo elenco di commit:

 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

Potresti semplicemente voler schiacciare i tuoi ultimi commit, nel qual caso potresti eseguire git rebase -i HEAD~3 e essere presentato con i tuoi ultimi tre commit:

 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

Ora possiamo schiacciare tutti i commit nel primo commit come mostrato di seguito.

 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

Quando salvi il file, Git aprirà il tuo messaggio di commit da modificare.

 # 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 #

Mentre eseguiamo il rebase, possiamo anche modificare la descrizione del commit in modo che sia più facile da leggere.

 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 di nuovo questo file e il gioco è fatto! Quando diamo un'altra occhiata al registro Git, possiamo vedere che c'è solo un commit pulito.

 [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

Gli sviluppatori di solito sono riluttanti a usare git rebase perché sanno che un rebase può essere utilizzato per eliminare permanentemente i file dalla tua codebase.

Come abbiamo visto sopra, git rebase può essere utilizzato per mantenere il codice e riordinarlo oltre che per eliminarlo, ma cosa succede se vuoi davvero rimuovere permanentemente un file dalla cronologia?

Una volta ho assistito a uno scenario in cui un membro del nostro team di sviluppo aveva accidentalmente commesso un file molto grande nella base di codice. Faceva parte di un ramo molto più grande, quindi il file di grandi dimensioni è passato inosservato durante la revisione del codice ed è stato erroneamente archiviato nel ramo principale. Questo è diventato un problema ogni volta che qualcuno ha voluto riclonare il repository: il download ha richiesto molto tempo! E, naturalmente, il fascicolo in questione non era necessario. Non sarebbe stato un problema se il file fosse stato l'ultimo commit nel ramo principale - in tal caso potresti semplicemente eseguire un hard reset ( git reset --hard HEAD~1 ) e forzare il push del ramo.

Allo stesso modo, se il file fosse l'unica modifica in un determinato commit, potresti semplicemente rimuovere l'intero commit eseguendo git reset --hard <commit-id> . Nel nostro scenario, tuttavia, il file di grandi dimensioni è stato sottoposto a commit insieme ad altro codice che volevamo conservare nella cronologia, come il secondo fino all'ultimo commit.

Una volta trovato il commit problematico, controllalo usando git checkout e l'hash del 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

Rimuovi il file o modifica il codice e lascia il codice (o i file) che desideri mantenere intatti.

 $ 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")

Assicurati di eseguire git add -A in modo che il tuo file eliminato sia messo in scena e Git sappia rimuoverlo. Ora esegui git commit --amend -v e Git ti chiederà di modificare il tuo messaggio di commit.

Dopodiché, esegui git rebase --onto HEAD <commit-id> main . È qui che potresti imbatterti in alcuni conflitti di unione, il che significa che c'è un conflitto tra il tuo nuovo commit e il vecchio codice. Git ti chiederà di risolvere il conflitto:

 $ 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.

Se apri il file nel tuo editor di testo, vedrai che Git ha contrassegnato due versioni del file di indice. Devi semplicemente rimuoverne uno o modificarne uno per mantenere le modifiche che ti piacciono.

 <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

Il codice tra <<<<<<< HEAD e la linea dei segni di uguale è una versione, e il codice tra i segni di uguale e >>>>>>> Add index file è la versione dal commit "Aggiungi file di indice" . Quindi puoi vedere che una versione ha il paragrafo aggiuntivo di "Toptal collega il 3% dei migliori talenti freelance in tutto il mondo", mentre l'altra no.

Salva il file modificato ed esegui git add filename seguito da git rebase --continue . Se non ci sono modifiche puoi anche eseguire git rebase --skip . Potrebbe volerci del tempo per eseguire il rebasing se ci sono stati molti commit tra il tuo commit "file di grandi dimensioni" e l'ultimo commit su main.

Sii paziente e se fai parte di una squadra numerosa assicurati di avere una seconda opinione! È particolarmente importante consultare le persone che hanno scritto i commit che stai unendo, se possibile.

Ricorda che le modifiche all'unione sono rilevanti per il commit specifico nella cronologia e non per le modifiche più aggiornate. Ad esempio, se stai modificando un commit da quando il testo sul tuo sito era Arial e ora è Verdana, dovresti comunque mantenere quel commit con la cronologia di Arial come carattere.

Nota anche che se Git vede uno spazio o un carattere di fine riga, può causare un conflitto di unione, quindi fai attenzione!

Più che impegnarsi e tirare

Git è più potente di quanto molti sviluppatori pensino. Se ti capita di presentare un principiante, assicurati di dare loro alcuni suggerimenti su queste preziose funzionalità. Rende più efficiente il flusso di lavoro.

Vuoi saperne di più su Git? Dai un'occhiata alla pagina Suggerimenti e pratiche Git di Toptal.