<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Git - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Impara a programmare gratuitamente! Tutorial di programmazione su Python, JavaScript, Linux e molto altro. ]]>
        </description>
        <link>https://www.freecodecamp.org/italian/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Git - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/italian/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 16 May 2026 19:16:17 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/italian/news/tag/git/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Git checkout – Come estrarre un file ed inserirlo in un altro branch ]]>
                </title>
                <description>
                    <![CDATA[ Mentre lavori su un repository in Git, potresti avere necessità di estrarre uno specifico file da un branch e spostarlo in un altro branch (in gergo, eseguire il checkout di un file in un altro branch). Fortunatamente, Git offre molti possibili modi per fare questa attività rapidamente. Una delle soluzioni ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/estrarre-un-file-da-un-altro-branch/</link>
                <guid isPermaLink="false">671fd7199ae93404d06944bd</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Andrea Sisti ]]>
                </dc:creator>
                <pubDate>Thu, 06 Feb 2025 16:42:09 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2025/02/cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/git-checkout-file-from-another-branch/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Git Checkout – How to Checkout a File from Another Branch</a>
      </p><p>Mentre lavori su un repository in Git, potresti avere necessità di estrarre uno specifico file da un branch e spostarlo in un altro branch (in gergo, eseguire il <em>checkout</em> di un file in un altro branch).</p><p>Fortunatamente, Git offre molti possibili modi per fare questa attività rapidamente. Una delle soluzioni più semplici è usare il comando <code>git checkout</code> con un file specifico come argomento.</p><p>In questo articolo, analizzeremo differenti soluzioni a questo problema e approfondiremo le procedura che dovrai seguire per ciascuna.</p><p>Partiamo! 😎.</p><h2 id="casi-d-uso-di-git-checkout"><strong>Casi d'uso di git checkout</strong></h2><p>Stai lavorando su un branch, chiamato <code>feature/A</code>, contenente un file denominato <code>utils.js</code>.</p><p>Hai anche un altro branch, chiamato <code>feature/B</code> con un file aggiornato <code>utils.js</code>.</p><p>Vuoi effettuare il checkout di questo file e portarlo dal branch chiamato <code>feature/B</code> al branch chiamato <code>feature/A</code>.</p><p>Ci sono tre possibili soluzioni per questo compito.</p><h3 id="soluzione-1-usare-il-comando-git-checkout"><strong>Soluzione <strong>1: </strong>Usare il comando<strong> <code>git checkout</code></strong></strong></h3><p>Il comando <code>git checkout</code> offre un modo semplice per prendere un file o una cartella da un altro branch.</p><p>Qui viene riportato il codice per eseguire il checkout di un file da un altro branch:</p><pre><code class="language-bash">git checkout &lt;nome-altro-branch&gt; -- percorso/del/file/
</code></pre><p>Ecco la procedura da seguire:</p><ol><li>Esegui il checkout del branch dove vuoi copiare il file.</li></ol><pre><code class="language-bash">git checkout feature/A
</code></pre><p>2.	Una volta che sei nel branch corretto, copia il file.</p><pre><code class="language-bash">git checkout feature/B -- utils.js
</code></pre><p>3.	Usa il comando git status per assicurarti che il file sia stato copiato.</p><p>4. 	Esegui il commit e il push a un branch remoto.</p><p>Quando usi il comando checkout, puoi anche ottenere:</p><ul><li>Una cartella da un altro branch.</li><li>File multipli specificando ciascuno di questi.</li></ul><p>Inoltre, considera che puoi anche estrarre un file/cartella dallo stash.</p><h3 id="soluzione-2-usa-il-comando-git-restore"><strong><strong>Sol</strong>uzione <strong>2: </strong>Usa il comando <strong><code>git restore</code> </strong></strong></h3><p>Un'altra opzione è utilizzare il comando <code>git switch</code> insieme al comando <code>git restore</code>.</p><p>Se non hai mai sentito di questi due comandi, è tutto a posto. Sono relativamente nuovi. Git li ha introdotti nella versione 2.23 del 2019.</p><p>La funzione di questi due comandi è separare le responsabilità del comando <code>git checkout</code> per semplificarne l'utilizzo per gli utenti.</p><p>Il comando <code>git restore</code> ripristina l'albero di lavoro.</p><p>Il comando <code>git switch</code> passa da un branch all'altro.</p><p>Questa è la procedura da seguire per prendere un file da un altro branch:</p><p>1.	Passa al branch dove vuoi inserire il file.</p><pre><code class="language-bash">git switch feature/A
</code></pre><p>2.	Prendi il file dall'altro branch.</p><pre><code class="language-bash">git restore --source feature/B -- utils.js
</code></pre><p>3.	Esegui il commit e il push dei cambiamenti.</p><h3 id="soluzione-3-usa-il-comando-git-show"><strong>Soluzione<strong> 3: </strong>Usa il comando<strong> <code>git show</code></strong></strong></h3><p>Per ultimo, possiamo usare il comando <code>git show</code> .</p><p>Qui è riportata la procedura da seguire:</p><p>1.	Passa al branch di lavoro.</p><pre><code class="language-bash">git switch feature/A
</code></pre><p>2.	Prendi il file dall'altro branch</p><pre><code class="language-bash">git show feature/B:path/utils.js &gt; path/utils.js
</code></pre><p>3.	Esegui il commit e il push dei cambiamenti.</p><p><strong>Nota: </strong>questa volta devi specificare il percorso relativo dalla root della tua directory.</p><h2 id="considerazioni-finali"><strong>Considerazioni finali</strong></h2><p>Come puoi vedere, prendere un file da un altro branch non è così complicato.</p><p>Quando devo farlo nella mia vita di tutti i giorni, di solito uso il comando <code>git checkout</code>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/06/6ii6ur.jpg" class="kg-image" alt="Image" width="600" height="400" loading="lazy"></figure><p>Visita il <a href="https://timmousk.com/">mio blog</a> se sei interessato a scoprire di più su Git o sulle tecnologie usate nello sviluppo Web, come TypeScript.</p><p>Grazie per aver letto questo articolo.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Come cambiare il nome di un branch locale  in Git ]]>
                </title>
                <description>
                    <![CDATA[ Mentre realizzi un progetto, a volte potresti avere necessità di rinominare un branch locale. Ma come puoi farlo in Git? In questo articolo, ti fornirò due metodi per rinominare i branch locali in Git. Come rinominare un branch in Git – Metodo n° 1 Step 1: assicurati di essere nella ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/come-cambiare-il-nome-di-un-branch-locale-in-git/</link>
                <guid isPermaLink="false">671fcb1b9ae93404d0694333</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Andrea Sisti ]]>
                </dc:creator>
                <pubDate>Sat, 18 Jan 2025 18:32:36 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2025/01/mila-tovar-NTiW908Uc1A-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/git-rename-branch-how-to-change-a-local-branch-name/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Git Rename Branch – How to Change a Local Branch Name</a>
      </p><p>Mentre realizzi un progetto, a volte potresti avere necessità di rinominare un branch locale. Ma come puoi farlo in Git?</p><p>In questo articolo, ti fornirò due metodi per rinominare i branch locali in Git.</p><h2 id="come-rinominare-un-branch-in-git-metodo-n-1"><strong>Come rinominare un branch in Git <strong>– </strong>Metodo n° <strong>1</strong></strong></h2><h3 id="step-1-assicurati-di-essere-nella-cartella-root-del-tuo-progetto"><strong><strong>Step 1: </strong>assicurati di essere nella cartella root del tuo progetto</strong></h3><p>Per prima cosa dovrai aprire il tuo terminale e quindi cambiare directory &nbsp;(<code>cd</code>) nella cartella root del tuo progetto.</p><p>Per esempio, questo è come appare il comando se ti trovi nella tua home directory e vuoi spostarti nel progetto collocato nel Desktop.</p><pre><code>cd Desktop/nome-progetto
</code></pre><p>Questo è un esempio di come spostarsi nella cartella di un progetto denominato <code>Happy_Messages_Bot</code>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-02-at-10.30.01-PM.png" class="kg-image" alt="Image" width="600" height="400" loading="lazy"></figure><h3 id="step-2-vai-sul-branch-che-vuoi-rinominare"><strong><strong>Step 2:</strong> vai sul Branch che vuoi rinominare</strong></h3><p>Puoi usare il comando <code>git checkout</code> per passare a un altro branch.</p><pre><code>git checkout nome-branch
</code></pre><p>In questo esempio, voglio passare al branch denominato <code>test-branch</code> che ho creato.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-02-at-10.39.57-PM.png" class="kg-image" alt="Image" width="600" height="400" loading="lazy"></figure><h3 id="step-3-usa-il-flag-m-per-cambiare-il-nome-al-branch"><strong><strong>Step 3: </strong>usa il flag<strong> <code>-m</code> </strong>per cambiare il nome al branch</strong></h3><p>Questo è la sintassi del comando per cambiare nome al branch:</p><pre><code>git branch -m nuovo-nome-branch
</code></pre><p>In questo esempio, voglio cambiare il nome del mio branch da <code>test-branch</code> a <code>test-branch2</code>.</p><pre><code>git branch -m test-branch2
</code></pre><p>Puoi usare <code>git status</code> per vedere il nuovo nome del branch.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-02-at-10.52.02-PM.png" class="kg-image" alt="Image" width="600" height="400" loading="lazy"></figure><h2 id="come-rinominare-un-branch-in-git-metodo-n-2"><strong>Come rinominare un branch in Git <strong>– </strong>Metodo n° 2</strong></h2><p>Possiamo rinominare il branch locale con un solo comando senza dover usare <code>git checkout</code>.</p><h3 id="step-1-assicurati-di-trovarti-sul-branch-master-main"><strong><strong>Step 1: </strong>assicurati di trovarti sul branch <strong>master/main</strong></strong></h3><p>Per controllare se ti trovi sul branch master/main, lancia <code>git status</code>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-02-at-11.02.20-PM.png" class="kg-image" alt="Image" width="600" height="400" loading="lazy"></figure><p>Se non ti trovi sul branch master/main , allora devi lanciare <code>git checkout master</code> oppure <code>git checkout main</code>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-02-at-11.05.28-PM.png" class="kg-image" alt="Image" width="600" height="400" loading="lazy"></figure><h3 id="step-2-usa-il-flag-m-per-cambiare-il-nome-al-branch"><strong><strong>Step 2: </strong>usa il flag<strong> <code>-m</code> </strong>per cambiare il nome al Branch</strong></h3><p>Puoi usare questa sintassi per rinominare il branch esistente:.</p><pre><code>git branch -m vecchio-nome nuovo-nome
</code></pre><p>Ecco come cambiare il nome di <code>test-branch</code> in <code>test-branch2</code>.</p><pre><code>git branch -m test-branch test-branch2
</code></pre><p>Per vedere il nuovo nome del branch, puoi lanciare <code>git branch</code>, che mostrerà la lista di tutti i tuoi branch.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-02-at-11.15.52-PM.png" class="kg-image" alt="Image" width="600" height="400" loading="lazy"></figure><p>Questi appena esposti sono due metodi per rinominare dei branch locali in Git.<br></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Git switch – Come passare da un branch a un altro in Git ]]>
                </title>
                <description>
                    <![CDATA[ Cambiare branch è un'operazione di cui avrai bisogno spesso in Git. Per farlo, puoi usare il comando git checkout. Come creare un nuovo branch in Git Per creare un nuovo branch in Git, puoi usare il comando git checkout e passare il flag -b seguito da un nome. Questo creerà ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/git-switch-branch-come-cambiare-branch/</link>
                <guid isPermaLink="false">671fc1029ae93404d0694211</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Andrea Sisti ]]>
                </dc:creator>
                <pubDate>Fri, 13 Dec 2024 09:59:55 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2024/12/60770740776bd507fe31f89c.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/git-switch-branch/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Git Switch Branch – How to Change the Branch in Git</a>
      </p><p>Cambiare branch è un'operazione di cui avrai bisogno spesso in Git.</p><p>Per farlo, puoi usare il comando <code>git checkout</code>.</p><h2 id="come-creare-un-nuovo-branch-in-git"><strong>Come creare un nuovo branch in Git</strong></h2><p>Per creare un nuovo branch in Git, puoi usare il comando <code>git checkout</code> e passare il flag <code>-b</code> seguito da un nome.</p><p>Questo creerà un nuovo branch partendo da quello corrente. La cronologia del nuovo branch inizierà con la posizione corrente del branch da cui hai lanciato il comando.</p><p>Assumendo di trovarsi sul branch chiamato <code>master</code>:</p><pre><code>(master)$ git checkout -b my-feature
Switched to a new branch 'my-feature'
(my-feature)$
</code></pre><p>Qui puoi vedere un nuovo branch appena creato chiamato <code>my-feature</code>, che è stato generato come ramificazione a partire da <code>master</code>. </p><h2 id="come-passare-a-un-branch-esistente-in-git"><strong>Come passare a un branch esistente in Git</strong></h2><p>Per passare a un branch esistente, puoi usare il comando <code>git checkout</code> (senza il flag &nbsp;<code>-b</code>) e passare il nome del branch che vuoi raggiungere:</p><pre><code>(my-feature)$ git checkout master
Switched to branch 'master'
(master)$
</code></pre><p>Esiste anche una pratica scorciatoia per ritornare al branch su cui ti trovavi precedentemente, passando <code>-</code> al comando <code>git checkout</code> invece del nome del branch:</p><pre><code>(my-feature)$ git checkout -
Switched to branch 'master'
(master)$ git checkout -
Switched to branch 'my-feature'
(my-feature)$
</code></pre><h2 id="come-eseguire-il-checkout-di-uno-specifico-commit"><strong>Come eseguire il checkout di uno specifico commit</strong></h2><p>Per eseguire il checkout o passare ad un commit specifico, puoi anche usare &nbsp;<code>git checkout</code> e passare come parametro lo <a href="https://it.wikipedia.org/wiki/Secure_Hash_Algorithm">SHA</a> del commit invece del nome del branch.</p><p>Dopotutto, i branch sono effettivamente solo puntatori e rilevatori di specifici commit nella cronologia di Git.</p><h3 id="come-trovare-lo-sha-di-un-commit"><strong>Come trovare lo SHA di un commit</strong></h3><p>Un modo per trovare lo SHA di un commit è guardare nel log di Git.</p><p>Puoi visualizzare il log utilizzando il comando <code>git log</code>:</p><pre><code>(my-feature)$ git log
commit 94ab1fe28727b7f8b683a0084e00a9ec808d6d39 (HEAD -&gt; my-feature, master)
Author: John Mosesman &lt;johnmosesman@gmail.com&gt;
Date:   Mon Apr 12 10:31:11 2021 -0500

    This is the second commmit message.

commit 035a128d2e66eb9fe3032036b3415e60c728f692 (blah)
Author: John Mosesman &lt;johnmosesman@gmail.com&gt;
Date:   Mon Apr 12 10:31:05 2021 -0500

    This is the first commmit message.
</code></pre><p>Sulla prima riga di ciascun commit, dopo la parola <code>commit</code> si trova una lunga stringa di caratteri e di numeri: <code>94ab1fe28727...</code></p><p>Si tratta dello SHA, un identificatore unico che viene generato per ogni commit.</p><p>Per eseguire il checkout di un commit specifico, devi solo passare lo SHA del commit come parametro al comando <code>git checkout</code>:</p><pre><code>(my-feature)$ git checkout 035a128d2e66eb9fe3032036b3415e60c728f692
Note: switching to '035a128d2e66eb9fe3032036b3415e60c728f692'.

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 switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c &lt;new-branch-name&gt;

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 035a128 a
((HEAD detached at 035a128))$
</code></pre><blockquote><em><em><strong><strong>Not</strong></strong></em><strong>a</strong><em>: </em>generalmente avrai bisogno di usare solo i primi caratteri dello SHA, poichè i primi quattro o cinque caratteri della stringa sono molto probabilmente unici in tutto il progetto.</em></blockquote><h2 id="cosa-vuol-dire-detached-head-state"><strong>Cosa vuol dire detached HEAD state?</strong></h2><p>Effettuare il checkout di uno specifico commit ti pone in un cosiddetto "<strong>detached HEAD state</strong>" (stato HEAD separato).</p><p><a href="http://git-scm.com/docs/git-checkout#_detached_head">Dalla documentazione:</a></p><blockquote><em><em>[</em>detached HEAD state<em>] </em>significa semplicemente che <em><code>HEAD</code> </em>si riferisce a uno specifico commit, invece che riferirsi a un branch con un nome.</em></blockquote><p>Fondamentalmente, l'<code>HEAD</code> (uno dei puntatoti interni di Git che rileva dove ci si trova nella cronologia di Git) risulta separato dai branch conosciuti, così le modifiche, da questo punto, formeranno un nuovo percorso nella cronologia di Git.</p><p>Git vuole assicurarsi che questo stato HEAD separato sia quello che realmente vuoi ottenere, pertanto ti fornisce uno "spazio libero" per ogni sorta di modifica sperimentale - come descritto nell'output:</p><pre><code>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 switching back to a branch.
</code></pre><p>Traduzione: "<em>Sei in uno 'stato HEAD separato'. Puoi dare un'occhiata in giro, fare cambiamenti sperimentali e salvarli in commit, e puoi cancellare qualsiasi commit che hai fatto in questo stato, senza alcun impatto sui branch, tornando indietro su un branch esistente</em>"</p><p>Da questo posizione hai due opzioni:</p><ul><li>Sperimentare e poi buttare via le tue modifiche tornato al branch precedente</li><li>Lavorare da qui ed iniziare un nuovo branch da questo punto</li></ul><p>Puoi usare il comando &nbsp;<code>git switch -</code> per annullare qualsiasi modifica che hai apportato e tornare al tuo branch precedente.</p><p>Se invece vuoi mantenere i tuoi cambiamenti e continuare da qui, puoi usare il comando <code>git switch -c &lt;nome-nuovo-branch&gt;</code> per <em>creare un nuovo branch</em> da questo punto.</p><h2 id="conclusioni"><strong>Conclusioni</strong></h2><p>Il comando <code>git checkout</code> è utile e ha molteplici usi.</p><p>Puoi usarlo per creare nuovi branch, spostarti su un branch, eseguire il checkout di uno specifico commit, e molto altro.</p><p>Se ti è piaciuto questo tutorial, parlo di argomenti come questi <a href="https://twitter.com/johnmosesman">su Twitter</a> e ne scrivo <a href="https://johnmosesman.com/">sul mio sito.</a></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Annullare il merge in Git – Come annullare l'ultimo commit di merge in Git ]]>
                </title>
                <description>
                    <![CDATA[ Il Branching (la ramificazione dello sviluppo di un progetto) è una parte essenziale di Git, in quanto ti permette di lavorare senza manomettere il codice già in produzione. Quando finisci di lavorare con un branch diverso da main, vuoi unirlo con il ramo main con un commit di merge,  in ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/annullare-il-merge-in-git-come-annullare-lultimo-commit-di-merge-in-git/</link>
                <guid isPermaLink="false">671fcfb09ae93404d06943d8</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Andrea Sisti ]]>
                </dc:creator>
                <pubDate>Tue, 29 Oct 2024 14:43:57 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2024/10/puppy-g3ddb72a98_1920.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/git-undo-merge-how-to-revert-the-last-merge-commit-in-git/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Git Undo Merge – How to Revert the Last Merge Commit in Git</a>
      </p><p>Il Branching (la ramificazione dello sviluppo di un progetto) è una parte essenziale di Git, in quanto ti permette di lavorare senza manomettere il codice già in produzione.</p><p>Quando finisci di lavorare con un branch diverso da <code>main</code>, vuoi unirlo con il ramo <code>main</code> con un commit di <em>merge</em>, &nbsp;in modo che le nuove feature o i bug risolti che hai appena inserito diventino effettivi e possano essere mostrati.</p><p>Ma cosa succede se finisci di effettuare il <em>merge </em>e ti accorgi di aver dimenticato di fare una cosa? Oppure cosa succede se accidentalmente effettui il <em>merge </em>quando non sei ancora pronto?</p><p>Puoi annullare quasi qualsiasi azione in Git. Così, in questo articolo, ti mostrerò come annullare un <em>merge </em>in Git, in modo da ripristinare la situazione precedente all'ultimo commit che hai effettuato.</p><h2 id="come-annullare-un-commit-di-merge-in-git"><strong>Come annullare un commit di merge in Git</strong></h2><p>Puoi usare il comando Git reset per annullare un <em>merge</em>.</p><p>Come prima cosa, è necessario controllare l'hash (o id) del commit, da usare per tornare al commit precedente.</p><p>Per controllare l'hash, usa il comando <code>git log</code> oppure <code>git reflog</code>. <code>git reflog</code> è una opzione migliore perché le informazioni sono più leggibili con questo comando.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/03/ss1-2.png" class="kg-image" alt="ss1-2" width="600" height="400" loading="lazy"></figure><p>Quando ottieni l'hash del commit a cui vuoi tornare, lancia <code>git reset --hard commit-prima-del-merge</code>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/03/ss-2-5.png" class="kg-image" alt="ss-2-5" width="600" height="400" loading="lazy"></figure><p>Dovresti vedere alcuni elementi essere rimossi dal tuo editor di codice quando lanci il comando.</p><p>Se non sei sicuro dell'hash dell'ultimo commit, puoi lanciare il comando <code>git reset --hard HEAD~1</code> &nbsp;per tornare al commit precedente al merge:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/03/ss-3-3.png" class="kg-image" alt="ss-3-3" width="600" height="400" loading="lazy"></figure><p>Nota che quando utilizzi il flag &nbsp;<code>--hard</code> per annullare un merge, qualsiasi cambiamento non salvato in un commit viene annullato.</p><h2 id="un-modo-migliore-per-annullare-un-merge-in-git"><strong>Un modo migliore per annullare un merge in Git</strong></h2><p>Dato che i metodi discussi precedentemente annullano le modifiche non salvate in un commit, Git fornisce un flag più sicuro, denominato &nbsp;<code>--merge</code>.</p><p>Per annullare un merge con il flag &nbsp;<code>--merge</code>, lancia &nbsp;<code>git reflog</code> per vedere gli hash dei commit, quindi lancia &nbsp;<code>git reset --merge commit-precedente</code>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/03/ss4-1.png" class="kg-image" alt="ss4-1" width="600" height="400" loading="lazy"></figure><p>Si può anche usare la keyword HEAD con il flag &nbsp;<code>--merge</code> lanciando <code>git reset --merge HEAD~1</code>: </p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/03/ss5.png" class="kg-image" alt="ss5" width="600" height="400" loading="lazy"></figure><p><strong><strong>N.B.</strong></strong>: Se non ottieni una risposta da questo comando quando usi il flag &nbsp;<code>--merge</code>, non preoccuparti, funziona.</p><h2 id="conclusione"><strong>Conclusione</strong></h2><p>In questo articolo, hai imparato come annullare un merge in Git, e adesso potrai annullare un merge non voluto o errato e lavorare in Git con maggiore efficienza.</p><p>Qui ci sono i punti principali da tenere a mente con i flag &nbsp;<code>--hard</code> e <code>--merge</code> quando si usano per annullare un merge: il flag &nbsp;<code>--hard</code> rimuove le modifiche non salvate in un commit, mentre il flag &nbsp;<code>--merge</code> mantiene le modifiche non salvate in un commit.</p><p>Grazie per aver letto questo articolo!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Una Guida Visuale ai Meccanismi Interni di Git — Oggetti, Branch e Come Creare un Repository Da Zero ]]>
                </title>
                <description>
                    <![CDATA[ Molti di noi usano git quotidianamente. Ma quanti di noi sanno cosa succede dietro le quinte? Per esempio, cosa succede quando usiamo git commit? Cosa viene conservato dopo ogni commit? Sono solo le differenze tra il commit attuale e quello precedente? In questo caso come sono codificate le differenze? Oppure ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/una-guida-visuale-ai-meccanismi-interni-di-git/</link>
                <guid isPermaLink="false">64c2c2c17194960696cf26d9</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Roberto Pauletto ]]>
                </dc:creator>
                <pubDate>Mon, 28 Aug 2023 08:59:39 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/07/A-Visual-Guide-to-Git-Internals-Book-Cover--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/git-internals-objects-branches-create-repo/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">https://www.freecodecamp.org/news/git-internals-objects-branches-create-repo/</a>
      </p><p>Molti di noi usano <code>git</code> quotidianamente. Ma quanti di noi sanno cosa succede dietro le quinte?</p><p>Per esempio, cosa succede quando usiamo <code>git commit</code>? Cosa viene conservato dopo ogni commit? Sono solo le differenze tra il commit attuale e quello precedente? In questo caso come sono codificate le differenze? Oppure viene salvata un'istantanea del repository ogni volta? Cosa succede veramente quando usiamo <code>git init</code>?</p><p>Molti di coloro che usano <code>git</code> non conoscono le risposte alle domande poste qui sopra. Ma ha davvero importanza?</p><p>Innanzitutto, come professionisti, dovremmo impegnarci a capire gli strumenti che usiamo, specialmente così di frequente, come <code>git</code>.</p><p>Ma soprattutto, ho scoperto che capire come funziona effettivamente <code>git</code> è utile in molte situazioni, sia che si tratti di risolvere conflitti di merge, che si cerchi di eseguire un rebase interessante, o anche solo quando qualcosa va leggermente storto.</p><p>Potrai trarre vantaggio da questo post se hai già abbastanza esperienza con <code>git</code> per sentirti a tuo agio con comandi come <code>git pull</code> ,<code>git push</code> ,<code>git add</code> oppure <code>git commit</code>.</p><p>Ciononostante, inizieremo con uno sguardo d'insieme per essere sicuri di essere tutti allo stesso livello per quanto riguarda la conoscenza dei meccanismi di <code>git</code>, e in particolare con i termini che verranno usati in questo post.</p><p>Ho anche caricato su YouTube una serie che tratta degli argomenti trattati in questo post e che ti invito a guardare <a href="https://www.youtube.com/playlist?list=PL9lx0DXCC4BNUby5H58y6s2TQVLadV8v7" rel="noopener">qui</a>.</p><h2 id="cosa-aspettarsi-da-questo-tutorial">Cosa aspettarsi da questo tutorial</h2><p>Avremo una approfondita comprensione di ciò che accade dietro le quinte durante le operazioni che facciamo quasi quotidianamente con <code>git</code>.</p><p>Inizieremo trattando gli <strong>oggetti </strong>—  <strong>blob</strong>, <strong>tree</strong> <strong>(alberi)</strong> e <strong>commit</strong>. Discuteremo quindi brevemente dei <strong>branch</strong> e di come vengono implementati. Analizzeremo i dettagli della <strong>directory di lavoro</strong>, dell'<strong>area di stage</strong> e del <strong>repository</strong>.</p><p>Ci assicureremo anche di capire come questi termini si relazionano rispetto ai comandi <code>git</code> che conosciamo e utilizziamo per creare un nuovo repository.</p><p>Successivamente, creeremo un repository da zero , senza usare <code>git init</code>, <code>git add</code> o <code>git commit</code>. Questo ci consentirà di <strong>approfondire la nostra comprensione di ciò che avviene dietro le quinte </strong>quando lavoriamo con <code>git</code>.</p><p>Creeremo anche nuovi branch, ci sposteremo tra di essi e creeremo ulteriori commit, tutto senza usare <code>git branch</code> o <code>git checkout</code>.</p><p>Alla fine di questo post, <strong>ti sentirai di aver <em>capito</em> git</strong>. Sei pronto per farlo?😎</p><h2 id="oggetti-git-blob-alberi-tree-e-commit">Oggetti Git: blob, alberi (tree) e commit</h2><p>È molto utile pensare a <code>git</code> come alla gestione di un file system, e in particolare a "istantanee" di un file system in un dato momento.</p><p>Un file system inizia con una <em>directory radice</em> (root directory), nei sistemi basati su Unix, <code>/</code>, che in genere contiene altre directory (per esempio <code>/usr</code> o <code>/bin</code>). Queste directory possono contenere altre directory e/o file (per esempio <code>/usr/1.txt</code>).</p><p>In <code>git</code>, il contenuto dei file viene conservato in oggetti chiamati <strong><strong>blob</strong></strong> (binary large objects – grandi oggetti binari).</p><p>La differenza tra <strong><strong>blob</strong></strong> e file è che i file contengono anche metadati. Per esempio un file "ricorda" quando è stato creato, quindi se lo sposti in un'altra directory, la sua data di creazione rimane la stessa.</p><p>I<strong> b<strong>lob</strong></strong>, diversamente, hanno solo contenuto, flussi binari di dati. Un <strong>blob </strong>non registra la sua data di creazione, il suo nome o qualsiasi altra cosa diversa dal suo contenuto.</p><p>Ogni <strong><strong>blob</strong> </strong>in <code>git</code> viene identificato dal suo <a href="https://en.wikipedia.org/wiki/SHA-1" rel="noopener">hash SHA-1</a>. Gli hash SHA-1 sono di 20 byte e rappresentano in genere 40 caratteri in formato esadecimale. In questo post talvolta mostreremo solo i primi caratteri di questo hash.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-34.png" class="kg-image" alt="Blobs have SHA-1 hashes associated with them" width="600" height="400" loading="lazy"></figure><p>In <code>git</code>, l'equivalente di una directory è un <strong>albero</strong> (<strong><strong>tree</strong>)</strong>. Un albero in pratica è un elenco del contenuto di una directory, che può essere costituito da dei <strong>blob</strong> così come da altri <strong>alberi</strong>.</p><p>Anche gli <strong>alberi</strong> sono identificati dal loro hash SHA-1. Per riferirsi a questi oggetti, siano blob o alberi, si usa il loro hash SHA-1.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-35.png" class="kg-image" alt="A tree is a directory listing" width="600" height="400" loading="lazy"></figure><p>Osserva l'<strong>albero</strong> <strong><strong>CAFE7 </strong></strong>che &nbsp;contiene il &nbsp;<strong><strong>blob F92A0</strong></strong> che rappresenta <em><em>pic.png. </em></em>In un altro <strong>albero</strong>, quello stesso <strong><strong>blob </strong></strong>potrebbe avere un altro nome.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-36.png" class="kg-image" alt="A tree may contain sub-trees, as well as blobs" width="600" height="400" loading="lazy"></figure><p>Il diagramma qui sopra equivale a un file system con una directory radice che ha un file, <code>/test.js</code>, e una directory chiamata <code>/docs</code> nella quale ci sono due file: <code>/docs/pic.png</code> e <code>/docs/1.txt</code>.</p><p>Ora è tempo di prendere un'istantanea di quel file system e conservare tutti i file al momento esistenti, assieme al loro contenuto.</p><p>In <code>git</code>, un'istantanea è un <strong><strong>commit</strong></strong>. Un oggetto <strong><strong>commit</strong></strong> include un puntatore all'<strong>albero</strong> principale (la directory radice), e anche altri metadati come il l'esecutore del commit (<strong><strong>committer</strong></strong>), un <strong>messaggio </strong>di commit<strong>, </strong>e la <strong>marca temporale</strong> del commit.</p><p>In molti casi, un <strong><strong>commit</strong></strong> ha anche uno o più <strong><strong>commit</strong> </strong>genitori, vale a dire le istantanee precedenti. Naturalmente anche gli oggetti <strong><strong>commit</strong></strong> sono identificati dal loro hash SHA-1. Questi sono gli hash mostrati quando usiamo <code>git log</code>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-37.png" class="kg-image" alt="A commit is a snapshot in time. It refers to the root tree. As this is the first commit, it has no parent(s)." width="600" height="400" loading="lazy"></figure><p>Ogni <strong><strong>commit </strong></strong>contiene l'<em>intera istantanea, </em>non solo le differenze rispetto ai <strong>commit</strong> precedenti.</p><p>Come può funzionare? Non significa che dovremo conservare un gran volume di dati ad ogni commit?</p><p>Esaminiamo cosa succede se modifichiamo il contenuto di un file. Diciamo che vogliamo modificare <code>1.txt</code>, aggiungendo un punto esclamativo, cioè modifichiamo il contenuto da <code>HELLO WORLD</code> a <code>HELLO WORLD!</code>.</p><p>Bene, questa modifica significa avere un nuovo <strong>blob</strong>, con un nuovo hash SHA-1. Ha senso, visto che <code>sha1("HELLO WORLD")</code> è diverso da <code>sha1("HELLO WORLD!")</code>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-38.png" class="kg-image" alt="Changing the blob results in a new SHA-1" width="600" height="400" loading="lazy"></figure><p>Poiché abbiamo un nuovo hash, allora anche il contenuto dell'<strong>albero</strong> dovrebbe cambiare, dopo tutto il nostro <strong>albero</strong> non punta più al <strong><strong>blob 73D8A</strong></strong>, ma al <strong><strong>blob 62E7A</strong></strong> . Quando modifichiamo il contenuto di un <strong>albero </strong>cambiamo anche il suo hash.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-39.png" class="kg-image" alt="image-39" width="600" height="400" loading="lazy"><figcaption>L'albero che punta al blob modificato deve essere modificato a sua volta</figcaption></figure><p>Ora, visto che l'hash dell'<strong>albero</strong> è diverso, dobbiamo cambiare anche l'<strong>albero</strong> genitore, visto che non punta più all'<strong>albero<strong><strong><strong> CAFE7</strong></strong></strong></strong>, ma all'<strong>albero<strong><strong><strong> 24601</strong></strong></strong></strong>.<strong><strong><strong><strong> </strong></strong></strong></strong>Ne consegue che anche l'<strong>albero genitore</strong> avrà un nuovo hash.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-40.png" class="kg-image" alt="The root tree also changes, and so does its hash." width="600" height="400" loading="lazy"></figure><p>Siamo quasi pronti per creare un nuovo oggetto <strong><strong>commit</strong></strong>, e sembra che andremo a salvare un gran volume di dati, l'intero file system, ancora una volta! È davvero necessario?</p><p>In realtà, alcuni oggetti, <strong><strong>blob</strong></strong> nello specifico, non sono cambiati rispetto al commit precedente, il  <strong><strong>blob F92A0 </strong></strong>è rimasto invariato, e anche il &nbsp;<strong><strong>blob F00D1.</strong></strong></p><p>Ecco il trucco, fintanto che un oggetto non cambia, non lo salviamo nuovamente. In questo caso non dobbiamo salvare nuovamente i <strong><strong>blob F92A0 </strong></strong>e<strong><strong> blob F00D1</strong>. </strong>Dobbiamo solo riferirci a essi usando i loro valori di hash. Quindi possiamo creare il nostro oggetto <strong><strong>commit</strong></strong>.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-41.png" class="kg-image" alt="image-41" width="600" height="400" loading="lazy"><figcaption>I blob che non cambiano sono referenziati tramite i loro valori hash</figcaption></figure><p>Visto che questo <strong><strong>commit</strong></strong> non è il primo <strong><strong>commit</strong></strong>, ha un genitore, il  <strong><strong>commit A1337</strong></strong>.</p><h4 id="per-ricapitolare-abbiamo-introdotto-tre-oggetti-git-"><strong>Per ricapitolare, abbiamo introdotto tre oggetti git:</strong></h4><ul><li><strong><strong>blob — </strong></strong>il contenuto di un file.</li><li><strong><strong>tree</strong> (albero) <strong> </strong></strong>— il contenuto di una directory (di <strong><strong>blob</strong></strong> e <strong>alberi</strong>).</li><li><strong><strong>commit </strong></strong>— un'istantanea dell'albero di lavoro.</li></ul><p>Prendiamo un attimo in considerazione gli hash di questi oggetti. Supponiamo che io abbia scritto la stringa <code>git is awesome!</code> e da essa abbia creato un <strong><strong>blob</strong>. </strong>Tu hai fatto lo stesso sul tuo sistema. Avremo lo stesso hash?</p><p>La risposta è  sì. Visto che i <strong><strong>blob</strong></strong> contengono gli stessi dati, avranno gli stessi valori di hash SHA-1.</p><p>Cosa succede se io creo un <strong>albero</strong> che fa riferimento al <strong><strong>blob </strong></strong> <code>git is awesome!</code>, e gli do nome e metadati specifici, e tu fai esattamente la stessa cosa sul tuo sistema. Avremo lo stesso hash?</p><p>Ancora una volta la risposta è sì. Visto che gli oggetti <strong>alberi</strong> sono uguali, avranno lo stesso hash.</p><p>Se creo un <strong><strong>commit</strong></strong> di quell'<strong>albero<strong> </strong></strong>con il messaggio di commit <code>Hello</code>, e tu fai lo stesso nel tuo file system. Avremo gli stessi hash?</p><p>In questo caso la risposta è negativa. Anche se i nostri oggetti <strong>commit</strong> fanno riferimento allo stesso <strong>albero</strong>, hanno dettagli di <strong>commit</strong> diversi, la marca temporale, l'esecutore del commit, e così via.</p><h2 id="branch-in-git">Branch in Git</h2><p><strong>Un<strong> branch</strong> (ramo) è semplicemente un riferimento nominativo a un <strong>commit</strong></strong>.</p><p>Possiamo sempre fare riferimento a un <strong>commit</strong> in git tramite il suo hash SHA-1, ma noi umani in genere preferiamo altri modi per denominare gli oggetti. Un <strong>branch</strong> è un modo di referenziare un <strong>commit</strong>, ma è semplicemente questo.</p><p>Nella maggior parte dei repository, la linea principale di sviluppo viene implementata in un branch chiamato <code>master</code>. È semplicemente un nome, creato quando usiamo <code>git init</code>, pertanto largamente usato. Tuttavia non riveste un significato particolare, e si potrebbe usare un qualsiasi altro nome ci vada a genio.</p><p>Tipicamente, il branch punta all'ultimo <strong>commit</strong> nella linea di sviluppo sulla quale stiamo attualmente lavorando.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-42.png" class="kg-image" alt="A branch is just a named reference to a commit" width="600" height="400" loading="lazy"></figure><p>Per creare un altro branch, in genere usiamo il comando <code>git branch</code>. Facendo questo creiamo in realtà un altro puntatore. Quindi se creiamo un branch chiamato <code>test</code>, usando il comando <code>git branch test</code>, stiamo in realtà creando un altro puntatore direzionato verso lo stesso <strong>commit</strong> del branch nel quale ci troviamo attualmente.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-43.png" class="kg-image" alt="image-43" width="600" height="400" loading="lazy"><figcaption>Usando <code>git branch</code> si crea un altro puntatore</figcaption></figure><p>Come fa <code>git</code> a sapere su quale branch ci troviamo attualmente? Mantiene un puntatore speciale, detto <code>HEAD</code>. In genere <code>HEAD</code> punta a un branch, che a sua volta punta a un <strong>commit</strong>. In alcuni casi, <code>HEAD</code> può anche puntare direttamente a un <strong>commit</strong>, ma non ci focalizzeremo su questo.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-44.png" class="kg-image" alt="image-44" width="600" height="400" loading="lazy"><figcaption><code>HEAD</code> punta al branch nel quale ci troviamo attualmente.</figcaption></figure><p>Per rendere attivo il branch <code>test</code>, possiamo usare il comando <code>git checkout test</code>. Possiamo già indovinare cosa fa questo comando in realtà: cambia semplicemente il puntamento di <code>HEAD</code> verso <code>test</code>.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-45.png" class="kg-image" alt="image-45" width="600" height="400" loading="lazy"><figcaption><code>git checkout test</code> modfiica il puntamento di <code>HEAD</code></figcaption></figure><p>Possiamo anche usare &nbsp;<code>git checkout -b test</code> prima di creare il branch <code>test</code>, che equivale a eseguire <code>git checkout test</code>, per far puntare <code>HEAD</code> al nuovo branch.</p><p>Cosa succede se eseguiamo qualche modifica e creiamo un nuovo <strong>commit</strong> con <code>git commit</code>? A quale branch verrà aggiunto il nuovo &nbsp;<strong><strong>commit</strong></strong>?</p><p>La risposta è il branch <code>test</code>, visto che è il branch attivo (quello su cui punta <code>HEAD</code>). Successivamente, il puntatore di <code>test</code> verrà spostato verso il nuovo <strong>commit</strong> aggiunto. Nota che <code>HEAD</code> punta ancora a <code>test</code>.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-46.png" class="kg-image" alt="image-46" width="600" height="400" loading="lazy"><figcaption>Ogni volta che usiamo <code>git commit</code>, il puntatore del branch si sposta verso il nuovo commit creato.</figcaption></figure><p>Quindi se riattiviamo <code>master</code> eseguendo <code>git checkout master</code>, facciamo in modo che <code>HEAD</code> punti nuovamente a <code>master</code> .</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-47.png" class="kg-image" alt="image-47" width="600" height="400" loading="lazy"></figure><p>Ora se creiamo un altro <strong><strong>commit</strong></strong>, verrà aggiunto al branch <code>master</code> (e il suo genitore sarà il <strong><strong>commit B2424</strong></strong>).</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-48.png" class="kg-image" alt="image-48" width="600" height="400" loading="lazy"></figure><h2 id="come-registrare-le-modifiche-in-git">Come registrare le modifiche in Git</h2><p>In genere, quando lavoriamo sul nostro codice, lo facciamo da <strong>una directory di lavoro</strong> (<strong>working dir</strong>). Una <strong>directory di lavoro</strong> o <strong>albero di lavoro</strong>, è una qualsiasi directory nel nostro file system che ha un <strong>repository</strong> associato. Contiene le cartelle e i file del nostro progetto, e una directory chiamata <code>.git</code>, che esamineremo più approfonditamente in seguito.</p><p>Dopo aver fatto alcune modifiche, vogliamo registrarle nel nostro <strong>repository</strong>. Un <strong>repository</strong> (<strong>repo</strong> in breve) è una collezione di <strong>commit</strong>, ciascuno dei quali rappresenta un archivio di quello che era l'<strong>albero di lavoro</strong> in una data precedente, sia sulla nostra macchina che su quella di qualcun altro.</p><p>Un <strong>r<strong>epository </strong></strong>include anche altre cose oltre ai nostri file che contengono il codice, come &nbsp;<code>HEAD</code>, branch, e così via.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-49.png" class="kg-image" alt="image-49" width="600" height="400" loading="lazy"></figure><p>A differenza di altri strumenti simili che potresti avere usato, <code>git</code> non inserisce le modifiche effettuate dall'<strong>albero di lavoro</strong> direttamente nel <strong>repository</strong>. Viceversa le modifiche sono prima registrate in qualcosa chiamato <strong>indice</strong> (<strong>index</strong>) o <strong>area di stage</strong> (<strong>staging area</strong>).</p><p>Entrambi questi termini fanno riferimento alla stessa cosa e sono spesso usati nella documentazione di <code>git</code>. Useremo questi termini in modo intercambiabile all'interno di questo post.</p><p>Quando attiviamo (<code>checkout</code>) un branch, <code>git</code> popola l'<strong>indice</strong> con tutti i contenuti dei file che erano presenti l'ultima volta nella nostra <strong>directory di lavoro</strong> e come apparivano quando sono stati originariamente verificati. Quando usiamo <code>git commit</code>, il <strong>commit</strong> viene creato in base allo stato dell'<strong>indice</strong>.</p><p>L'uso dell'<strong>indice</strong> ci consente di preparare con cura ogni commit. Per esempio potremmo avere due file con modifiche rispetto al nostro ultimo commit nella nostra <strong>directory di lavoro</strong>. Potremmo volere aggiungere solo uno di essi all'<strong>indice</strong> (usando <code>git add</code>), quindi usare <code>git commit</code> per registrare solo quelle modifiche.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-50.png" class="kg-image" alt="image-50" width="600" height="400" loading="lazy"></figure><p>I file nella nostra <strong>directory di lavoro</strong> possono trovarsi in uno di due stati: <strong>tracciato (tracked)</strong> o <strong>non tracciato (untracked)</strong>.</p><p>I file<strong> tracciati </strong>sono quelli che <code>git</code> conosce. Potrebbero trovarsi nell'ultima istantanea (<strong>commit) </strong>oppure essere stati portati nell<strong>'area di stage </strong>adesso.</p><p>I file<strong> non tracciati</strong>, sono tutto il resto, qualunque file o directory nella nostra <strong>directory di lavoro</strong> che non compariva nella nostra ultima istantanea (<strong>commit</strong>) e che non si trova attualmente nell<strong>'area di stage</strong>.</p><h2 id="come-creare-un-repository-nel-modo-convenzionale">Come creare un repository nel modo convenzionale</h2><p>Assicuriamoci di capire in che modo i termini che abbiamo introdotto si riferiscono al procedimento di creazione di un <strong>repository</strong>. Questa è solo una rapida panoramica di alto livello, prima di immergerci molto più a fondo in questo processo.</p><p><strong>Nota</strong>:  la maggior parte delle videate con i comandi di shell mostra i comandi UNIX. Fornirò comandi sia per Windows che per UNIX, con schermate da Windows, per coprire i sistemi operativi più diffusi. Quando i comandi saranno esattamente gli stessi, li fornirò solo una volta.</p><p>Inizializzeremo un nuovo <strong>repository</strong> usando <code>git init repo_1</code>, quindi ci sposteremo nella directory di quel repository usando <code>cd repo_1</code>. Digitando <code>tree /f .git</code> possiamo vedere che l'esecuzione di <code>git init</code> ha prodotto parecchie sottodirectory all'interno di <code>.git</code>. (L'opzione del comando tree &nbsp;<code>/f</code> include anche i file nel risultato dell'esecuzione del comando).</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-51.png" class="kg-image" alt="image-51" width="600" height="400" loading="lazy"></figure><p>Creiamo un file all'interno della directory <code>repo_1</code> (versione Windows):</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-52.png" class="kg-image" alt="image-52" width="600" height="400" loading="lazy"></figure><p>Sui sistemi Linux e macOS:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-53.png" class="kg-image" alt="image-53" width="600" height="400" loading="lazy"></figure><p>Questo file si trova all'interno della nostra <strong>directory di lavoro</strong>. Tuttavia, visto che non è ancora stato inserito nell'<strong>area di stage</strong>, attualmente risulta <strong>non tracciato</strong> (<strong>untracked</strong>). Verifichiamolo con il comando <code>git status</code>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-54.png" class="kg-image" alt="image-54" width="600" height="400" loading="lazy"><figcaption>Il nuovo file non è tracciato visto che non è stato ancora inserito nell'area di stage, e non era compreso in un precedente commit</figcaption></figure><p>Ora possiamo aggiungere questo file all'<strong>area di stage</strong> con il comando <code>git add new_file.txt</code>. Possiamo verificare che il file si trova nell'<strong>area di stage</strong> eseguendo <code>git status</code>:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-55.png" class="kg-image" alt="image-55" width="600" height="400" loading="lazy"><figcaption>Aggiunto un nuovo file nell'area di stage</figcaption></figure><p>Ora possiamo creare un <strong>commit</strong> con <code>git commit</code>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-56.png" class="kg-image" alt="image-56" width="600" height="400" loading="lazy"></figure><p>È cambiato qualcosa nella directory <code>.git</code>? Eseguiamo <code>tree /f .git</code> per verificare:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-57.png" class="kg-image" alt="image-57" width="600" height="400" loading="lazy"><figcaption>Sono cambiate molte cose all'interno di <code>.git</code></figcaption></figure><p>Sembra che siano cambiate parecchie cose. È ora di esaminare approfonditamente la struttura di <code>.git</code> e capire cosa succede dietro le quinte quando eseguiamo <code>git init</code>, <code>git add</code> oppure <code>git commit</code>.</p><h2 id="ora-di-andare-alle-fondamenta">Ora di andare alle fondamenta</h2><p>Fino ad ora abbiamo trattato alcuni degli aspetti base di Git, ora siamo pronti per andare davvero a fondo. </p><p>Per capire a fondo come funziona <code>git</code>, dovremo creare un <strong>repository</strong>, questa volta però lo faremo partendo da zero.</p><p>Non useremo <code>git init</code>, <code>git add</code> o <code>git commit</code>, il che ci consentirà di ottenere una migliore comprensione pratica del procedimento.</p><h2 id="come-impostare-git">Come impostare <code>.git</code></h2><p>Creiamo una nuova directory, portiamoci all'interno di essa ed eseguiamo <code>git status</code>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-106.png" class="kg-image" alt="image-106" width="600" height="400" loading="lazy"></figure><p>Va bene, <code>git</code> non sembra contento visto che non ha trovato nessuna cartella <code>.git</code>. La cosa naturale da fare sarebbe semplicemente crearla, poi rieseguire <code>git status</code>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-107.png" class="kg-image" alt="image-107" width="600" height="400" loading="lazy"></figure><p>Apparentemente, non è sufficiente creare una cartella <code>.git</code> . Ci serve qualche cosa da immettere in quella directory.</p><p><strong>Un<strong><strong><strong> repository </strong></strong></strong>git ha due componenti principali</strong>:</p><ol><li>Una collezione di oggetti — <strong><strong><strong><strong>blob</strong></strong></strong></strong>, <strong>alberi<strong><strong><strong>,</strong></strong></strong></strong> e <strong><strong><strong><strong>commit</strong></strong></strong></strong>.</li><li>Un sistema di denominazione di quegli oggetti, o <strong>riferimenti (references)</strong>.</li></ol><p>Un <strong><strong><strong><strong>repository</strong></strong></strong></strong> potrebbe anche contenere altre cose, come gli hook di git, ma come minimo deve includere oggetti e riferimenti.</p><p>Creiamo quindi una directory per gli oggetti, <code>.git\objects</code> e una per i riferimenti, &nbsp;<code>.git\refs</code> (sui sistemi UNIX <code>.git/objects</code> e <code>.git/refs</code>, rispettivamente).</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-108.png" class="kg-image" alt="image-108" width="600" height="400" loading="lazy"></figure><p>Un tipo di riferimento sono i branch. Internamente, <code>git</code> chiama i branch con il nome head. Quindi andremo a creare una directory apposita, <code>.git\refs\heads</code>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-109.png" class="kg-image" alt="image-109" width="600" height="400" loading="lazy"></figure><p>Lo stato non cambia ancora eseguendo <code>git status</code>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-110.png" class="kg-image" alt="image-110" width="600" height="400" loading="lazy"></figure><p>Come fa <code>git</code> a sapere dove iniziare a cercare un <strong>commit</strong> nel <strong>repository</strong>? Come spiegato in precedenza, cerca <code>HEAD</code>, che punta al branch attivo corrente (o <strong>commit</strong> in taluni casi).</p><p>Quindi dobbiamo creare <code>HEAD</code>, che è semplicemente un file che si trova in <code>./git/HEAD</code>. Per farlo eseguiamo:</p><p>Su Windows: <code>&gt; echo ref: refs/heads/master &gt; .git\HEAD</code></p><p>Su sistemi UNIX: <code>$ echo "ref: refs/heads/master" &gt; .git/HEAD</code></p><p>⭐ Adesso sappiamo come viene implementato <code>HEAD</code>, è semplicemente un file e il suo contenuto descrive verso quale oggetto puntare.</p><p>Dopo l'esecuzione dei comandi qui sopra, <code>git status</code> sembra cambiare idea:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-111.png" class="kg-image" alt="image-111" width="600" height="400" loading="lazy"><figcaption>HEAD è semplicemente un file</figcaption></figure><p>Ora <code>git</code> crede che siamo nel branch chiamato <code>master</code>, anche se non abbiamo creato questo branch. Come detto prima, &nbsp;<code>master</code> è solo un nome. Avremmo potuto far credere a &nbsp;<code>git</code> di essere su un branch chiamato <code>banana</code> se avessimo voluto:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-112.png" class="kg-image" alt="image-112" width="600" height="400" loading="lazy"><figcaption>🍌</figcaption></figure><p>Per il resto di questo post torneremo a <code>master</code>, semplicemente per conformarci alla normale convenzione.</p><p>Ora che la nostra directory <code>.git</code> è pronta, possiamo iniziare le operazioni per creare un <strong>commit</strong> (come già detto, senza usare <code>git add</code> oppure <code>git commit</code>).</p><h2 id="i-comandi-in-git-idraulica-vs-ceramica">I comandi in Git, idraulica vs. ceramica</h2><p>A questo punto sarebbe utile fare una distinzione tra due tipi di comando in <code>git</code>: idraulici e in ceramica. La definizione è presa in prestito da termini usati dagli idraulici quando si parla di tazza (già, questa — 🚽), che tradizionalmente è fatta di ceramica mentre l'infrastruttura (tubi e scarichi) costituisce l'idraulica.</p><p>Mantenendo l'analogia, possiamo dire che la ceramica fornisce all'utente un'interfaccia amichevole per accedere a tubature e scarichi. La maggior parte delle persone ha a che fare con la ceramica. Tuttavia, quando succede qualcosa di veramente brutto, e qualcuno vuole capirne il motivo, deve rimboccarsi le maniche e controllare le tubature e gli scarichi. (Nota: questi termini non sono miei, sono usati in modo estensivo in <code>git</code>).</p><p><code>git</code> usa questa terminologia come analogia per distinguere i comandi di basso livello che in genere gli utenti non usano direttamente (i comandi idraulici che agiscono su tubi e scarichi) dai comandi di alto livello più amichevoli per gli utenti (comandi in ceramica).</p><p>Fino a ora abbiamo avuto a che fare con i comandi in ceramica, <code>git init</code>, <code>git add</code> o <code>git commit</code>. Di seguito passeremo ai comandi idraulici.</p><h2 id="come-creare-oggetti-in-git">Come creare oggetti in Git</h2><p>Partiamo creando un oggetto e scrivendolo nel database degli oggetti di <code>git</code>, che si trova in <code>.git\objects</code>. Troveremo un valore di hash SHA-1 per un <strong><strong><strong><strong>blob</strong></strong></strong></strong> usando il nostro primo comando di basso livello (idraulico), <code>git hash-object</code>, in questo modo:</p><p>Su Windows:</p><p><code>&gt; echo git is awesome | git hash-object --stdin</code></p><p>Su sistemi UNIX:</p><p><code>$ echo "git is awesome" | git hash-object --stdin</code></p><p>Usando <code>--stdin</code> diciamo a <code>git hash-object</code> di prendere i suoi dati dallo standard input. Questo ci fornirà il relativo valore hash valido.</p><p>Per scrivere effettivamente quel <strong>blob</strong> nel database degli oggetti di <code>git</code> possiamo semplicemente aggiungere l'opzione <code>-w</code> a <code>git hash-object</code>. Successivamente possiamo verificare il contenuto della cartella <code>.git</code> e vedere cosa è cambiato.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-113.png" class="kg-image" alt="image-113" width="600" height="400" loading="lazy"><figcaption>Scrittura di un blob nel database degli oggetti</figcaption></figure><p>Adesso possiamo vedere che l'hash del nostro <strong>blob</strong> è <code>54f6...36</code>. Possiamo anche vedere che è stata creata una sottodirectory in <code>.git\objects</code> chiamata <code>54</code>, il file è stato chiamato <code>f6...36</code>.</p><p>Quindi <code>git</code> in realtà prende i primi due caratteri dell'hash SHA-1 e li usa come nome di una directory. I restanti caratteri dell'hash vengono usati come nome del file che contiene il <strong><strong><strong><strong>blob</strong></strong></strong></strong>.</p><p>Come mai? Immagina un repository piuttosto grande, uno che abbia 300.000 oggetti (<strong><strong><strong><strong>blob</strong></strong></strong></strong>, <strong>alberi</strong>, e <strong><strong><strong><strong>commit</strong></strong></strong></strong>) nel suo database. Può servire molto tempo per cercare un hash in una lista di 300.000 elementi. Per questo <code>git</code> divide semplicemente il problema per 256.</p><p>Per cercare l'hash qui sopra, <code>git</code> per prima cosa cerca una directory chiamata <code>54</code> all'interno di <code>.git\objects</code>, che potrebbe avere fino a 256 directory (da <code>00</code> a <code>FF</code>). Poi cerca in quella directory, restringendo la ricerca mano a mano che la stessa progredisce.</p><p>Torniamo al nostro procedimento per generare un <strong>commit</strong>. Ora che abbiamo creato un oggetto, di che tipo è? Possiamo usare un altro comando di basso livello, <code>git cat-file -t</code> (<code>-t</code> sta per “tipo”), per verificarlo:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-114.png" class="kg-image" alt="image-114" width="600" height="400" loading="lazy"></figure><p>Non c'è da sorprendersi, questo oggetto è un <strong><strong><strong><strong>blob</strong></strong></strong></strong>. Possiamo anche usare &nbsp;<code>git cat-file -p</code> (<code>-p</code> sta per “pretty-print” - bella stampa) per vederne il contenuto:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-115.png" class="kg-image" alt="image-115" width="600" height="400" loading="lazy"></figure><p>Il procedimento di creazione di un <strong>blob</strong> in genere si verifica quando aggiungiamo qualcosa nell'<strong>area di stage</strong>, vale a dire quando usiamo <code>git add</code>.</p><p>Ricorda che <code>git</code> crea un <strong><strong><strong><strong>blob</strong></strong></strong></strong> dell'<em>intero</em> file portato in area di stage. Anche se viene modificato un solo carattere (come nell'esempio di prima quando abbiamo aggiunto un <code>!</code>), il file avrà un nuovo <strong><strong><strong><strong>blob </strong></strong></strong></strong>con un nuovo <strong><strong><strong><strong>hash</strong></strong></strong></strong>.</p><p>Vedremo modifiche se verifichiamo lo stato del repository usando <code>git status</code>?</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-116.png" class="kg-image" alt="image-116" width="600" height="400" loading="lazy"></figure><p>Apparentemente no. Aggiungere un oggetto <strong>blob</strong> al database interno di <code>git</code> non modifica lo stato, visto che <code>git</code> non sa in questa fase quali file siano tracciati o meno.</p><p>Dobbiamo tracciare questo file, aggiungendolo all'<strong>area di stage</strong>. A questo scopo possiamo usare il comando di basso livello <code>git update-index</code>, così: <code>git update-index --add --cacheinfo 100644 &lt;blob-hash&gt; &lt;nomefile&gt;</code>.</p><p>Nota: <code>cacheinfo</code> è un file in modalità 16-bit <a href="https://github.com/git/git/blob/master/Documentation/technical/index-format.txt" rel="noopener nofollow">conservato da git</a>, seguendo le direttive di <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html" rel="noopener nofollow">tipi e modalità POSIX</a>. Questo va oltre lo scopo di questo post.</p><p>Eseguendo il comando qui sopra otterremo una modifica nel contenuto di <code>.git</code>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-117.png" class="kg-image" alt="image-117" width="600" height="400" loading="lazy"></figure><p>Riesci a identificare le modifiche? È stato creato un nuovo file chiamato <code>index</code> . Eccolo, il famoso <strong><strong><strong><strong>ind</strong></strong></strong>ice</strong> (o <strong>area di stage</strong>), è praticamente un file che si trova nella directory <code>.git</code>.</p><p>Adesso che il nostro <strong><strong><strong><strong>blob</strong></strong></strong></strong> è stato aggiunto all'<strong>indice</strong>, ci aspettiamo che il risultato di <code>git status</code> sia diverso, come questo:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-118.png" class="kg-image" alt="image-118" width="600" height="400" loading="lazy"></figure><p>Interessante! Sono successe due cose.</p><p>La prima, possiamo vedere che <code>my_file.txt</code> è visualizzato in verde nella sezione <code>Changes to be committed</code> (modifiche da portare in commit). Questo perché l'<strong>indice</strong> ora contiene <code>my_file.txt</code>, in attesa di essere portato in un commit.</p><p>La seconda, osserviamo che <code>my_file.txt</code> viene visualizzato in rosso, poiché <code>git</code> crede che <code>my_file.txt</code> sia stato eliminato e il fatto che il file sia stato eliminato non è stato registrato in <strong>area di stage</strong>.</p><p>Questo succede in quanto abbiamo aggiunto un <strong>blob</strong> con il contenuto <code>git is awesome</code> al database degli oggetti, e abbiamo detto all'<strong>indice </strong>che <code>my_file.txt</code> ha il contenuto di quel &nbsp;<strong><strong><strong><strong>blob</strong></strong></strong></strong>, ma in realtà non abbiamo mai veramente creato quel file.</p><p>Possiamo facilmente risolvere prendendo il contenuto del <strong>blob</strong> e scrivendolo nel nostro file system, in un file chiamato <code>my_file.txt</code>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-119.png" class="kg-image" alt="image-119" width="600" height="400" loading="lazy"></figure><p>Ne consegue che <code>my_file.txt</code> non appare più in rosso nel risultato di &nbsp;<code>git status</code>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-120.png" class="kg-image" alt="image-120" width="600" height="400" loading="lazy"></figure><p>È ora di creare un oggetto <strong>commit </strong>dalla nostra <strong>area di stage</strong>. Come spiegato sopra, un oggetto <strong>commit</strong> ha un riferimento a un <strong>albero</strong>, quindi dobbiamo crearlo.</p><p>Lo possiamo fare con il comando <code>git write-tree</code>, che registra il contenuto dell'<strong>indice</strong> in un oggetto <strong>albero</strong>. Naturalmente possiamo usare <code>git cat-file -t</code> per verificare che in effetti si tratti di un <strong>albero<strong><strong><strong>:</strong></strong></strong></strong></p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-121.png" class="kg-image" alt="image-121" width="600" height="400" loading="lazy"><figcaption>Creazione di un oggetto albero nell'indice</figcaption></figure><p>Possiamo usare <code>git cat-file -p</code> per vedere il contenuto:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-122.png" class="kg-image" alt="image-122" width="600" height="400" loading="lazy"></figure><p>Grande, abbiamo creato un <strong>albero</strong>, e ora ci serve creare un oggetto <strong>commit</strong> che faccia riferimento a questo <strong>albero</strong>. Per farlo possiamo usare <code>git commit-tree &lt;hash-albero&gt; -m &lt;messaggio_di_commit&gt;</code>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-123.png" class="kg-image" alt="image-123" width="600" height="400" loading="lazy"></figure><p>Ora dovresti essere a tuo agio con i comandi usati per verificare il tipo di oggetto creato, e per stamparne il contenuto:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-124.png" class="kg-image" alt="image-124" width="600" height="400" loading="lazy"><figcaption>Creazione di un oggetto commit</figcaption></figure><p>Osserva che questo <strong><strong><strong><strong>commit </strong></strong></strong></strong>non ha un <strong>genitore</strong>, visto che è il primo <strong><strong><strong><strong>commit</strong></strong></strong></strong>. Quando aggiungeremo un altro <strong>commit</strong>, dovremo dichiarare il suo <strong>genitore</strong>, lo faremo più tardi.</p><p>L'ultimo hash che abbiamo ottenuto, &nbsp;<code>80e...8f</code> è l'hash di un<strong> commit</strong>. Questi hash ci devono essere piuttosto familiari, ci abbiamo a che fare tutte le volte. Nota che un <strong>commit</strong> detiene un oggetto <strong>albero</strong>, con un proprio hash, che raramente specifichiamo esplicitamente.</p><p>Qualcosa è cambiato nel risultato di &nbsp;<code>git status</code>?</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-125.png" class="kg-image" alt="image-125" width="600" height="400" loading="lazy"></figure><p>Niente 🤔.</p><p>Come mai? Bene, per sapere che il nostro file è stato portato in commit, a <code>git</code> serve conoscere il nostro ultimo <strong>commit</strong>. Come ci riesce? Legge <code>HEAD</code>:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-126.png" class="kg-image" alt="image-126" width="600" height="400" loading="lazy"><figcaption>Stampare il contenuto di <code>HEAD</code> su Windows</figcaption></figure><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-127.png" class="kg-image" alt="image-127" width="600" height="400" loading="lazy"><figcaption>Stampare il contenuto di <code>HEAD</code> su sistemi UNIX</figcaption></figure><p><code>HEAD</code> punta a <code>master</code>, ma cos'è <code>master</code>? Non l'abbiamo ancora creato.</p><p>Come spiegato in precedenza, un branch è semplicemente un riferimento nominativo a un <strong>commit</strong>. In questo caso, vorremmo che <code>master</code> facesse riferimento al <strong>commit</strong> con hash <code>80e8ed4fb0bfc3e7ba88ec417ecf2f6e6324998f</code>.</p><p>Possiamo farlo creando semplicemente un file <code>master</code> in &nbsp;<code>\refs\heads</code>, con questo hash come contenuto, così:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-128.png" class="kg-image" alt="image-128" width="600" height="400" loading="lazy"></figure><p>⭐ Alla fine, un <strong>branch</strong> è semplicemente un file all'interno di <code>.git\refs\heads</code>, che contiene un hash del <strong><strong><strong><strong>commit </strong></strong></strong></strong>al quale si riferisce.</p><p>Ora, finalmente, <code>git status</code> e <code>git log</code> sembrano apprezzare i nostri sforzi:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-129.png" class="kg-image" alt="image-129" width="600" height="400" loading="lazy"></figure><p>Abbiamo creato con successo un <strong>commit</strong> senza usare i comandi di alto livello (quelli in ceramica)! Forte, non è vero? 🎉</p><h2 id="come-lavorare-con-i-branch-in-git-dietro-le-quinte">Come lavorare con i branch in Git: dietro le quinte</h2><p>Proprio come abbiamo creato un &nbsp;<strong><strong><strong><strong>repository</strong></strong></strong></strong> e un <strong><strong><strong><strong>commit </strong></strong></strong></strong>senza usare <code>git init</code>, <code>git add</code> o <code>git commit</code>, ora possiamo creare e spostarci tra i <strong>branch</strong> senza usare i comandi di primo livello (quelli in ceramica), <code>git branch</code> o <code>git checkout</code>.</p><p>È perfettamente legittimo che tu sia eccitato, lo sono anche io 🙂</p><p><strong>Iniziamo<strong><strong><strong>:</strong></strong></strong></strong></p><p>Finora abbiamo solo un <strong>branch</strong>, che si chiama <code>master</code>. Per crearne un altro che chiameremo <code>test</code> (l'equivalente di <code>git branch test</code>), dobbiamo semplicemente creare un file chiamato <code>test</code> all'interno di <code>.git\refs\heads</code>, e il contenuto di quel file sarà lo stesso hash del <strong>commit</strong> al quale <code>master</code> punta.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-130.png" class="kg-image" alt="image-130" width="600" height="400" loading="lazy"></figure><p>Se usiamo <code>git log</code>, possiamo vedere che questo è in effetti il caso, sia <code>master</code> che <code>test</code> puntano a questo <strong><strong><strong><strong>commit</strong></strong></strong></strong>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-131.png" class="kg-image" alt="image-131" width="600" height="400" loading="lazy"></figure><p>Ora spostiamoci nel nostro branch appena creato (l'equivalente di <code>git checkout test</code>). A questo scopo, dovremo modificare <code>HEAD</code> per farlo puntare al nostro nuovo branch:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-132.png" class="kg-image" alt="image-132" width="600" height="400" loading="lazy"><figcaption>Spostamento al branch <code>test</code> modificando <code>HEAD</code></figcaption></figure><p>Come possiamo vedere, sia <code>git status</code> che <code>git log</code> confermano che <code>HEAD</code> ora punta a &nbsp;<code>test</code>, che è, di conseguenza, il branch attivo.</p><p>Ora possiamo avvalerci dei comandi già usati per creare un altro file e aggiungerlo all'<strong>indice</strong>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-133.png" class="kg-image" alt="image-133" width="600" height="400" loading="lazy"></figure><p>Con i comandi qui sopra, abbiamo creato un file chiamato <code>test.txt</code>, che contiene la parola <code>Testing</code>, creato il <strong>blob</strong> corrispondente, e lo abbiamo aggiunto all'<strong>indice</strong>. Abbiamo anche creato un <strong>albero</strong> che rappresenta l'<strong>indice</strong>.</p><p>Adesso creiamo un commit che fa riferimento a questo <strong>albero</strong>. Questa volta, dovremmo anche specificare il <em>genitore</em> di questo <strong>commit</strong>, che sarà il <strong>commit</strong> precedente. Specifichiamo il genitore usando l'opzione <code>-p</code> per &nbsp;<code>git commit-tree</code>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-136.png" class="kg-image" alt="image-136" width="600" height="400" loading="lazy"></figure><p>Abbiamo appena creato un <strong>commit</strong>, con <strong>albero</strong> e un genitore, come possiamo vedere:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-139.png" class="kg-image" alt="image-139" width="600" height="400" loading="lazy"></figure><p>Il risultato di <code>git log</code> ci mostrerà il nuovo <strong><strong><strong><strong>commit</strong></strong></strong></strong>?</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-138.png" class="kg-image" alt="image-138" width="600" height="400" loading="lazy"></figure><p><code>git log</code> non ci mostra nulla di nuovo, come puoi vedere. Perché?🤔 Ricorda che <code>git log</code> traccia i <strong><strong><strong><strong>branch</strong></strong></strong></strong> per trovare commit rilevanti da mostrare. Adesso ci mostra <code>test</code> e il &nbsp;<strong><strong><strong><strong>commit</strong></strong></strong></strong> a cui punta, e ci mostra anche <code>master</code>, che punta allo stesso <strong><strong><strong><strong>commit</strong></strong></strong></strong>.</p><p>Esatto, dobbiamo modificare &nbsp;<code>test</code> per farlo puntare al nostro nuovo <strong><strong><strong><strong>commit</strong></strong></strong></strong>. Lo facciamo modificando semplicemente il contenuto di &nbsp;<code>.git\refs\heads\test</code>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-140.png" class="kg-image" alt="image-140" width="600" height="400" loading="lazy"></figure><p>Ha funzionato! 🎉🥂</p><p><code>git log</code> passa per <code>HEAD</code>, che gli dice di andare al branch <code>test</code>, che a sua volta punta al <strong>commit</strong> <code>465...5e</code>, il quale fa riferimento nuovamente al suo <strong>commit</strong> genitore <code>80e...8f</code>.</p><p>Meraviglioso, non è vero? 😊</p><h2 id="riepilogo">Riepilogo</h2><p>Questo post ti ha introdotto ai meccanismi interni di git. Abbiamo iniziato trattando gli oggetti di base, <strong>blob</strong>, <strong>alberi</strong> e <strong>commit</strong>.</p><p>Abbiamo appreso che un <strong>blob</strong> conserva il contenuto di un file. Un <strong>albero</strong> è un elenco di directory contenente <strong>blob</strong> e/o sotto<strong>alberi</strong>. Un <strong>blob</strong> è un'istantanea della nostra directory di lavoro, con alcuni metadati come la marca temporale e il messaggio di commit.</p><p>Abbiamo quindi discusso dei <strong>branch</strong> e spiegato che non sono altro che un riferimento nominativo a un <strong>commit</strong>.</p><p>Abbiamo continuato descrivendo la <strong>directory di lavoro</strong>, una directory a cui è associato un repository, l'<strong>area di stage</strong> (<strong>indice</strong>) che contiene l'<strong>albero</strong> per il <strong>commit</strong> successivo e il <strong>repository</strong>, che è una raccolta di <strong>commit</strong>.</p><p>Abbiamo chiarito come questi termini si relazionano ai comandi <code>git</code> che conosciamo creando un nuovo repository ed eseguendo il commit di un file utilizzando i ben noti comandi <code>git init</code>, <code>git add</code> e <code>git commit</code>.</p><p>Quindi ci siamo immersi senza paura in git. Abbiamo smesso di usare comandi di alto livello (in ceramica) e siamo passati a comandi di basso livello (idraulici).</p><p>Usando <code>echo</code> e comandi di basso livello come <code>git hash-object</code>, siamo stati in grado di creare un <strong>blob</strong>, aggiungerlo all'<strong>indice</strong>, creare un <strong>albero</strong> dell<strong>'indice</strong> e creare un oggetto <strong>commit</strong> che punta a quell'albero.</p><p>Siamo stati anche in grado di creare e passare da un <strong>branch</strong> all'altro. Complimenti a quelli di voi che l'hanno provato da soli!👏</p><p>Spero che dopo aver seguito questo post sentirai di aver approfondito la tua conoscenza di ciò che accade dietro le quinte quando lavori con <code>git</code>.</p><p><strong>Grazie per aver letto</strong>! Se ti è piaciuto questo articolo, puoi leggere di più su questo argomento sul blog <a href="http://swimm.io/">swimm.io</a>.</p><p><em><em><a href="https://www.linkedin.com/in/omer-rosenbaum-034a08b9/">Omer Rosenbaum</a>,</em> <em>Chief Technology Officer</em> per <em><a href="https://swimm.io/">Swimm</a>. </em>Esperto di c<em>yber training </em>e fondatore di<em> Checkpoint Security Academy. Au</em>tore di </em><a href="https://data.cyber.org.il/networks/networks.pdf" rel="noopener nofollow noopener noopener"><em><em>Computer Networks</em></em></a><em> (in Ebraico)<em>.</em></em></p><p><em><em>Visi</em>ta il mio <a href="https://www.youtube.com/watch?v=79jlgESHzKQ&amp;list=PL9lx0DXCC4BMS7dB7vsrKI5wzFyVIk2Kg">Canale YouTube</a></em></p><h2 id="risorse-addizionali">Risorse addizionali</h2><p>Molto è stato scritto e detto su <code>git</code>. In particolare, ho trovato utili queste risorse (in lingua inglese - n.d.t.):</p><ul><li><a href="https://www.youtube.com/playlist?list=PL9lx0DXCC4BNUby5H58y6s2TQVLadV8v7" rel="noopener">La playlist di YouTube Git Internals — di Brief</a></li><li><a href="https://www.youtube.com/watch?v=MYP56QJpDr4" rel="noopener">La lezione di Tim Berglund  “Git From the Bits Up”</a></li><li><a href="https://jwiegley.github.io/git-from-the-bottom-up/" rel="noopener">Git from the Bottom Up ,  di John Wiegley</a></li><li><a href="http://www.gelato.unsw.edu.au/archives/git/0512/13748.html" rel="noopener">as promised, docs: git for the confused</a></li><li><a href="https://git-scm.com/book/en/v2/Git-Internals-Git-Objects" rel="noopener">Git Internals — Git Objects , dal libro Pro Git book, di Scott Chacon e Ben Straub</a></li></ul> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Il Manuale di Git Rebase – La Guida Definitiva per Rebase ]]>
                </title>
                <description>
                    <![CDATA[ Uno degli strumenti più potenti che uno sviluppatore può avere nella propria cassetta degli attrezzi è git rebase. Eppure è noto per essere complesso e frainteso. La verità è che se capisci cosa fa realmente, git rebase è uno strumento molto elegante e diretto per ottenere tante cose diverse in ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/il-manuale-di-git-rebase/</link>
                <guid isPermaLink="false">64bcd6310ec9a30673ad5b88</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Roberto Pauletto ]]>
                </dc:creator>
                <pubDate>Tue, 08 Aug 2023 14:23:08 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/07/The-Git-Rebase-Handbook-Book-Cover--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/git-rebase-handbook/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The Git Rebase Handbook – A Definitive Guide to Rebasing</a>
      </p><p>Uno degli strumenti più potenti che uno sviluppatore può avere nella propria cassetta degli attrezzi è <code>git rebase</code>. Eppure è noto per essere complesso e frainteso.</p><p>La verità è che se capisci cosa fa <em>realmente</em>, <code>git rebase</code> è uno strumento molto elegante e diretto per ottenere tante cose diverse in Git.</p><p>Nei post precedenti, hai capito <a href="https://www.freecodecamp.org/news/git-diff-and-patch/">come funziona git diff</a>, <a href="https://www.freecodecamp.org/news/the-definitive-guide-to-git-merge/">cosa sia un'azione di merge</a>, <a href="https://www.freecodecamp.org/news/the-definitive-guide-to-git-merge/">come git risolve i conflitti di merge</a>. In questo post, capirai cos'è il comando rebase di Git, perché è diverso da merge e come utilizzare <code>git rebase</code> con sicurezza 💪🏻</p><h2 id="prima-di-iniziare"><strong>Prima di iniziare</strong></h2><ol><li>Ho creato anche un video che tratta il contenuto di questo post. Se desideri guardarlo mentre stai leggendo, puoi trovarlo <a href="https://youtu.be/3VFsitGUB3s">qui</a>.</li><li>Se vuoi fare esperimenti con il repository che ho usato e provare da solo i comandi, puoi trovarlo <a href="https://github.com/Omerr/rebase_playground">qui</a>.</li><li>Sto lavorando a un libro su Git! Ti interessa leggere la versione iniziale e darmi un feedback? Mandami una email: <a href="https://www.freecodecamp.org/news/p/2e1fc200-f447-4f55-b0a3-73ef790a2190/gitting.things@gmail.com">gitting.things@gmail.com</a></li></ol><p>OK, sei pronto?</p><h2 id="breve-riepilogo-cos-e-git-merge-">Breve riepilogo <strong>- Cos'e Git Merge</strong>? 🤔</h2><p>Dietro le quinte, <code>git rebase</code> e <code>git merge</code> sono cose molto, molto diverse. Allora come mai la gente continua a confrontarli tutte le volte?</p><p>La ragione è il loro utilizzo. Quando si lavora con Git in genere si lavora su branch diversi, nei quali si introducono delle modifiche.</p><p>Nel <a href="https://www.freecodecamp.org/news/the-definitive-guide-to-git-merge/#howgits3waymergealgorithmworks">tutorial precedente</a>, ho fornito un esempio dove John e Paul (dei Beatles) scrivevano a 4 mani una nuova canzone. Avevano iniziato entrambi dal branch <code>main</code> poi ognuno di loro ha preso una strada diversa, modificando le parole, quindi confermando le loro modifiche.</p><p>Poi entrambi volevano integrare i loro cambiamenti, il che è qualcosa che succede molto frequentemente quando lavori con Git.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/rebase_integrazione.png" class="kg-image" alt="rebase_integrazione" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/rebase_integrazione.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/rebase_integrazione.png 898w" sizes="(min-width: 720px) 720px" width="898" height="331" loading="lazy"><figcaption>Una cronologia divergente - <code>paul_branch</code> e <code>john_branch</code> divergono da <code>main</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Ci sono due modi principali per integrare modifiche introdotte in branch diversi in Git, oppure, in altre parole, diversi commit e diverse cronologie di commit. Questi sono merge e rebase.</p><p><a href="https://www.freecodecamp.org/news/the-definitive-guide-to-git-merge/">In un tutorial precedente</a>, abbiamo imparato a conoscere <code>git merge</code> molto bene. Abbiamo visto come eseguire un merge, abbiamo creato il <strong>merge di un commit </strong> – dove il contenuto di questo commit è una combinazione di due branch, e aveva anche due genitori, uno in ciascun branch.</p><p>Quindi, diciamo che sei sul branch <code>john_branch</code> (ipotizzando la cronologia descritta nell'immagine qui sopra) ed esegui <code>git merge paul_branch</code>. Arriverai a questo stato – dove su <code>john_branch</code>, c'è un nuovo commit con due genitori. Il primo sarà il commit su <code>john_branch</code> dove <code>HEAD</code> stava puntando prima di eseguire il merge, in questo caso - "Commit 6". Il secondo sarà il commit puntato da <code>paul_branch</code>, "Commit 9".</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/rebase_divergenze.jpg" class="kg-image" alt="rebase_divergenze" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/rebase_divergenze.jpg 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/rebase_divergenze.jpg 895w" sizes="(min-width: 720px) 720px" width="895" height="276" loading="lazy"><figcaption>Il risultato dell'esecuzione di <code>git merge paul_branch</code>: Un nuovo merge commit con due genitori (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Osserva nuovamente il grafico della cronologia: hai creato una cronologia <strong>divergente</strong>. Puoi in effetti vedere dove sono stati ramificati e integrati nuovamente.</p><p>Quindi quando usi <code>git merge</code>, non riscrivi la cronologia – piuttosto aggiungi un commit alla cronologia esistente. E, nello specifico, un commit che crea cronologie divergenti.</p><h2 id="in-che-modo-git-rebase-diverso-da-git-merge-">In che modo <code>git rebase</code> è diverso da <code>git merge</code>? 🤔</h2><p>Quando si usa <code>git rebase</code>, succede qualcosa di diverso. 🥁</p><p>Partiamo dal quadro generale: se sei su <code>paul_branch</code>, ed esegui <code>git rebase john_branch</code>, Git va all'antenato comune per i branch di John e Paul. Poi prende le modifiche introdotte nei commit del branch di Paul e applica dette modifiche al branch di John.</p><p>In questo caso usi <code>rebase</code> per prendere le modifiche effettuate e confermate (con commit) in un branch – quello di Paul (<code>paul_branch</code>) – e le replichi in un branch diverso – quello di John (<code>john_branch</code>).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/integrazione-con-rebase.jpg" class="kg-image" alt="integrazione-con-rebase" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/integrazione-con-rebase.jpg 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/integrazione-con-rebase.jpg 1000w, https://www.freecodecamp.org/italian/news/content/images/2023/07/integrazione-con-rebase.jpg 1227w" sizes="(min-width: 720px) 720px" width="1227" height="348" loading="lazy"><figcaption>Il risultato dell'esecuzione di <code>git rebase john_branch</code>: i commit in <code>paul_branch</code> sono stati "replicati" in <code>john_branch</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Aspetta, cosa significa? 🤔</p><p>Ora analizziamo questo concetto un poco per volta, in modo che tu possa capire pienamente cosa sta succedendo sotto il cofano 😎</p><h2 id="cherry-pick-come-base-per-rebase"><code>cherry-pick</code> come base per rebase</h2><p>È utile pensare a rebase come all'esecuzione di <code>git cherry-pick</code> – un comando che prende un commit, calcola le differenze che questo introduce confrontando il commit del genitore con il commit stesso, e le replica nel branch corrente.</p><p>Facciamolo a mano.</p><p>Se diamo un'occhiata alle differenze introdotte da "Commit 5" eseguendo <code>git diff main &lt;SHA_DI_COMMIT_5&gt;</code>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-199.png" class="kg-image" alt="image-199" width="559" height="248" loading="lazy"><figcaption>Esecuzione di <code>git diff</code> per osservare le modifiche introdotte da "Commit 5" (Fonte: <a href="https://youtu.be/3VFsitGUB3sù">Brief</a>)</figcaption></figure><p>Se vuoi fare esperimenti con il repository che ho usato e provare da solo i comandi, puoi trovare il repository <a href="https://github.com/Omerr/rebase_playground">qui</a>.</p><p>Puoi notare in questo commit, che John ha iniziato a lavorare a una canzone chiamata "Lucy in the Sky with Diamonds":</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-200.png" class="kg-image" alt="image-200" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-200.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-200.png 896w" sizes="(min-width: 720px) 720px" width="896" height="666" loading="lazy"><figcaption>Il risultato di git diff - le modifiche introdotte da "Commit 5" (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Ti ricordo che puoi usare anche il comando <code>git show</code> per ottenere lo stesso risultato:</p><pre><code>git show &lt;SHA_DI_COMMIT_5&gt;</code></pre><p>Ora se esegui il <code>cherry-pick</code> di questo commit, introdurrai questa specifica modifica, sul branch attivo. Prima portati su <code>main</code>:</p><p><code>git checkout main</code> (oppure <code>git switch main</code>)</p><p>Poi crea un altro branch, giusto per essere più chiari:</p><p><code>git checkout -b my_branch</code> (oppure <code>git switch -c my_branch</code>)</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-201-1.png" class="kg-image" alt="image-201-1" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-201-1.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-201-1.png 607w" width="607" height="164" loading="lazy"><figcaption>Creazione del branch <code>my_branch</code> che si dirama da <code>main</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Poi esegui il <code>cherry-pick</code> di questo commit:</p><pre><code>git cherry-pick &lt;SHA_DI_COMMIT_5&gt;</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-202.png" class="kg-image" alt="image-202" width="594" height="113" loading="lazy"><figcaption>Uso di <code>cherry-pick</code> per applicare le modifiche introdotte da "Commit 5" in <code>main</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Esamina questo log (risultato di <code>git lol</code>):</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-205.png" class="kg-image" alt="image-205" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-205.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-205.png 781w" sizes="(min-width: 720px) 720px" width="781" height="141" loading="lazy"><figcaption>Il risultato di <code>git lol</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>(<code>git lol</code> è un alias che ho aggiunto a Git per vedere chiaramente in modo grafico la cronologia. Puoi trovare il comando che sostituisce <a href="https://gist.github.com/Omerr/8134a61b56ca82dd90e546e7ef04eb77">qui</a>).</p><p>Sembra che tu abbia fatto un <em>copia-incolla </em>di "Commit 5". Ricorda che sebbene abbia lo stesso messaggio di commit e introduca le stesse modifiche, e punti anche allo stesso albero di oggetti &nbsp;del "Commit 5" originale, in questo caso è comunque un oggetto commit diverso, visto che è stato creato con una diversa marca temporale.</p><p>Se osserviamo le modifiche usando <code>git show HEAD</code>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-204.png" class="kg-image" alt="image-204" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-204.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-204.png 862w" sizes="(min-width: 720px) 720px" width="862" height="643" loading="lazy"><figcaption>Il risultato di git show HEAD (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Sono le stesse di "Commit 5"'.</p><p>Naturalmente, se osservi il contenuto del file con un editor (diciamo usando il comando <code>nano lucy_in_the_sky_with_diamonds.md</code>), sarà nello stesso stato nel quale si trovava dopo il "Commit 5" originale.</p><p>Forte! 😎</p><p>OK, ora puoi eliminare il nuovo branch così che non appaia nella tua cronologia tutte le volte:</p><pre><code>git checkout main
git branch -D my_branch</code></pre><h2 id="andare-oltre-cherry-pick-come-usare-git-rebase"><strong>Andare oltre<strong> <code>cherry-pick</code> – </strong>Come usare<strong> <code>git rebase</code></strong></strong></h2><p>Puoi considerare <code>git rebase</code> come un modo per eseguire più <code>cherry-pick</code> uno dopo l'altro – vale a dire "replicare" diversi commit. Questa non è la sola cosa che puoi fare con &nbsp;<code>rebase</code>, ma è un buon punto di partenza per la nostra spiegazione.</p><p>È ora di giocare con <code>git rebase</code>! 👏🏻👏🏻</p><p>In precedenza, hai integrato &nbsp;<code>paul_branch</code> in <code>john_branch</code>. Cosa sarebbe successo se avessi <em>eseguito il</em> <em>rebase </em>di <code>paul_branch</code> su <code>john_branch</code>? Avresti ottenuto una cronlogia molto diversa.</p><p>In sostanza, sarebbe come se avessimo preso le modifiche introdotte nei commit su <code>paul_branch</code> e le avessimo replicate su <code>john_branch</code>. Il risultato sarebbe stato una cronologia <strong>lineare</strong>.</p><p>Per capire il processo, ti fornirò una visione ad alto livello, poi approfondiremo ogni passaggio. Il processo di rebase di un branch su un altro branch è il seguente:</p><ol><li>Trova l'antenato comune.</li><li>Identifica i commit da "replicare".</li><li>Per ogni commit <code>X</code>, calcola <code>diff(genitore(X), X)</code>, e conserva il risultato come <code>patch(X)</code>.</li><li>Sposta <code>HEAD</code> verso la nuova base.</li><li>Applica le patch generate in ordine sul branch di destinazione. Ogni volta, crea un nuovo oggetto commit con il nuovo stato.</li></ol><p>Il processo di creare nuovi commit con lo stesso insieme di modifiche di commit esistenti è detto "<strong>replica</strong>" di questi commit, un termine che abbiamo già usato.</p><h2 id="-ora-di-provare-rebase-">È ora di provare rebase🙌🏻</h2><p>Partiamo dal branch di Paul:</p><pre><code>git checkout paul_branch</code></pre><p>Questa è la cronologia:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-206.png" class="kg-image" alt="image-206" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-206.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-206.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-206.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-206.png 1642w" sizes="(min-width: 720px) 720px" width="1642" height="460" loading="lazy"><figcaption>Cronologia dei commit prima di eseguire <code>git rebase</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Ora veniamo alla parte eccitante:</p><pre><code>git rebase john_branch</code></pre><p>Osserva la cronologia:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-207.png" class="kg-image" alt="image-207" width="477" height="268" loading="lazy"><figcaption>La cronologia dopo il rebase (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p><code>gg</code> è un alias per uno strumento esterno che ho introdotto <a href="https://youtu.be/3VFsitGUB3s">nel video</a> (è il programma git-graph <a href="https://github.com/mlange-42/git-graph">che puoi trovare in questo repository</a> - n.d.t.).</p><p>Pertanto mentre con <code>git merge</code> hai aggiunto alla cronologia, con <code>git rebase</code> hai<strong> riscritto la cronologia</strong>. Hai creato oggetti commit <strong>nuovi</strong>. Inoltre il risultato è un grafico di cronologia lineare, non divergente.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-209.png" class="kg-image" alt="image-209" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-209.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-209.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-209.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-209.png 2353w" sizes="(min-width: 720px) 720px" width="2000" height="548" loading="lazy"><figcaption>La cronologia dopo il rebase (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>In sostanza abbiamo "copiato" i commit che si trovavano in <code>paul_branch</code>, introdotti dopo "Commit 4", e "incollati" in <code>john_branch</code>.</p><p>Il comando è chiamato "rebase", in quanto modifica la base di commit del branch dal quale viene eseguito. Nel nostro caso, prima di eseguire <code>git rebase</code>, la base di <code>paul_branch</code> era "Commit 4" – visto che da lì è "nato" il branch (derivato da <code>main</code>). Con <code>rebase</code>, hai chiesto a Git di darti un'altra base, vale a dire: fai finta che <code>paul_branch</code> sia "nato" &nbsp;da "Commit 6".</p><p>Per fare questo Git ha preso quello che era il "Commit 7", e ha "replicato" le modifiche introdotte in questo commit in "Commit 6", poi ha creato un nuovo oggetto commit. Questo oggetto differisce dal "Commit 7" originale in tre aspetti:</p><ol><li>Ha una marca temporale diversa.</li><li>Ha un commit genitore diverso – "Commit 6" invece che "Commit 4".</li><li>L'<a href="https://www.freecodecamp.org/news/git-internals-objects-branches-create-repo/">albero di oggetti</a> a cui punta è diverso - visto che le modifiche sono state introdotte all'albero di oggetti puntato da "Commit 6", non a quello puntato da "Commit 4".</li></ol><p>Nota l'ultimo commit qui, "Commit 9'". L'istantanea che rappresenta (cioè l'<a href="https://www.freecodecamp.org/news/git-internals-objects-branches-create-repo/">albero</a> a cui punta) è esattamente la stessa che avresti se avessi integrato i due branch. Lo stato dei file nel tuo repository Git sarebbe stato <strong>uguale</strong> se avessi usato <code>git merge</code>. Solo che la cronologia è diversa, e l'oggetto commit naturalmente.</p><p>Ora puoi semplicemente usare:</p><pre><code>git checkout main
git merge paul_branch</code></pre><p>Hmm... Cosa succederebbe se eseguissi questo ultimo comando? 🤔 Esamina nuovamente la cronologia dei commit, dopo esserti portato in &nbsp;<code>main</code>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-210.png" class="kg-image" alt="image-210" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-210.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-210.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-210.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-210.png 2352w" sizes="(min-width: 720px) 720px" width="2000" height="697" loading="lazy"><figcaption>La cronologia dopo il rebase e l'entrata in main (Fonte <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Cosa comporta integrare <code>main</code> e <code>paul_branch</code>?</p><p>In effetti, Git può semplicemente eseguire un merge fast-forward, visto che la cronologia è perfettamente lineare (se ti serve una rinfrescata su cosa sia un merge fast-forward, dai un'occhiata a &nbsp;<a href="https://www.freecodecamp.org/news/the-definitive-guide-to-git-merge/#timetogethandson">questo post</a>). Come risultato, <code>main</code> e <code>paul_branch</code> ora puntano allo stesso commit:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-211.png" class="kg-image" alt="image-211" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-211.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-211.png 1000w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-211.png 1168w" sizes="(min-width: 720px) 720px" width="1168" height="619" loading="lazy"><figcaption>Il risultato di un merge fast-forward (Fonte <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><h2 id="rebase-avanzato-in-git-">Rebase avanzato in Git💪🏻</h2><p>Ora che conosci le basi di rebase, è ora di prendere in considerazione casi più avanzati, laddove torneranno utili opzioni addizionali e argomenti per il comando <code>rebase</code>.</p><p>Nell'esempio precedente, quando hai usato <code>rebase</code> senza opzioni aggiuntive, Git ha replicato tutti i commit a partire dall'antenato comune fino all'inizio del branch corrente.</p><p>Ma rebase è potentissimo, è un comando possente in grado di riscrivere la cronologia e può tornare utile se vuoi modificare la cronologia e generarne una tua propria.</p><p>Annulla l'ultimo merge facendo puntare nuovamente <code>main</code> a "Commit 4":</p><pre><code>git reset -–hard &lt;COMMIT 4_ORIGINALE&gt;</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-238.png" class="kg-image" alt="image-238" width="590" height="322" loading="lazy"><figcaption>Annullamento dell'ultima operazione di merge (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Annulla anche il rebase in questo modo:</p><pre><code>git checkout paul_branch
git reset -–hard &lt;COMMIT 9_ORIGINALE&gt;</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-239.png" class="kg-image" alt="image-239" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-239.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-239.png 694w" width="694" height="367" loading="lazy"><figcaption>Annullamento dell'operazione di rebase (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Nota che ora la cronologia è esattamente quella che avevi in precedenza:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-240.png" class="kg-image" alt="Visualizing the history after &quot;undoing&quot; the rebase operation (Source: Brief)" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-240.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-240.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-240.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-240.png 2323w" sizes="(min-width: 720px) 720px" width="2000" height="567" loading="lazy"><figcaption>Visualizzazione della cronologia dopo l'annullamento dell'operazione di rebase (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)è&nbsp;</figcaption></figure><p>Giusto per essere chiari, "Commit 9" non sparisce semplicemente quando non è raggiungibile dall'<code>HEAD</code> corrente. Viceversa è ancora conservato nel database degli oggetti. Visto che hai usato <code>git reset</code> per fare in modo che <code>HEAD</code> punti a questo commit, sei in grado di recuperarlo, assieme ai suoi commit genitori visto che anch'essi sono conservati nel database. Non male, non è vero? 😎</p><p>Adesso diamo un veloce sguardo alle modifiche introdotte da Paul:</p><pre><code>git show HEAD</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-241.png" class="kg-image" alt="image-241" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-241.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-241.png 814w" sizes="(min-width: 720px) 720px" width="814" height="658" loading="lazy"><figcaption><code>git show HEAD</code> mostra le modifiche introdotte da "Commit 9" (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Proseguiamo a ritroso nel grafico dei commit:</p><pre><code>git show HEAD~</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-242.png" class="kg-image" alt="image-242" width="589" height="723" loading="lazy"><figcaption><code>git show HEAD~</code> (uguale a <code>git show HEAD~1</code>) mostra le modifiche introdotte da "Commit 8" (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Andiamo indietro di un altro commit:</p><pre><code>git show HEAD~2</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-243.png" class="kg-image" alt="image-243" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-243.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-243.png 636w" width="636" height="663" loading="lazy"><figcaption><code>git show HEAD~2</code> mostra le modifiche introdotte da "Commit 7" (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Quindi, queste modifiche sono buone, ma forse Paul non vuole questo tipo di cronologia. Piuttosto vuole che sembri che le modifiche introdotte in &nbsp;"Commit 7" e "Commit 8" appaiano come un singolo commit.</p><p>Per fare questo, puoi usare un rebase <strong>interattivo</strong>, aggiungendo l'opzione <code>-i</code> (oppure <code>--interactive</code>) al comando <code>rebase</code> :</p><pre><code>git rebase -i &lt;SHA_DI_COMMIT_4&gt;</code></pre><p>Oppure, visto che <code>main</code> sta puntando a &nbsp;"Commit 4", possiamo semplicemente eseguire:</p><pre><code>git rebase -i main</code></pre><p>Eseguendo questo comando, dici a Git di usare una nuova base, "Commit 4". Pertanto stai chiedendo a Git di tornare a tutti i commit che sono stati introdotti dopo "Commit 4", che sono raggiungibili dall' <code>HEAD</code> corrente, e di replicarli.</p><p>Per ogni commit che viene replicato, Git ci chiede come vogliamo agire:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-250.png" class="kg-image" alt="image-250" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-250.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-250.png 994w" sizes="(min-width: 720px) 720px" width="994" height="738" loading="lazy"><figcaption><code>git rebase -i main</code> ti chiede di selezionare cosa deve essere fatto con ciascun commit (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>In questo contesto, è utile pensare a un commit come a una modifica. Vale a dire, &nbsp;"Commit 7" come fosse "la modifica che 'Commit 7' ha introdotto sopra il suo genitore".</p><p>Una opzione è usare <code>pick</code>. Questo è il comportamento predefinito, che dice a Git di replicare le modifiche introdotte in questo commit. In questo caso, non devi fare nulla e scegliere (<code>pick</code>) &nbsp;per tutti i commit – otterrai la stessa cronologia e Git non dovrà neppure creare dei nuovi oggetti commit.</p><p>Un'altra opzione è <code>squash</code>. Un commit si definisce <em>squashed (accorpato) </em>quando ha tutto il suo contenuto inserito nel commit precedente. Nel nostro caso Paul vorrebbe accorpare &nbsp;"Commit 8" in "Commit 7":</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-251.png" class="kg-image" alt="image-251" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-251.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-251.png 1000w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-251.png 1020w" sizes="(min-width: 720px) 720px" width="1020" height="641" loading="lazy"><figcaption>L'accorpamento di "Commit 8" in "Commit 7" (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Come puoi vedere, &nbsp;<code>git rebase -i</code> fornisce opzioni aggiuntive, ma non le esamineremo tutte in questo post. Se provi ad eseguire il rebase, ti verrà richiesto di indicare un messaggio per il nuovo commit che sarà creato (vale a dire quello che introdurrà le modifiche sia di "Commit 7" che di "Commit 8"):</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-252.png" class="kg-image" alt="image-252" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-252.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-252.png 1000w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-252.png 1004w" sizes="(min-width: 720px) 720px" width="1004" height="680" loading="lazy"><figcaption>Inserimento del messaggio di commit: <code>Commits 7+8</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Dai un'occhiata alla cronologia:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-253.png" class="kg-image" alt="image-253" width="556" height="268" loading="lazy"><figcaption>La cronologia dopo il rebase interattivo (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Esattamente quello che volevamo! Abbiamo su <code>paul_branch</code> "Commit 9" (ovviamente un oggetto diverso rispetto al "Commit 9" originale). Questo punta a "Commits 7+8", che è un singolo commit che contiene le modifiche dei "Commit 7" e "Commit 8" originali. Il genitore di questi commit è &nbsp;"Commit 4", a cui sta puntando <code>main</code>, che è il genitore di <code>john_branch</code>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-254-1.png" class="kg-image" alt="image-254-1" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-254-1.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-254-1.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-254-1.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-254-1.png 2219w" sizes="(min-width: 720px) 720px" width="2219" height="615" loading="lazy"><figcaption>La cronologia dopo il rebase interattivo - visualizzata (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Wow, forte, non è vero? 😎</p><p><code>git rebase</code> ti consente controllo illimitato sulla forma di qualsiasi branch. Puoi usarlo per riordinare i commit, oppure per rimuovere modifiche non corrette, o cambiare una modifica in retrospettiva. In alternativa, potresti spostare la base del tuo branch in un altro commit di tua scelta.</p><h2 id="come-usare-l-opzione-di-switch-onto-di-git-rebase"><strong>Come usare l'opzione di s<strong>witch <code>--onto</code> </strong>di<strong> <code>git rebase</code></strong></strong></h2><p>Consideriamo un altro esempio. Andiamo su <code>main</code> nuovamente:</p><pre><code>git checkout main</code></pre><p>Eliminiamo i puntatori a <code>paul_branch</code> e <code>john_branch</code> in modo che non compaiono più nel grafico della cronologia:</p><pre><code>git branch -D paul_branch
git branch -D john_branch</code></pre><p>Ora generiamo un nuovo branch da <code>main</code> e ci spostiamo su di esso:</p><pre><code>git checkout -b new_branch</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-255-1.png" class="kg-image" alt="image-255-1" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-255-1.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-255-1.png 634w" width="634" height="202" loading="lazy"><figcaption>Creazione di <code>new_branch</code> che si dirama da <code>main</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-256.png" class="kg-image" alt="image-256" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-256.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-256.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-256.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-256.png 1601w" sizes="(min-width: 720px) 720px" width="1601" height="814" loading="lazy"><figcaption>Una cronologia pulita per <code>new_branch</code> che si dirama da <code>main</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)&nbsp;</figcaption></figure><p>Ora facciamo qualche modifica ed eseguiamo il commit:</p><pre><code>nano code.py</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-257.png" class="kg-image" alt="image-257" width="588" height="328" loading="lazy"><figcaption>Aggiunta della funzione <code>new_branch</code> a <code>code.py</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><pre><code>git add code.py
git commit -m "Commit 10"</code></pre><p>Torniamo su <code>main</code>:</p><pre><code>git checkout main</code></pre><p>Poi introduciamo una modifica:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-258.png" class="kg-image" alt="image-258" width="588" height="331" loading="lazy"><figcaption>Aggiunta una docstring (stringa di documentazione in Python) all'inizio del file (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Adesso eseguiamo il commit queste modifiche:</p><pre><code>git add code.py
git commit -m "Commit 11"</code></pre><p>Poi effettuiamo un altro cambiamento:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-259.png" class="kg-image" alt="image-259" width="587" height="380" loading="lazy"><figcaption>Aggiunto <code>@Author</code> alla docstring (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Eseguiamo il commit anche di questa modifica:</p><pre><code>git add code.py
git commit -m "Commit 12"</code></pre><p>Aspetta, ora mi sono reso conto che avrei voluto apportare le modifiche introdotte nel "Commit 11" in <code>new_branch</code>. Che si può fare adesso? 🤔</p><p>Esaminiamo la cronologia:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-260.png" class="kg-image" alt="image-260" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-260.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-260.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-260.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-260.png 1613w" sizes="(min-width: 720px) 720px" width="1613" height="798" loading="lazy"><figcaption>La cronologia dopo l'introduzione di "Commit 12" (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Quello che voglio è che invece di avere "Commit 10" situato solo sul branch &nbsp;<code>main</code>, sia anche in <code>new_branch</code>. Visivamente, vorrei spostarlo in fondo al grafico mostrato qui sotto:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-261.png" class="kg-image" alt="image-261" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-261.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-261.png 1000w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-261.png 1578w" sizes="(min-width: 720px) 720px" width="1578" height="559" loading="lazy"><figcaption>Visivamente, vorrei che tu inglobassi (<code>git push</code>) il "Commit 10" (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Riesci a vedere dove voglio arrivare? 😇</p><p>Bene, come sappiamo rebase ci consente in pratica di <em>replicare</em> le modifiche introdotte in <code>new_branch</code>, quelle del "Commit 10", &nbsp;come se in origine fossero state apportate in "Commit 11" invece che in "Commit 4".</p><p>Per fare questo, puoi usare altri argomenti di <code>git rebase</code>. Dovresti dire a Git che vuoi prendere tutta la cronologia introdotta tra l'antenato comune di <code>main</code> e <code>new_branch</code>, che sarebbe "Commit 4", e fare in modo che la nuova base per quella cronologia sia "Commit 11". Per farlo usa:</p><pre><code>git rebase -–onto &lt;SHA_DI_COMMIT_11&gt; main new_branch</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-262.png" class="kg-image" alt="image-262" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-262.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-262.png 812w" sizes="(min-width: 720px) 720px" width="812" height="565" loading="lazy"><figcaption>La cronologia prima e dopo il rebase, "Commit 10" è stato inserito in <code>new_branch</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)&nbsp;</figcaption></figure><p>Ora dai uno sguardo alla nostra meravigliosa cronologia! 😍</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-263.png" class="kg-image" alt="image-263" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-263.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-263.png 1000w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-263.png 1579w" sizes="(min-width: 720px) 720px" width="1579" height="552" loading="lazy"><figcaption>La cronologia prima e dopo il rebase, "Commit 10" è stato inserito in <code>new_branch</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Consideriamo un altro caso.</p><p>Diciamo che ho iniziato a lavorare su un branch e per errore ho iniziato a lavorare da <code>feature_branch_1</code>, invece che da <code>main</code>.</p><p>Per emulare questa situazione crea <code>feature_branch_1</code>:</p><pre><code>git checkout main
git checkout -b feature_branch_1</code></pre><p>Poi elimina <code>new_branch</code> così che non appaia più nel grafico della cronologia:</p><pre><code>git branch -D new_branch</code></pre><p>Crea un semplice file Python chiamato <code>1.py</code>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-264.png" class="kg-image" alt="image-264" width="581" height="80" loading="lazy"><figcaption>Un nuovo file, <code>1.py</code>, con <code>print("Hello World!")</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Aggiungi a Git questo file ed esegui il commit:</p><pre><code>git add 1.py
git commit -m  "Commit 13"</code></pre><p>Ora esci (per errore) da <code>feature_branch_1</code> ed entra in un nuovo branch (<code>feature_branch_2</code>):</p><pre><code>git checkout -b feature_branch_2</code></pre><p>Poi crea un altro file, <code>2.py</code>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-265.png" class="kg-image" alt="image-265" width="561" height="90" loading="lazy"><figcaption>Creazione di <code>2.py</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Aggiungi anche questo file ed esegui il commit:</p><pre><code>git add 2.py
git commit -m  "Commit 14"</code></pre><p>Poi inserisci dell'altro codice a <code>2.py</code>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-266.png" class="kg-image" alt="image-266" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-266.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-266.png 995w" sizes="(min-width: 720px) 720px" width="995" height="134" loading="lazy"><figcaption>Modifica del file <code>2.py</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Fai il commit anche di queste modifiche:</p><pre><code>git add 2.py
git commit -m  "Commit 15"</code></pre><p>Fino ad ora dovresti avere questa cronologia:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-267.png" class="kg-image" alt="image-267" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-267.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-267.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-267.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-267.png 2050w" sizes="(min-width: 720px) 720px" width="2050" height="572" loading="lazy"><figcaption>La cronologia dopo l'introduzione di "Commit 15" (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Ritorna su <code>feature_branch_1</code> e modifica <code>1.py</code>:</p><pre><code>git checkout feature_branch_1</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-268.png" class="kg-image" alt="image-268" width="563" height="84" loading="lazy"><figcaption>Modifica di <code>1.py</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Fai il commit del file modificato:</p><pre><code>git add 1.py
git commit -m  "Commit 16"</code></pre><p>La tua cronologia dovrebbe essere questa:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-270.png" class="kg-image" alt="image-270" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-270.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-270.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-270.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-270.png 2080w" sizes="(min-width: 720px) 720px" width="2080" height="573" loading="lazy"><figcaption>La cronologia dopo l'introduzione di "Commit 16" (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Diciamo che ora ti rendi conto di avere fatto un errore. In realtà avresti voluto far nascere <code>feature_branch_2</code> da <code>main</code>, invece che da <code>feature_branch_1</code>.</p><p>Come puoi rimediare? 🤔</p><p>Prova a pensarci tenendo conto del grafico della cronologia e di quello che hai imparato fino ad ora sull'opzione <code>--onto</code> per il comando <code>rebase</code> </p><p>Bene, vuoi "sostituire" il genitore del tuo primo commit su <code>feature_branch_2</code>, che è "Commit 14", in modo che sia alla sommità del branch <code>main</code> , in questo caso "Commit 12", invece che all'inizio di <code>feature_branch_1</code>, in questo caso "Commit 13". Pertanto, ancora una volta, andrai a creare una <em>nuova base, </em>questa volta per il primo commit su <code>feature_branch_2</code>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-271.png" class="kg-image" alt="image-271" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-271.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-271.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-271.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-271.png 2039w" sizes="(min-width: 720px) 720px" width="2039" height="570" loading="lazy"><figcaption>Vuoi spostare "Commit 14" e "Commit 15" (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Come faresti?</p><p>Per prima cosa portati su <code>feature_branch_2</code>:</p><pre><code>git checkout feature_branch_2</code></pre><p>Da qui puoi usare:</p><pre><code>git rebase -–onto main &lt;SHA_DI_COMMIT_13&gt;</code></pre><p> Come risultato avrai <code>feature_branch_2</code> con base su <code>main</code> invece che su <code>feature_branch_1</code>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-272.png" class="kg-image" alt="image-272" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-272.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-272.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-272.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-272.png 2049w" sizes="(min-width: 720px) 720px" width="2049" height="567" loading="lazy"><figcaption>La cronologia dei commit dopo il rebase (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>La sintassi del comando è:</p><pre><code>git rebase --onto &lt;nuovo_genitore&gt; &lt;vecchio_genitore&gt;</code></pre><h2 id="come-effettuare-il-rebase-su-un-singolo-branch"><strong>Come effettuare il rebase su un singolo branch</strong></h2><p>Puoi anche usare <code>git rebase</code> in relazione alla cronologia di un singolo branch.</p><p>Vediamo se mi puoi aiutare.</p><p>Diciamo che ho lavorato da <code>feature_branch_2</code>, e nello specifico ho modificato il file <code>code.py</code>. Ho iniziato modificando gli apici singoli che racchiudono le stringhe in apici doppi:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-273.png" class="kg-image" alt="image-273" width="588" height="382" loading="lazy"><figcaption>Modifica di <code>'</code> in <code>"</code> nel file <code>code.py</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Poi ho eseguito il commit delle modifiche:</p><pre><code>git add code.py
git commit -m "Commit 17"</code></pre><p>Quindi ho deciso di aggiungere una nuova funzione all'inizio del file:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-274.png" class="kg-image" alt="image-274" width="590" height="423" loading="lazy"><figcaption>Inserimento della funzione <code>another_feature</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Ho nuovamente portato nell'area di stage <code>code.py</code> ed eseguito il commit:</p><pre><code>git add code.py
git commit -m "Commit 18"</code></pre><p>Ora mi sono reso conto che mi sono dimenticato di cambiare gli apici che racchiudono l'istruzione &nbsp;<code>__main__</code> da singoli a doppi (come potresti aver notato), pertanto ho fatto anche questo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-275.png" class="kg-image" alt="image-275" width="599" height="446" loading="lazy"><figcaption>Modificato <code>'__main__'</code> in <code>"__main__"</code> (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Naturalmente ho eseguito il commit anche di questa modifica:</p><pre><code>git add code.py
git commit -m "Commit 19"</code></pre><p>Ora esamina la cronologia:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-276.png" class="kg-image" alt="image-276" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-276.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-276.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-276.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-276.png 2055w" sizes="(min-width: 720px) 720px" width="2055" height="593" loading="lazy"><figcaption>La cronologia di commit dopo l'introduzione di "Commit 19" (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Non è molto bella, giusto? Voglio dire, ho due commit (in relazione tra loro), "Commit 17" e "Commit 19" (sostituzione di <code>'</code> con &nbsp;<code>"</code>), ma sono separati l'uno dall'altro da un "Commit 18" che non ha niente a che vedere con quelli (ho aggiunto una nuova funzione). Cosa posso fare? 🤔 Puoi aiutarmi?</p><p>Andando a intuito, voglio modificare la cronologia qui:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-277.png" class="kg-image" alt="image-277" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-277.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-277.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-277.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-277.png 2058w" sizes="(min-width: 720px) 720px" width="2058" height="561" loading="lazy"><figcaption>Questi sono i commit che voglio modificare (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Quindi, cosa dovrei fare?</p><p>Hai ragione! 👏🏻</p><p>Posso eseguire il rebase della cronologia da &nbsp;"Commit 17" a "Commit 19", sopra il "Commit 15". Per fare questo:</p><pre><code>git rebase --interactive --onto &lt;SHA_DI_COMMIT_15&gt; &lt;SHA_DI_COMMIT_15&gt;</code></pre><p>Nota che ho specificato "Commit 15" come inizio del gruppo di commit, escludendo questo commit. Non ho avuto bisogno di specificare &nbsp;<code>HEAD</code> come ultimo parametro.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-279.png" class="kg-image" alt="image-279" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-279.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-279.png 1000w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-279.png 1023w" sizes="(min-width: 720px) 720px" width="1023" height="391" loading="lazy"><figcaption>Uso di <code>rebase --onto</code> su un singolo branch (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Dopo aver seguito il tuo consiglio ed eseguito il comando <code>rebase</code> &nbsp;(grazie! 😇) mi viene presentata la seguente schermata:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-280.png" class="kg-image" alt="image-280" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-280.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-280.png 904w" sizes="(min-width: 720px) 720px" width="904" height="638" loading="lazy"><figcaption>Rebase interattivo (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Quindi cosa dovrei fare? Voglio inserire "Commit 19" <em>prima di</em> "Commit 18", in modo che venga appena dopo "Commit 17". Posso proseguire e accorparli, in questo modo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-281.png" class="kg-image" alt="image-281" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-281.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-281.png 1000w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-281.png 1010w" sizes="(min-width: 720px) 720px" width="1010" height="396" loading="lazy"><figcaption>Rebase interattivo - modifica dell'ordine dei commit e accorpamento (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Ora quando mi viene richiesto di inserire un messaggio per il commit, posso indicare &nbsp;"Commit 17+19":</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-282.png" class="kg-image" alt="image-282" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-282.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-282.png 799w" sizes="(min-width: 720px) 720px" width="799" height="393" loading="lazy"><figcaption>Inserimento di un messaggio per il nuovo commit (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Ora guardiamo la nostra stupenda cronologia:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-283.png" class="kg-image" alt="image-283" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-283.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-283.png 1000w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-283.png 1030w" sizes="(min-width: 720px) 720px" width="1030" height="493" loading="lazy"><figcaption>La cronologia risultante (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Grazie ancora! 🙌🏻</p><h2 id="altri-casi-d-uso-per-rebase-altri-esercizi">Altri casi d'uso per rebase + altri esercizi</h2><p>A questo punto, spero tu sia a tuo agio con la sintassi di rebase. Il modo migliore per comprenderla veramente è considerare varie situazioni e cercare di risolverle da solo.</p><p>Per quanto riguarda i casi d'uso che andrò a presentare, ti suggerisco vivamente di interrompere la lettura dopo che ho introdotto ciascun caso e cercare di risolverlo autonomamente.</p><h3 id="come-escludere-commit">Come escludere commit</h3><p>Ipotizziamo che in un altro repository tu abbia questa cronologia:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-284.png" class="kg-image" alt="image-284" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-284.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-284.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-284.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-284.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="438" loading="lazy"><figcaption>Un'altra cronologia di commit (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Prima di iniziare a sperimentare, inserisci un etichetta (tag) per "Commit F", in modo che tu possa poi tornarci più tardi:</p><pre><code>git tag original_commit_f</code></pre><p>In realtà non vuoi includere le modifiche in "Commit C" e "Commit D". Potresti usare un rebase interattivo come prima ed eliminare quelle modifiche, oppure potresti nuovamente usare &nbsp;<code>git rebase -–onto</code>. In che modo useresti l'opzione <code>--onto</code> per "rimuovere" quei due commit?</p><p>Puoi portare la base di &nbsp;<code>HEAD</code> sopra a &nbsp;"Commit B", dove il vecchio genitore era in realtà "Commit D", e ora dovrebbe essere "Commit B". Esamina nuovamente la cronologia:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-284--1-.png" class="kg-image" alt="image-284--1-" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-284--1-.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-284--1-.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-284--1-.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-284--1-.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="438" loading="lazy"><figcaption>Di nuovo la cronologia (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Effettuare il rebase in modo che "Commit B" costituisca la base di "Commit E", significa "spostare" sia "Commit E" che "Commit F", e dargli un'altra <em>base </em>– "Commit B". Puoi comporre da solo il comando per fare questo?</p><pre><code>git rebase --onto &lt;SHA_DI_COMMIT_B&gt; &lt;SHA_OF_COMMIT_D&gt; HEAD</code></pre><p>Nota che usando la sintassi qui sopra non viene spostato <code>main</code> per puntare al nuovo commit, pertanto il risultato è un <code>HEAD</code> staccato. Se usi <code>gg</code> (git-graph) o un altro strumento che visualizza la cronologia raggiungibile dai branch potresti essere confuso:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-285.png" class="kg-image" alt="image-285" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-285.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-285.png 859w" sizes="(min-width: 720px) 720px" width="859" height="462" loading="lazy"><figcaption>Il rebase con <code>--onto</code> risulta in un <code>HEAD</code> staccato (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Tuttavia se usi semplicemente <code>git log</code> (oppure il mio alias <code>git lol</code>), vedrai la cronologia desiderata:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-286--1-.png" class="kg-image" alt="image-286--1-" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-286--1-.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-286--1-.png 740w" sizes="(min-width: 720px) 720px" width="740" height="136" loading="lazy"><figcaption>La cronologia risultante (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Non so tu come la pensi, ma questo tipo di cose mi fanno davvero felice. 😊😇</p><p>A proposito, potresti omettere <code>HEAD</code> dal comando precedente poiché questo è il valore predefinito per il terzo parametro. Quindi usando solo:</p><pre><code>git rebase --onto &lt;SHA_DI_COMMIT_B&gt; &lt;SHA_DI_COMMIT_D&gt;</code></pre><p>otterresti lo stesso risultato. L'ultimo parametro in effetti dice a Git dove si trova la fine della sequenza corrente di commit per i quali effettuare il rebase. Quindi la sintassi <code>git rebase --onto</code> con tre argomenti è:</p><pre><code>git rebase --onto &lt;nuovo_genitore&gt; &lt;vecchio_genitore&gt; &lt;fino_a&gt;</code></pre><h3 id="come-spostare-commit-tra-branch">Come spostare commit tra branch</h3><p>Diciamo di avere la stessa cronologia di prima, alla quale torniamo usando il tag applicato nella sezione precedente:</p><pre><code>git checkout original_commit_f</code></pre><p>Ora voglio che solo "Commit E", sia in un branch basato su "Commit B". Vale a dire, voglio avere un nuovo branch, che si dirama da "Commit B", con solo "Commit E".</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-287.png" class="kg-image" alt="image-287" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-287.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-287.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-287.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-287.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="590" loading="lazy"><figcaption>La cronologia corrente, considerando "Commit E" (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)&nbsp;</figcaption></figure><p>Quindi, cosa significa questo in termini di rebase? Osserva l'immagine qui sopra. Quale commit (o quali) dovrebbero essere oggetto di rebase, e quale commit dovrebbe costituire la nuova base?</p><p>So che posso contare su di te qui 😉</p><p>Quello che voglio è prendere "Commit E", e solo questo commit, e modificare la sua base in &nbsp;"Commit B". In altre parole, <em>replicare</em> le modifiche introdotte in "Commit E" su "Commit B".</p><p>Puoi applicare questa logica alla sintassi di <code>git rebase</code>?</p><p>Eccola (questa volta scrivo <code>&lt;COMMIT_B&gt;</code> invece di <code>&lt;SHA_DI_COMMIT_B&gt;</code>, per brevità):</p><pre><code>git rebase –-onto &lt;COMMIT_B&gt; &lt;COMMIT_D&gt; &lt;COMMIT_E&gt;</code></pre><p>Ora la cronologia risulta questa:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-288.png" class="kg-image" alt="image-288" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-288.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-288.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-288.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-288.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="572" loading="lazy"><figcaption>La cronologia dopo il rebase (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Meraviglioso!</p><h2 id="una-nota-sui-conflitti">Una nota sui conflitti</h2><p>Nota che quando esegui un rebase, potresti imbatterti in conflitti, come se stessi facendo un'azione di integrazione con merge. Potresti avere conflitti perché quando si esegue il rebase, stai cercando di applicare modifiche su una base diversa, nella quale forse le modifiche non si applicano.</p><p>Per esempio prendi di nuovo il repository precedente e in particolare esamina le modifiche introdotte nel "Commit 12", puntato da <code>main</code>:</p><pre><code>git show main</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-289.png" class="kg-image" alt="image-289" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-289.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-289.png 714w" width="714" height="453" loading="lazy"><figcaption>Le modifiche introdotte da "Commit 12" (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Ho già trattato il formato di <code>git diff</code> in dettaglio <a href="https://www.freecodecamp.org/news/git-diff-and-patch/">in un post precedente</a>, ma come veloce ripasso questo commit dice a Git di aggiungere una riga dopo le due righe:</p><pre><code>```
This is a sample file</code></pre><p>e prima di queste tre righe:</p><pre><code>```
def new_feature():
  print('new feature')</code></pre><p>Supponiamo che tu stia tentando di effettuare un rebase di "Commit 12" su un altro commit. Se, per qualche motivo, queste righe non esistono come nella patch sul commit <em>verso il quale</em> stai effettuando il rebase, allora avrai un conflitto. Per saperne di più sui conflitti e su come risolverli, consulta <a href="https://www.freecodecamp.org/news/the-definitive-guide-to-git-merge/">questa guida</a>.</p><h2 id="la-prospettiva-dal-quadro-generale">La prospettiva dal quadro generale</h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/tabella-merge-rebase.png" class="kg-image" alt="tabella-merge-rebase" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/tabella-merge-rebase.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/tabella-merge-rebase.png 1000w, https://www.freecodecamp.org/italian/news/content/images/2023/07/tabella-merge-rebase.png 1526w" sizes="(min-width: 720px) 720px" width="1526" height="526" loading="lazy"><figcaption>Confronto fra rebase e merge (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>All'inizio di questa guida, ho iniziato citando le similitudini tra <code>git merge</code> e <code>git rebase</code>: entrambi sono usati per integrare modifiche introdotte in diverse cronologie.</p><p>Tuttavia, come ora sai, le modalità con le quali operano sono molto diverse. Con merge l'integrazione ha come risultato cronologie divergenti, con rebase la cronologia risultante è lineare. I conflitti sono possibili in entrambi i casi. C'è un'ulteriore colonna nella tabella qui sopra (la terza) che richiede una particolare attenzione.</p><p>Ora che sai cos'è <code>git rebase</code> e come usare il rebase interattivo oppure &nbsp;<code>rebase --onto</code>, spero che tu sia d'accordo con me nell'affermare che <code>git rebase</code> sia uno strumento potentissimo. Tuttavia ha un grosso inconveniente se confrontato con l'integrazione via merge.</p><p>Git rebase modifica la cronologia.</p><p>Ciò significa che <strong>non</strong> dovresti effettuare il rebase di commit che si trovano al di fuori della tua copia locale del repository, sul quali altre persone potrebbero aver basato i loro commit.</p><p>In altre parole, se i commit in oggetto sono solo quelli che tu hai creato localmente, vai pure avanti, usa rebase, scatenati.</p><p>Ma se i commit sono stati portati sul repository remoto, si può generare un grosso problema, visto che qualcun altro potrebbe fare affidamento su questi commit, che tu più tardi hai sovrascritto, pertanto tu e gli altri avrete versioni diverse del repository.</p><p>Questo è improbabile avvenga con <code>merge</code> in quanto, come abbiamo visto, non modifica la cronologia.</p><p>Considera ad esempio l'ultimo caso nel quale abbiamo effettuato un rebase che ha generato questa cronologia:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/07/image-288--1-.png" class="kg-image" alt="image-288--1-" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/07/image-288--1-.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2023/07/image-288--1-.png 1000w, https://www.freecodecamp.org/italian/news/content/images/size/w1600/2023/07/image-288--1-.png 1600w, https://www.freecodecamp.org/italian/news/content/images/2023/07/image-288--1-.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="572" loading="lazy"><figcaption>La cronologia dopo il rebase (Fonte: <a href="https://youtu.be/3VFsitGUB3s">Brief</a>)</figcaption></figure><p>Ora, supponi che io abbia già portato questo branch nel repository remoto con <code>git push</code>, e dopo aver fatto questo, un altro sviluppatore abbia scaricato il repository derivandolo da "Commit C". L'altro sviluppatore non sa che, nel frattempo, io avevo effettuato localmente il rebase del mio branch e l'avevo successivamente inviato nuovamente al repository remoto.</p><p>Ne deriva un'inconsistenza: l'altro sviluppatore lavora da un commit che non è più disponibile sulla mia copia del repository.</p><p>Non approfondirò le conseguenze esatte di quanto esposto qui sopra in questa guida, visto che il mio messaggio principale è che dovresti evitare assolutamente queste situazioni. Se ti interessa sapere cosa sarebbe veramente accaduto, ti lascio un link a un'utile risorsa qui sotto. Per ora riepiloghiamo quanto abbiamo trattato.</p><h2 id="riepilogo">Riepilogo</h2><p>In questo tutorial, hai appreso il comando <code>git rebase</code>, uno strumento potentissimo per riscrivere la cronologia in Git. Hai preso in considerazione alcune situazioni dove <code>git rebase</code> può essere di aiuto, e come usarlo con uno, due o tre parametri, con e senza l'opzione <code>--onto</code>.</p><p>Spero di essere stato in grado di convincerti che <code>git rebase</code> è potente, tuttavia è piuttosto semplice una volta che hai capito il concetto. È uno strumento per "copiare-incollare" i commit (o più precisamente, le modifiche), ed è utile da avere a tua disposizione.</p><h2 id="riferimenti-aggiuntivi">Riferimenti aggiuntivi </h2><ul><li><a href="https://www.youtube.com/playlist?list=PL9lx0DXCC4BNUby5H58y6s2TQVLadV8v7" rel="noopener">Git Internals YouTube playlist — by Brief</a> (il mio canale YouTube).</li><li><a href="https://www.freecodecamp.org/news/git-internals-objects-branches-create-repo/">Un mio post precedente sui meccanismi interni di Git.</a></li><li><a href="https://medium.com/@Omer_Rosenbaum/git-undo-how-to-rewrite-git-history-with-confidence-d4452e2969c2">Un mio tutorial su Git UNDO - riscrivere la cronologia con Git</a>.</li><li><a href="https://git-scm.com/book/en/v2/Git-Branching-Rebasing">Documentazione di Git su rebase</a></li><li><a href="https://jwiegley.github.io/git-from-the-bottom-up/1-Repository/7-branching-and-the-power-of-rebase.html">Branch e la potenza di rebase</a></li><li><a href="https://jwiegley.github.io/git-from-the-bottom-up/1-Repository/8-interactive-rebasing.html">Rebase interattivo</a></li><li><a href="https://womanonrails.com/git-rebase-onto">Git rebase --onto</a></li></ul><h2 id="notizie-sull-autore">Notizie sull'autore</h2><p><a href="https://www.linkedin.com/in/omer-rosenbaum-034a08b9/">Omer Rosenbaum</a> è Chief Technology Officer per <a href="https://swimm.io/">Swimm</a> . È l'autore &nbsp;del <a href="https://youtube.com/@BriefVid">canale YouTube Brief</a>. È anche un esperto di cyber training e fondatore della Checkpoint Security Academy. È l'autore di <a href="https://data.cyber.org.il/networks/networks.pdf" rel="noopener nofollow noopener noopener">Computer Networks (in Ebraico)</a>. Lo puoi trovare su <a href="https://twitter.com/Omer_Ros">Twitter</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 10 Comandi Git che Ogni Sviluppatore Dovrebbe Conoscere ]]>
                </title>
                <description>
                    <![CDATA[ Git è una parte importante dell'attività quotidiana di programmazione (specialmente se lavori in un team) ed è largamente usato nell'industria del software. Visto che ci sono molti comandi che puoi usare, padroneggiare Git richiede tempo. Tuttavia alcuni comandi sono usati più frequentemente (alcuni quotidianamente). Pertanto in questo post condividerò e ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/10-comandi-git-che-ogni-sviluppatore-dovrebbe-conoscere/</link>
                <guid isPermaLink="false">642588b5bdacb6067130296d</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Roberto Pauletto ]]>
                </dc:creator>
                <pubDate>Thu, 06 Apr 2023 13:26:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/03/1o-comandi-git.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/10-important-git-commands-that-every-developer-should-know/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">10 Git Commands Every Developer Should&nbsp;Know</a>
      </p><p>Git è una parte importante dell'attività quotidiana di programmazione (specialmente se lavori in un team) ed è largamente usato nell'industria del software.</p><p>Visto che ci sono molti comandi che puoi usare, padroneggiare Git richiede tempo. Tuttavia alcuni comandi sono usati più frequentemente (alcuni quotidianamente). Pertanto in questo post condividerò e spiegherò i 10 comandi Git più usati che ogni sviluppatore dovrebbe conoscere.</p><p><strong><strong>Not</strong>a<strong>: </strong>per comprendere questo articolo, dovresti conoscere le basi di <strong>Git.</strong></strong></p><h2 id="1-git-clone"><strong><strong>1. </strong>g<strong>it clone</strong></strong></h2><p><code>git clone</code> è un comando per scaricare il codice sorgente esistente da un repository remoto (come Github, per esempio). In altre parole, <code>git clone</code> praticamente fa una copia identica dell'ultima versione di un progetto in un repository e la salva sul tuo computer.</p><p>Ci sono un paio di modi per scaricare il codice sorgente, ma per lo più preferisco la <strong>clonazione tramite https</strong>:</p><pre><code>git clone &lt;https://link-del-nome-del-repository&gt;</code></pre><p>Per esempio, se vuoi scaricare un progetto da Github, tutto quello che devi fare è cliccare sul pulsante verde "Clone or download", copiare l'URL dalla casella di testo e incollarlo dopo il comando "git clone", la cui sintassi ho mostrato qui sopra.</p><p>Questo effettuerà una copia del progetto nel tuo spazio di lavoro locale in modo che tu possa iniziare a lavorarci.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/03/resim-4.png" class="kg-image" alt="resim-4" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/03/resim-4.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/03/resim-4.png 960w" sizes="(min-width: 720px) 720px" width="960" height="288" loading="lazy"><figcaption><strong>Esempio di codice sorgente per Bootstrap da Github</strong></figcaption></figure><h2 id="2-git-branch"><strong><strong>2. </strong>g<strong>it branch</strong></strong></h2><p>I branch sono molto importanti nel mondo Git. Usando i branch, parecchi sviluppatori sono in grado di lavorare in parallelo sullo stesso progetto simultaneamente. Possiamo usare il comando <code>git branch</code> per creare, elencare ed eliminare branch.</p><p><strong><strong>Crea</strong>re un nuovo<strong> branch:</strong></strong></p><pre><code>git branch &lt;nome-branch&gt;</code></pre><p>Questo comando crea un nuovo branch <strong>localmente</strong>. Per inviare il nuovo branch al repository remoto, devi usare questo comando:</p><pre><code>git push -u &lt;remoto&gt; &lt;nome-branch&gt;</code></pre><p><strong>Visualizzare i<strong> branch:</strong></strong></p><!--kg-card-begin: markdown--><p><code>git branch</code> oppure <code>git branch --list</code></p>
<!--kg-card-end: markdown--><p><strong>Eliminare<strong> </strong>un<strong> branch:</strong></strong></p><pre><code>git branch -d &lt;nome-branch&gt;</code></pre><h2 id="3-git-checkout"><strong><strong>3. </strong>g<strong>it checkout</strong></strong></h2><p>Anche questo è uno dei comandi git più usati. Per lavorare in un branch, per prima devi spostarti su di esso. Usiamo <code>git checkout</code> principalmente per spostarci da un branch all'altro. Possiamo anche usarlo per verificare file e commit.</p><pre><code>git checkout &lt;nome-del-tuo-branch&gt;</code></pre><p>Ci sono alcuni passaggi che devi seguire per spostarti con successo tra i branch:</p><ul><li>Devi eseguire l'azione di commit per le modifiche nel tuo branch corrente oppure devi accantonarle (<code>git stash</code>) prima di cambiare branch</li><li>Il branch sul quale vuoi portarti deve esistere localmente</li></ul><p><strong>C'è anche una comando scorciatoia che consente di creare e portarsi su un branch allo stesso tempo<strong>:</strong></strong></p><pre><code>git checkout -b &lt;nome-del-tuo-nuovo-branch&gt;</code></pre><p>Questo comando crea un nuovo branch localmente (<code>-b</code> sta per branch) quindi passa ad esso non appena viene creato.</p><h2 id="4-git-status"><strong><strong>4. </strong>g<strong>it status</strong></strong></h2><p>Il comando <code>git status</code> fornisce tutte le informazioni necessarie sul branch corrente.</p><pre><code>git status</code></pre><p>Possiamo raccogliere diverse informazioni, tra le quali:</p><ul><li>se il branch corrente è aggiornato</li><li>se c'è qualcosa da passare a commit, da inviare al repository oppure da ottenere dal repository</li><li>se ci sono file nell'area di stage, non passati all'area di stage oppure non tracciati</li><li>se ci sono file creati, modificati o cancellati</li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/03/resim-5.png" class="kg-image" alt="resim-5" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/03/resim-5.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/03/resim-5.png 960w" sizes="(min-width: 720px) 720px" width="960" height="370" loading="lazy"><figcaption><strong>git status fornisce informazioni sui branch e sui fil</strong>e</figcaption></figure><h2 id="5-git-add"><strong><strong>5. </strong>g<strong>it add</strong></strong></h2><p>Quando creiamo, modifichiamo o cancelliamo un file, queste modifiche hanno luogo localmente e non saranno incluse nel prossimo commit (a meno che non modifichiamo la configurazione).</p><p>Dobbiamo utilizzare il comando <code>git add</code> per includere le modifiche di uno o più file nel prossimo commit.</p><p><strong>Per aggiungere un file singolo:</strong></p><pre><code>git add &lt;file&gt;</code></pre><p><strong>Per aggiungere tutto in una volta<strong>:</strong></strong></p><pre><code>git add -A</code></pre><p>Come puoi vedere dalla videata precedente nella sezione 4, ci sono nomi di file in colore rosso, il che significa che questi file che non sono stati contrassegnati per essere inclusi nel prossimo commit.</p><p><strong>Per includerli, dobbiamo usare<strong> git add:</strong></strong></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/03/resim-6.png" class="kg-image" alt="resim-6" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/03/resim-6.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/03/resim-6.png 960w" sizes="(min-width: 720px) 720px" width="960" height="245" loading="lazy"><figcaption><strong>Dopo il comando <code>git add</code>, I file di colore verde saranno inclusi nel prossimo commit</strong></figcaption></figure><p><strong><strong>Important</strong>e<strong>: </strong>Il comando <code>git add</code> non modifica il repository e i cambiamenti non saranno salvati a meno che non usiamo <code>git commit</code><strong>.</strong></strong></p><h2 id="6-git-commit"><strong><strong>6. </strong>g<strong>it commit</strong></strong></h2><p>Questo è forse il comando di Git maggiormente usato. Una volta che raggiungiamo un certo punto nello sviluppo, vogliamo salvare le nostre modifiche (che probabilmente si riferiscono a un'attività o alla risoluzione di un problema specifico).</p><p><code>git commit</code> è come impostare un punto di controllo nel processo di sviluppo, al quale puoi tornare successivamente se necessario.</p><p>Dobbiamo anche scrivere un breve messaggio per spiegare cosa abbiamo sviluppato o modificato nel codice.</p><pre><code>git commit -m "messaggio di commit"</code></pre><p><strong><strong>Important</strong>e<strong>: </strong><code>g<strong>it commit</strong></code><strong> sa</strong>lva le tue modifiche solo localmente<strong>.</strong></strong></p><h2 id="7-git-push"><strong><strong>7. </strong>g<strong>it push</strong></strong></h2><p>Dopo avere eseguito il commit delle tue modifiche, la prossima cosa che vorrai fare sarà inviare le modifiche al server remoto. <code>git push</code> invia i tuoi commit al repository remoto.</p><pre><code>git push &lt;remoto&gt; &lt;nome-branch&gt;</code></pre><p>Tuttavia, se il tuo branch è nuovo, dovrai inviare anch'esso con il comando:</p><pre><code>git push --set-upstream &lt;remoto&gt; &lt;nome-del-tuo-branch&gt;</code></pre><p>oppure</p><pre><code>git push -u origin &lt;nome_branch&gt;</code></pre><p><strong><strong>Important</strong>e<strong>: </strong><code>g<strong>it push</strong></code><strong> </strong>invia solo le modifiche che sono state oggetto di commit</strong></p><h2 id="8-git-pull"><strong><strong>8. </strong>g<strong>it pull</strong></strong></h2><p>Il comando <code><strong>git pull</strong></code> viene usato per ottenere aggiornamenti dal repository remoto. È la combinazione dei comandi <code><strong>git fetch</strong></code> e <code><strong>git merge</strong></code>, il che significa che quando usiamo <code>git pull</code> otteniamo aggiornamenti dal repository remoto (<code>git fetch</code>) e applichiamo immediatamente le ultime modifiche localmente (<code>git merge</code>).</p><pre><code>git pull &lt;remoto&gt;</code></pre><p><strong>Questa operazione potrebbe causare conflitti che potresti dover risolvere manualmente<strong>.</strong></strong></p><h2 id="9-git-revert"><strong><strong>9. </strong>g<strong>it revert</strong></strong></h2><p>Talvolta dobbiamo annullare modifiche che abbiamo effettuato. Ci sono vari modi per annullare le modifiche, sia localmente che su remoto (a seconda delle necessità), ma dobbiamo essere cauti con questi comandi per evitare cancellazioni indesiderate.</p><p>Un modo più sicuro per annullare i nostri commit è l'uso del comando <code><strong>git revert</strong></code>. Per vedere la nostra cronologia di commit, per prima cosa usiamo <code><strong>git log --oneline</strong></code>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/03/resim.png" class="kg-image" alt="resim" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/03/resim.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/03/resim.png 896w" sizes="(min-width: 720px) 720px" width="896" height="81" loading="lazy"><figcaption><strong>Cronologia dei commit del mio branch master</strong></figcaption></figure><p>Poi dobbiamo solo specificare il codice hash vicino al commit che vorremmo annullare:</p><pre><code>git revert 3321844</code></pre><p>A questo punto, verrà aperto l'editor di testo predefinito e vedrai un testo come quello qui sotto. Digita semplicemente il comando per uscire dall'editor oppure modifica e salva il contenuto se vuoi modificare il messaggio di commit:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2020/01/resim-2.png" class="kg-image" alt="resim-2" width="600" height="400" loading="lazy"></figure><p>Il comando <code>git revert</code> annullerà il commit specificato creando un nuovo commit senza eliminare quello vecchio:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/03/resim-3.png" class="kg-image" alt="resim-3" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/03/resim-3.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/03/resim-3.png 946w" sizes="(min-width: 720px) 720px" width="946" height="120" loading="lazy"><figcaption><strong>Il "nuovo" commit creato da <code>git revert</code></strong></figcaption></figure><p>Il vantaggio dell'uso di <code>git revert</code> è che non tocca la cronologia dei commit. Questo significa che puoi ancora vedere tutti i commit nella tua cronologia, anche quelli ripristinati.</p><p>Un'altra misura di sicurezza qui è che tutto accade localmente a meno che non inviamo (<code>git push</code>) i commit al repository remoto. Ecco perché <code>git revert</code> è più sicuro da usare ed è il modo da preferire per annullare i nostri commit.</p><h2 id="10-git-merge"><strong><strong>10. </strong>g<strong>it merge</strong></strong></h2><p>Quando hai completato lo sviluppo nel tuo branch, e tutto funziona correttamente, il passo finale è integrare il branch nel suo branch genitore (dev o master). Ciò viene fatto con il comando <code>git merge</code>.</p><p>In pratica <code>git merge</code> integra il branch che stai usando con tutti i suoi commit con il branch dev (o master). È importante ricordare che prima devi portarti nel branch nel quale vuoi effettuare l'integrazione.</p><p>Per esempio, quando vuoi integrare un tuo branch nel branch dev:</p><p><strong>Prima portati nel branch dev:</strong></p><pre><code>git checkout dev</code></pre><p><strong>Prima dell'integrazione, dovresti aggiornare il tuo branch dev locale<strong>:</strong></strong></p><pre><code>git fetch</code></pre><p><strong>Alla fine, puoi integrare il tuo branch nel branch dev:</strong></p><pre><code>git merge &lt;nome-branch&gt;</code></pre><p><strong>Suggerimento<strong>: </strong>Assicurati che il tuo branch dev sia aggiornato all'ultima versione, prima di effettuare il merge, altrimenti potresti avere dei conflitti o altri problemi indesiderati<strong>.</strong></strong></p><p>Questi sono i 10 comandi git più usati durante la programmazione quotidiana. Ci sono molte altre cose da imparare su Git e le spiegherò successivamente in altri articoli.</p><p><strong>Se vuoi saperne di più sullo sviluppo web, puoi seguirmi su </strong><a href="https://www.youtube.com/channel/UC1EgYPCvKCXFn8HlpoJwY3Q" rel="noopener"><strong><strong>Youtube</strong></strong></a><strong><strong>!</strong></strong></p><p>Grazie per la lettura!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Come ripristinare le modifiche in Git ]]>
                </title>
                <description>
                    <![CDATA[ Potresti già sapere che Git è come un sistema di punti di salvataggio. Quello che in genere impari con Git all'inizio è come salvare le tue modifiche ed eseguire un'azione di commit verso un repository remoto. Ma come fare per ripristinare una modifica e tornare a uno stato precedente? È ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/come-ripristinare-le-modifiche-in-git/</link>
                <guid isPermaLink="false">63b982742d9e0906706d5f91</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Roberto Pauletto ]]>
                </dc:creator>
                <pubDate>Mon, 06 Mar 2023 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/01/0_6JjR02sGP4FgM6zj.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/how-to-undo-changes-in-git-e1da7930afdb/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to undo changes in Git</a>
      </p><p>Potresti già sapere che Git è come un sistema di punti di salvataggio. Quello che in genere impari con Git all'inizio è come salvare le tue modifiche ed eseguire un'azione di commit verso un repository remoto. Ma come fare per ripristinare una modifica e tornare a uno stato precedente?</p><p>È ciò che andremo a trattare all'interno di questo articolo.</p><p>Il contenuto di questo articolo è anche esposto in un video (risorsa in inglese) se preferisci imparare guardando invece che leggendo.</p><h3 id="locale-contro-remoto"><strong>Locale contro Remoto</strong></h3><p>È più complicato ripristinare qualcosa che si trova già su remoto. Ecco perché vorrai mantenere le cose sulla tua macchina locale fino a quando sei praticamente sicuro che vadano bene.</p><h3 id="quattro-scenari-comuni"><strong>Quattro scenari comuni</strong></h3><p>Tratteremo i quattro scenari seguenti:</p><ol><li>Eliminare modifiche locali</li><li>Correggere il commit precedente</li><li>Ripristinare lo stato del codice a un commit precedente</li><li>Ripristinare un commit che è stato inviato al repository remoto</li></ol><p>Nota: Nelle videate che seguono, ho usato il client Git <a href="https://git-fork.com/" rel="noopener">Fork for Mac OS</a>. &nbsp;Puoi fare altrettanto in altri client Git simili.</p><h4 id="scenario-1-eliminare-modifiche-locali"><strong>Scenario 1: Eliminare modifiche locali</strong></h4><p>In questo primo scenario ipotizziamo che hai effettuato alcune modifiche che non sono ancora state oggetto di commit, e vuoi eliminarle.</p><p>Diciamo di voler creare una nuova funzionalità. Aggiungeremo un poco di HTML e CSS al progetto:</p><pre><code class="language-html">&lt;!--Nel file index.html--&gt;
&lt;div class="feature"&gt;&lt;/div&gt;</code></pre><pre><code class="language-css">/* Nel file CSS */
.feature {
  font-size: 2em; 
  /* Altri stili */
}</code></pre><p>Per eliminare queste modifiche:</p><ol><li>Vai all'area di staging</li><li>Seleziona i file dai quali vuoi eliminare le modifiche</li><li>Click destro sui file</li><li>Seleziona "Discard changes"</li></ol><figure class="kg-card kg-image-card"><img src="https://cdn-media-1.freecodecamp.org/images/0*6JjR02sGP4FgM6zj.png" class="kg-image" alt="0*6JjR02sGP4FgM6zj" width="800" height="779" loading="lazy"></figure><h4 id="scenario-2-correggere-il-commit-precedente"><strong>Scenario 2: Correggere il commit precedente</strong></h4><p>In questo caso hai creato un commit ma hai dimenticato di aggiungere alcune modifiche e vuoi aggiungere dette modifiche nel messaggio di commit precedente.</p><ol><li>Vai all'area di staging</li><li>Porta i file da inserire nel commit nell'area di staging</li><li>Clicca sulla casella di spunta "Amend"</li><li>Modifica il tuo messaggio di commit</li><li>Esegui il commit</li></ol><figure class="kg-card kg-image-card"><img src="https://cdn-media-1.freecodecamp.org/images/0*1wkCc2i9X8JWsBz4.png" class="kg-image" alt="0*1wkCc2i9X8JWsBz4" width="800" height="252" loading="lazy"></figure><h4 id="scenario-3-ritornare-a-un-commit-precedente"><strong>Scenario 3: Ritornare a un commit precedente</strong></h4><p>Hai già effettuato alcuni commit nel tuo repository locale. Decidi che non vuoi più questi commit e vuoi "caricare" i tuoi file da uno stato precedente.</p><ol><li>Vai a "Git History"</li><li>Click destro sul commit verso il quale vuoi ritornare</li><li>Seleziona "Reset <code>nome-branch</code> to here"</li></ol><figure class="kg-card kg-image-card"><img src="https://cdn-media-1.freecodecamp.org/images/0*IwWQ9XZNRmCaVvb8.png" class="kg-image" alt="0*IwWQ9XZNRmCaVvb8" width="800" height="326" loading="lazy"></figure><blockquote>Nota: Puoi ritornare solo a commit che non sono stati ancora inviati al repository remoto.</blockquote><h4 id="scenario-4-annullare-un-commit-che-stato-inviato-a-un-remoto"><strong>Scenario 4: Annullare un commit che è stato inviato a un remoto</strong></h4><p>In questo caso hai un commit che è stato già inviato a un repository remoto e vuoi annullarlo.</p><blockquote>Annullarlo significa ripristinare la situazione precedente creando un nuovo commit "al contrario". Se hai aggiunto una riga, questo commit la eliminerà. Se hai eliminato una riga, questo commit la aggiungerà nuovamente.</blockquote><p>Per fare questo:</p><ol><li>Vai a Git history</li><li>Click destro sul commit che vuoi annullare</li><li>Seleziona "Revert commit"</li><li>Assicurati che &nbsp;"<code>commit the changes</code>" sia spuntato.</li><li>Click su Revert</li></ol><figure class="kg-card kg-image-card"><img src="https://cdn-media-1.freecodecamp.org/images/0*29rgArX4rXn3aH6x.png" class="kg-image" alt="0*29rgArX4rXn3aH6x" width="800" height="364" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://cdn-media-1.freecodecamp.org/images/0*fUD5rUESrzaMnbXu.png" class="kg-image" alt="0*fUD5rUESrzaMnbXu" width="800" height="235" loading="lazy"></figure><h3 id="altri-scenari"><strong>Altri scenari</strong></h3><p>GitHub ha un utile articolo che ti mostra come puoi ripristinare praticamente qualsiasi cosa con Git. Ti sarà utile qualora dovessi fronteggiare altre situazioni. Leggilo <a href="https://blog.github.com/2015-06-08-how-to-undo-almost-anything-with-git/" rel="noopener">qui</a> (risorsa in inglese).</p><p>Grazie per la lettura. Questo articolo ti è stato d'aiuto in qualche modo? In questo caso mi <a href="http://twitter.com/share?text=Undoing%20changes%20in%20Git%20by%20@zellwk%20?%20&amp;url=https://zellwk.com/blog/git-undo/&amp;hashtags=" rel="noopener">auguro che tu lo voglia condividere</a>. Potresti aiutare qualcuno. Grazie!</p><p>Questo articolo è stato originariamente pubblicato sul <a href="https://zellwk.com/blog/git-undo" rel="noopener">mio blo</a>g.<br>Iscriviti alla mia<a href="https://zellwk.com/" rel="noopener"> newsletter</a> se vuoi più articoli che ti aiutino a diventare uno sviluppatore migliore.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Ora che non hai più paura di GIT, ecco come sfruttare quello che sai ]]>
                </title>
                <description>
                    <![CDATA[ La prima parte di questa serie [/italian/news/come-non-aver-piu-paura-di-git/]  ha esaminato il funzionamento interno di Git e ti ha mostrato come non aver paura di lavorare con Git. Ora che abbiamo capito come funziona Git, passiamo alla sostanza: come sfruttare ciò che sappiamo nei nostri progetti. Integrazione (merge) Merge integra il ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/ora-che-non-hai-piu-paura-di-git-ecco-come-sfruttare-quello-che-sai/</link>
                <guid isPermaLink="false">638baf4904f75a068657d30b</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Roberto Pauletto ]]>
                </dc:creator>
                <pubDate>Tue, 13 Dec 2022 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/12/1_8rQSJ7R76i_N0r-LjULBZw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/now-that-youre-not-afraid-of-git-anymore-here-s-how-to-leverage-what-you-know-11e710c7f37b" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Now that you’re not afraid of GIT anymore, here’s how to leverage what you know</a>
      </p><p><a href="https://www.freecodecamp.org/italian/news/come-non-aver-piu-paura-di-git/">La prima parte di questa serie</a> ha esaminato il funzionamento interno di Git e ti ha mostrato come non aver paura di lavorare con Git.</p><p>Ora che abbiamo capito come funziona Git, passiamo alla sostanza: come sfruttare ciò che sappiamo nei nostri progetti.</p><h3 id="integrazione-merge-"><strong>Integrazione (m<strong>erge</strong>)</strong></h3><p>Merge <em>integra</em> il tuo codice.</p><p>Ricordi come stavamo seguendo le buone pratiche Git, avendo branch per varie funzionalità su cui stavamo lavorando e non tutto su <code>master</code>? Verrà un momento in cui avrai finito con quella funzionalità e vorrai includerla nel tuo <code>master</code>. È qui che entra in gioco <code>merge</code>, quando vuoi integrare il tuo ramo in master.</p><p>Ci sono due tipi di azioni di merge:</p><h4 id="integrazione-con-avanzamento-veloce-fast-forward-merge-">Integrazione con avanzamento veloce (fast forward merge)</h4><p>Ritorniamo al nostro esempio dall'ultima volta:</p><p>Questo è tanto semplice quanto spostare l'etichetta per <code>master</code> a <code>the-ending</code>. Git non ha dubbi su ciò che deve essere fatto esattamente, dal momento che il nostro "albero" aveva un'unica lista collegata di nodi.</p><pre><code>$ git branch
  master
* the-ending
$ git checkout master
Switched to branch 'master'
$ git merge the-ending
Updating a39b9fd..b300387
Fast-forward
 byeworld | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 byeworld</code></pre><h4 id="integrazione-senza-avanzamento-veloce-non-fast-forward-merge-"><strong>Integrazione senza avanzamento veloce (n<strong>on-</strong>f<strong>ast </strong>f<strong>orward </strong>m<strong>erge</strong>)</strong></h4><p>Con questo tipo di integrazione Git non sa cosa fare. Ci sono state alcune modifiche sul branch base e altre modifiche sul branch che vogliamo integrare, il che genera i temuti <em>conflitti di integrazione</em> (merge conflicts<em>)</em></p><p>Ecco la prima cosa da sapere circa i conflitti di integrazione: se non sai cosa sta succedendo, rinuncia all'operazione.</p><pre><code>git merge --abort</code></pre><p>Questo comando ti riporta allo stato originale, senza effetti collaterali. Hai semplicemente annullato il disastro che stavi per fare.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2022/12/image-10.png" class="kg-image" alt="image-10" width="475" height="562" loading="lazy"><figcaption><a href="http://www.quickmeme.com/p/3vzhql">Non vuoi essere Brian?</a></figcaption></figure><p>Esaminiamo passo passo come risolvere i conflitti di integrazione.</p><pre><code>$ git checkout -b the-middle
Switched to a new branch 'the-middle'</code></pre><p>Continuando secondo il nostro stile, impariamo con un esempio. Ho modificato <code>helloworld</code> nel branch <code>the-middle</code>.</p><pre><code>$ git diff
diff --git a/helloworld b/helloworld
index a042389..e702052 100644
--- a/helloworld
+++ b/helloworld
@@ -1 +1,3 @@
 hello world!
+
+Middle World</code></pre><p>Poi ho eseguito un'azione di commit su <code>the-middle</code>.</p><p>Quindi sono passato a <code>master</code> e ho modificato <code>helloworld</code>. Ho aggiunto quanto segue:</p><pre><code>$ git diff --cached
diff --git a/helloworld b/helloworld
index a042389..ac7a733 100644
--- a/helloworld
+++ b/helloworld
@@ -1 +1,3 @@
 hello world!
+
+Master World</code></pre><p>Capisci come mai ho dovuto eseguire &nbsp;<code>git diff --cached</code> qui? In caso contrario chiedimelo qui sotto!</p><p>Ora è tempo di integrare!</p><pre><code>$ git merge the-middle
Auto-merging helloworld
CONFLICT (content): Merge conflict in helloworld
Automatic merge failed; fix conflicts and then commit the result.</code></pre><p>Quando un'azione di <code>merge</code> fallisce, ecco cosa fa git: modifica i file oggetto di integrazione sui quali si sono verificati i conflitti per mostrarti esattamente come potresti agire.</p><p>Prima dell'azione di merge, in <code>master</code> il contenuto del file <code>helloworld</code> era:</p><pre><code>$ cat helloworld 
hello world!</code></pre><p>Dopo l'azione di merge, in <code>master</code> il contenuto del file <code>helloworld</code> è:</p><pre><code>$ cat helloworld 
hello world!
&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD
Master World
=======
Middle World
&gt;&gt;&gt;&gt;&gt;&gt;&gt; the-middle</code></pre><p>Questo ha senso? La parte <code>&lt;&lt;&lt;&lt;&lt; HEAD</code> è la nostra (il branch base) e la parte <code>&gt;&gt;&gt;&gt;&gt; the-middle</code> &nbsp;è la loro (il branch che si vuole integrare nel branch base).</p><p>Puoi semplicemente modificare il file per rimuovere il testo extra aggiunto da git, e scegliere cosa dovrebbe contenere in definitiva <code>helloworld</code>. Ci sono alcuni strumenti e integrazioni per editor per facilitare le cose, ma penso che sapere come funziona sotto il cofano possa &nbsp;renderti più fiducioso quando non hai a disposizione il tuo editor preferito.</p><pre><code>$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)
Unmerged paths:
  (use "git add &lt;file&gt;..." to mark resolution)
both modified:   helloworld</code></pre><p>Ho deciso di mantenere entrambe le modifiche.</p><pre><code>$ cat helloworld 
hello world!
Master World
Middle World</code></pre><blockquote>N.d.T.<br>Da qui in avanti i commenti dei commit rilevanti sono stati tradotti per una maggiore comprensione dell'esposizione.</blockquote><p>E il gioco è fatto: </p><pre><code>$ git add helloworld 
$ git commit -m "risolto conflitto di integrazione"
[master c747e68] risolto conflitto di integrazione</code></pre><h3 id="remoto"><strong><strong>Remot</strong>o</strong></h3><p>Visto che uno dei poteri del controllo della versione delle sorgenti è di salvare il tuo codice in caso di disastri, i remoti sono qui per essere di aiuto. Un remoto è una copia ospitata all'esterno del tuo repository. Per essere più precisi un remoto è un repository esterno (non necessariamente dello stesso codice che tu hai). Per esterno si intende una cartella differente nel tuo file system oppure nel cloud.</p><h4 id="clonazione"><strong><strong>Clon</strong>azione</strong></h4><p>Il comando <code>clone</code> esegue una clonazione del repository remoto all'interno della tua directory di lavoro corrente. Ciò avviene semplicemente creando una copia della cartella <code>./git</code>, che ci fornisce l'intera cronologia e i file necessari per popolare la directory di lavoro.</p><pre><code>git clone &lt;repository-url&gt;</code></pre><p>Se non hai ancora eseguito un'azione di clonazione, probabilmente non hai un remoto. Puoi creare un remoto in questo modo:</p><pre><code>git remote add &lt;nome&gt; &lt;url&gt;</code></pre><h3 id="inviare-e-scaricare-push-e-pull-"><strong>Inviare e Scaricare (p<strong>ush</strong> e<strong> </strong>p<strong>ull</strong>)</strong></h3><p>Le azioni di push e pull si applicano sul remoto.</p><p>Push <em>invia</em> le tue modifiche al remoto, vale a dire che stiamo inviando l'indice e gli oggetti corrispondenti dall'object store della nostra versione locale!</p><pre><code>git push &lt;nome del remoto&gt; &lt;nome del branch&gt;</code></pre><p>Pull <em>scarica</em> il code dal remoto. Esattamente come prima, stiamo copiando l'indice e gli oggetti corrispondenti dell'object store dalla versione su remoto!</p><pre><code>git pull origin master</code></pre><p><code>origin</code> è il nome predefinito del remoto. Visto che <code>master</code> è il branch predefinito puoi vedere come il comando si trasforma nel semplice testo che troviamo ovunque: <code>git pull origin master</code>. Ora ne sai di più.</p><h3 id="reset"><strong>R<strong>eset</strong></strong></h3><p>Reset <em>ripristina</em> il tuo codebase a una versione precedente. Questo comando ha 3 opzioni:</p><p><code>--soft</code>, <code>--hard</code> e <code>--mixed</code>.</p><p>La bellezza di <code>reset</code>, è che è in grado di cambiare la cronologia. Diciamo che hai commesso un errore in un commit e ora il tuo log di git è sporcato da commit di questo tipo:</p><p><code>Risoluzione Bug</code></p><p><code>Risoluzione Finale Bug</code></p><p><code>Risoluzione Finale Finale Bug</code></p><p><code>Accidenti, perché questo non funziona ultimo tentativo di risoluzione bug </code></p><p>Se vuoi mantenere la cronologia del tuo <code>master</code> pulita, vorrai pulire questo log di commit.</p><p>Se stai inviando una pull request dove non c'è accorpamento dei commit, è auspicata anche una cronologia di commit pulita!</p><p>Ecco dove entra in gioco il comando <code>reset</code>. Potresti ripristinare tutti i tuoi commit e convertirli tutti in uno singolo: <code>tutto sistemato!</code></p><p>(Per favore non usare questo come messaggio di commit, segui le migliori pratiche!)</p><p>Tornando al nostro esempio ecco quello che ho fatto :</p><pre><code>$ git log
commit 959781ec78c970d4797c5e938ec154de44d0151b (HEAD -&gt; master)
Author: Neil Kakkar
Date:   Mon Nov 5 07:32:55 2018 +0000
Accidenti, perché questo non funziona ultimo tentativo di risoluzione bug
commit affa90c0db78999d22c326fdbd6c1d5057228822
Author: Neil Kakkar
Date:   Mon Nov 5 07:32:19 2018 +0000
Risoluzione Finale Finale Bug
commit 2e9570cffc0a8206132d75c402d68351eda450bd
Author: Neil Kakkar
Date:   Mon Nov 5 07:31:49 2018 +0000
Risoluzione Finale Bug
commit 4560fc0ec6305d0b7bcfb4be1901438fd126d6d1
Author: Neil Kakkar
Date:   Mon Nov 5 07:31:21 2018 +0000
Risoluzione Bug
commit c747e6891af419119fd817dc69a2e122084aedae
Merge: 3d01508 fb8b2fc
Author: Neil Kakkar
Date:   Tue Oct 23 07:44:09 2018 +0100
risolto conflitto di integrazione</code></pre><p>Ora che il bug è risolto, vorrei pulire la mia cronologia prima di inviare le modifiche al <code>master</code>. Questo funzionerebbe bene anche nel caso in cui realizzassi a posteriori di avere introdotto un altro bug e volessi ripristinare la versione precedente. In questo caso il commit <code>c747e689</code> non ha il miglior messaggio di commit per capire questo.</p><pre><code>$ git reset c747e6891af419119fd817dc69a2e122084aedae
$ git log
commit c747e6891af419119fd817dc69a2e122084aedae (HEAD -&gt; master)
Merge: 3d01508 fb8b2fc
Author: Neil Kakkar
Date:   Tue Oct 23 07:44:09 2018 +0100
risolto conflitto di integrazione</code></pre><p>Ecco, tutto sistemato?</p><pre><code>$ git status
On branch master
Untracked files:
  (use "git add &lt;file&gt;..." to include in what will be committed)
      clean.txt
nothing added to commit but untracked files present (use "git add" to track)</code></pre><p><code>clean.txt</code> è il file che ho usato nel commit per risolvere il bug. Ora tutto quello che devo fare è:</p><pre><code>$ git add clean.txt 
$ git commit -m "risoluzione bug: non si riesce a pulire la cartella"
[master d8487ca] risoluzione bug: non si riesce a pulire la cartella
 1 file changed, 4 insertions(+)
 create mode 100644 clean.txt
$ git log
commit d8487ca8b9acfa9666bdf2c6b7fa27b3971bd957 (HEAD -&gt; master)
Author: Neil Kakkar
Date:   Mon Nov 5 07:41:41 2018 +0000
risoluzione bug: non si riesce a pulire la cartella
commit c747e6891af419119fd817dc69a2e122084aedae
Merge: 3d01508 fb8b2fc
Author: Neil Kakkar
Date:   Tue Oct 23 07:44:09 2018 +0100
risolto conflitto di integrazione</code></pre><p>Ecco, fatto e finito. Riesci a indovinare ora, usando gli indizi del log, la sintassi del comando <code>reset</code> e le tue capacità tecniche per capire come funziona dietro le quinte?</p><p><code>Reset</code> taglia l'alberatura dei commit al commit specificato. Tutte le etichette per quel branch, se sono più avanti, sono spostate indietro verso il commit specificato. I file esistenti rimangono comunque nell'object store? Sai come verificarlo ora.</p><p>I file sono anche stati rimossi dall'area di staging. Ora questo potrebbe essere un problema se hai molti file non tracciati o modificati che non vuoi aggiungere.</p><p>Come puoi fare?</p><p>Puoi recuperare l'indizio che ho lasciato all'inizio di questa sezione?</p><p>Le opzioni per gestire il comportamento del comando <code>reset</code>!</p><p><code>--soft</code> mantiene tutti i file presenti nell'area di staging.</p><pre><code>$ git reset --soft c747e6891af419119fd817dc69a2e122084aedae
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD &lt;file&gt;..." to unstage)
new file:   clean.txt</code></pre><p><code>--mixed</code> è l'opzione predefinita: elimina anche tutti i file dall'area di staging.</p><p><code>--hard</code> è brutale. Elimina i file dall'object store, comprese le directory. Usalo con estrema cautela. Ecco, ora sparisce la mia risoluzione del bug*. Andata.</p><pre><code>$ git reset --hard c747e6891af419119fd817dc69a2e122084aedae
HEAD is now at c747e68 risolto conflitto di integrazione
$ git status
On branch master
nothing to commit, working tree clean</code></pre><p>*Beh, non completamente. Git è stupefacente. Hai sentito parlare di metadati?. Un registro di ridondanza di quello che accade nel repository? Sì, naturalmente, Git lo mantiene!</p><pre><code>$ git reflog
c747e68 (HEAD -&gt; master) HEAD@{0}: reset: moving to c747e6891af419119fd817dc69a2e122084aedae
efc6d21 HEAD@{1}: commit: soft reset
c747e68 (HEAD -&gt; master) HEAD@{2}: reset: moving to c747e6891af419119fd817dc69a2e122084aedae
d8487ca HEAD@{3}: commit: risoluzione bug: non si riesce a pulire la cartella
c747e68 (HEAD -&gt; master) HEAD@{4}: reset: moving to c747e6891af419119fd817dc69a2e122084aedae
959781e HEAD@{5}: commit: Accidenti, perché questo non funziona ultimo tentativo di risoluzione bug
affa90c HEAD@{6}: commit: Risoluzione Finale Finale Bug
2e9570c HEAD@{7}: commit: Risoluzione Finale Bug
4560fc0 HEAD@{8}: commit: Risoluzione Bug
c747e68 (HEAD -&gt; master) HEAD@{9}: commit (merge): risolto conflitto di integrazione
3d01508 HEAD@{10}: commit: add Master World
b300387 (the-ending) HEAD@{11}: checkout: moving from the-middle to master
fb8b2fc (the-middle) HEAD@{12}: commit: add Middle World
b300387 (the-ending) HEAD@{13}: checkout: moving from master to the-middle
b300387 (the-ending) HEAD@{14}: checkout: moving from the-middle to master
b300387 (the-ending) HEAD@{15}: checkout: moving from master to the-middle
b300387 (the-ending) HEAD@{16}: merge the-ending: Fast-forward
a39b9fd HEAD@{17}: checkout: moving from the-ending to master
b300387 (the-ending) HEAD@{18}: checkout: moving from master to the-ending
a39b9fd HEAD@{19}: checkout: moving from the-ending to master
b300387 (the-ending) HEAD@{20}: commit: add byeworld
a39b9fd HEAD@{21}: checkout: moving from master to the-ending
a39b9fd HEAD@{22}: commit (initial): Add helloworld</code></pre><p>Questo è tutto il log dall'inizio dell'esempio dell'articolo precedente. Significa che sarei in grado di recuperare delle cose se avessi fatto un orribile errore?</p><pre><code>$ git checkout d8487ca
Note: checking out 'd8487ca'.
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 &lt;new-branch-name&gt;
HEAD is now at d8487ca... fix bug: Unable to clean folder

$ ls
byeworld clean.txt  helloworld</code></pre><blockquote>N.d.T.<br>La traduzione del risultato del comando git qui sopra è: "Sei nello stato 'HEAD staccato'. Puoi guardarti attorno, fare modifiche sperimentali e inserirle in un commit, e puoi scartare qualunque commit fatto in questo stato senza influenzare alcun branch eseguendo un'altra azione di checkout. <br>Se vuoi creare un nuovo branch per mantenere i commit che hai creato, puoi farlo (ora o successivamente) usando nuovamente l'opzione -b con il comando checkout. Esempio: git checkout -b &lt;nuovo-nome-branch&gt;<br>HEAD è ora a d8487ca... risoluzione bug: non si riesce a pulire la cartella" </blockquote><p>Ecco fatto.</p><p>Congratulazioni, sei un Git Ninja, apprendista ora.</p><p>C'è qualcos'altro che ti piacerebbe sapere? Qualcosa di Git che non ti è chiara? Fammelo sapere qui sotto! Cercherò di spiegartela nel modo nel quale l'ho imparata!</p><p>Soddisfatto? <a href="http://neilkakkar.com/subscribe/" rel="noopener">Non perdere ancora un altro post — iscriviti alla mia mailing list!</a></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Come non avere più paura di Git ]]>
                </title>
                <description>
                    <![CDATA[ Comprendere i meccanismi per eliminare l'incertezza Ti sei mai trovato in questa situazione? Web comic da XKCD [https://imgs.xkcd.com/comics/git.png]Cos'è Git? “È un sistema di controllo di versione.” Perché mi serve? “Per controllare le versioni, sciocchino.” Va bene, va bene, non sono di grande aiuto, non ancora. Ecco l'idea di base: man ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/come-non-aver-piu-paura-di-git/</link>
                <guid isPermaLink="false">638104d06ef95d06118fdfbd</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Roberto Pauletto ]]>
                </dc:creator>
                <pubDate>Mon, 05 Dec 2022 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/11/5f9ca86e740569d1a4ca7de8.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/how-not-to-be-afraid-of-git-anymore-fe1da7415286" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How not to be afraid of GIT anymore</a>
      </p><h4 id="comprendere-i-meccanismi-per-eliminare-l-incertezza">Comprendere i meccanismi per eliminare l'incertezza</h4><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2022/11/xcdstrip-1.png" class="kg-image" alt="xcdstrip-1" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2022/11/xcdstrip-1.png 600w, https://www.freecodecamp.org/italian/news/content/images/size/w1000/2022/11/xcdstrip-1.png 1000w, https://www.freecodecamp.org/italian/news/content/images/2022/11/xcdstrip-1.png 1117w" sizes="(min-width: 720px) 720px" width="1117" height="776" loading="lazy"><figcaption>Ti sei mai trovato in questa situazione? <a href="https://imgs.xkcd.com/comics/git.png">Web comic da XKCD</a></figcaption></figure><h4 id="cos-git">Cos'è Git<strong>?</strong></h4><p>“È un sistema di controllo di versione.”</p><h4 id="perch-mi-serve"><strong>Perché mi serve?</strong></h4><p>“Per controllare le versioni, sciocchino.”</p><p>Va bene, va bene, non sono di grande aiuto, non ancora. Ecco l'idea di base: man mano che i progetti diventano troppo grandi, con troppi collaboratori, diventa impossibile tracciare chi ha fatto cosa e quando. Qualcuno ha introdotto un cambiamento che ha "rotto" l'intero sistema? Come fai a capire di quale cambiamento si tratta? Come tornare indietro, quando le cose funzionavano? Al paese delle meraviglie non compromesso?</p><p>Farò un ulteriore passo avanti: diciamo che c'è un progetto che non ha molti collaboratori, solo un piccolo progetto con te come creatore, manutentore e distributore: crei una nuova funzionalità per questo progetto, che introduce subdoli bug che si scopriranno in seguito. Non ricordi quali modifiche hai apportato al codebase esistente per creare questa nuova funzionalità. Problemi?</p><p>La risposta a tutti questi problemi è gestire le versioni (versioning)! Avere versioni per tutto il codice che è stato scritto ti assicura di sapere chi ha apportato le modifiche, quali modifiche ed esattamente dove, dall'inizio del progetto!</p><p>Ora ti invito a smettere di pensare a git come a una scatola chiusa, aprirlo e scoprire quali tesori ti attendono. Scopri come lavora Git e non avrai mai più problemi a far funzionare le cose. Una volta arrivato in fondo a questo articolo, prometto che ti renderai conto della follia di fare ciò che dice il fumetto XKCD qui sopra. Questo è esattamente ciò che la gestione delle versioni cerca di prevenire.</p><h3 id="come-usare-git"><strong>Come usare Git?</strong></h3><p>Suppongo che tu conosca i comandi di base di Git, o ne abbia sentito parlare, e che li abbia usati almeno una volta. In caso contrario, ecco un vocabolario di base per aiutarti a iniziare.</p><p><strong>r<strong>epository</strong></strong>: un posto per conservare le cose. Con Git indica la cartella in cui si trova il codice</p><p><strong><strong>head: </strong></strong>un "puntatore" all'ultima versione del codice alla quale stai lavorando.</p><p><strong><strong>add: </strong></strong>un'azione per dire a Git di tracciare un file.</p><p><strong><strong>commit: </strong></strong>un'azione per salvare lo stato corrente, in modo che sia possibile visionare questo stato, se necessario</p><p><strong><strong>remote:</strong></strong> un repository che non è locale. Può essere in un'altra cartella oppure nel cloud (ad esempio GitHub); fa sì che altre persone possano facilmente collaborare, poiché non devono ottenere una copia del codice dal tuo sistema, possono semplicemente ottenerla dal cloud. Inoltre ti assicura di avere una copia di riserva nel caso il tuo computer si rompa</p><p><strong><strong>pull: </strong></strong>un'azione per ottenere il codice aggiornato dal repository remoto</p><p><strong><strong>push: </strong></strong>un'azione per inviare il codice aggiornato al repository remoto</p><p><strong><strong>merge: </strong></strong>un'azione per integrare due versioni differenti di codice</p><p><strong><strong>status: </strong></strong>visualizza informazioni circa lo stato corrente del repository </p><h4 id="dove-si-trova-git"><strong>Dove si trova Git?</strong></h4><p>La magia risiede in una cartella nascosta: <code>.git/</code></p><p>In ogni repostitory git, dovresti vedere qualcosa del genere:</p><pre><code>$ tree .git/
.git/
├── HEAD
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags
8 directories, 14 files</code></pre><p>Questo è il modo nel quale Git controlla e gestisce il tuo intero progetto. Esamineremo tutte le parti importanti, una a una.</p><p>Git consiste di 3 parti: l'object store, l'indice e la directory di lavoro.</p><h4 id="object-store"><strong>Object Store</strong></h4><p>Ecco come Git conserva tutto internamente. Per ogni file nel tuo progetto che aggiungi e aggiorni con il comando <code>add</code>, Git genera un hash per il file e conserva il file sotto quell'hash. Per esempio, se ora creo un file <code>helloworld</code> ed eseguo <code>git add helloworld</code> (che dice a Git di aggiungere un file chiamato <code>helloworld</code> all'object store di git), ottengo qualcosa tipo questo:</p><pre><code>$ tree .git/
.git/
├── HEAD
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── index
├── info
│   └── exclude
├── objects
│   ├── a0
│   │   └── 423896973644771497bdc03eb99d5281615b51
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags
9 directories, 16 files</code></pre><p>È stato generato un nuovo oggetto! Per quelli che sono interessati a guardare sotto il cofano, Git usa internamente il comando <code>hash-object</code> in questo modo:</p><pre><code>$ git hash-object helloworld
a0423896973644771497bdc03eb99d5281615b51</code></pre><p>Sì, è lo stesso hash che vediamo all'interno della cartella <code>objects</code>. Perché la sotto-directory con i primi due caratteri dell'hash? <strong>Rende la ricerca più veloce</strong>.</p><p>Successivamente, Git crea un oggetto con il nome dell'hash sopra citato, comprime il file relativo e lo conserva lì. Pertanto puoi anche vedere il contenuto dell'oggetto!</p><pre><code>$ git cat-file a0423896973644771497bdc03eb99d5281615b51 -p
hello world!</code></pre><p>Questo avviene tutto dietro le quinte. Non dovresti mai usare il comando <code><a href="https://git-scm.com/docs/git-cat-file">cat-file</a></code> nelle operazioni quotidiane di aggiunta/aggiornamento. Userai semplicemente il comando <code>add</code> e Git si occuperà del resto.</p><p>Questo è il nostro primo comando git, fatto e finito.</p><p><code><strong><strong>git add</strong></strong></code><strong><strong> crea</strong> un<strong> hash, </strong>comprime il file e aggiunge &nbsp;l'oggetto compresso all'object store<strong>.</strong></strong></p><h4 id="la-directory-di-lavoro">La directory di lavoro</h4><p>Come suggerisce il nome, è dove lavori. Tutti i file che crei e modifichi si trovano nella directory di lavoro. Ho creato un nuovo file, <code>byeworld</code> ed eseguito il comando <code>git status</code>:</p><pre><code>$ git status
On branch master
No commits yet
Changes to be committed:
  (use "git rm --cached &lt;file&gt;..." to unstage)
new file:   helloworld
Untracked files:
  (use "git add &lt;file&gt;..." to include in what will be committed)
byeworld</code></pre><p>I file non tracciati (untracked files) sono i file nella directory di lavoro che non abbiamo detto a git di gestire.</p><p>Se non avessimo fatto nulla nella directory di lavoro avremmo il seguente messaggio:</p><pre><code>$ git status
On branch master
nothing to commit, working tree clean</code></pre><p>che informa che non ci sono cambiamenti e la situazione del codebase è pulita ("nothing to commit, working tree clean"). Ignora per ora le parole "branch" e "commit". Il concetto chiave è che la directory di lavoro è pulita.</p><h4 id="l-indice"><strong>L'indice</strong></h4><p>Questo è il nucleo di Git. Anche noto come staging area. L'indice conserva la corrispondenza dei file con gli oggetti nell'object store. Qui è dove entrano in gioco i commit. Il miglior modo per vederlo è provare!</p><p>Eseguiamo un'azione di commit per l'aggiunta del file <code>helloworld</code></p><pre><code>$ git commit -m "Add helloworld"
[master (root-commit) a39b9fd] Add helloworld
 1 file changed, 1 insertion(+)
 create mode 100644 helloworld</code></pre><p>Ora la nostra alberatura è:</p><pre><code>$ tree .git/
.git/
├── COMMIT_EDITMSG
├── HEAD
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
│       └── heads
│           └── master
├── objects
│   ├── a0
│   │   └── 423896973644771497bdc03eb99d5281615b51
│   ├── a3
│   │   └── 9b9fdd624c35eee08a36077f411e009da68c2f
│   ├── fb
│   │   └── 26ca0289762a454db2ef783c322fedfc566d38
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   └── master
    └── tags
14 directories, 22 files</code></pre><p>Interessante! Abbiamo due nuovi oggetti nell'object store, e alcune cose che ancora non capiamo nelle cartelle <code>logs</code> e <code>refs</code>. Affidiamoci nuovamente al nostro amico <code>cat-file</code>:</p><pre><code>$ git cat-file a39b9fdd624c35eee08a36077f411e009da68c2f -p
tree fb26ca0289762a454db2ef783c322fedfc566d38
author = &lt;=&gt; 1537700068 +0100
committer = &lt;=&gt; 1537700068 +0100
Add helloworld
$ git cat-file fb26ca0289762a454db2ef783c322fedfc566d38 -p
100644 blob a0423896973644771497bdc03eb99d5281615b51 helloworld</code></pre><p>Come puoi intuire il primo oggetto rappresenta i metadati del commit: chi ("author", "committer") ha fatto cosa e perché ("Add helloworld"), con un'alberatura ("tree"). Il secondo oggetto è l'effettiva alberatura. Se conosci il file system di unix, sai esattamente di cosa si tratta.</p><p>L'alberatura (<code>tree</code>) in Git corrisponde al sistema di file di Git. Tutto è un'alberatura (directory) oppure un file (blob), e a ogni commit, Git conserva anche le informazioni sull'alberatura, per dire a sé stesso: questo è come dovrebbe essere la directory di lavoro a questo punto. Nota che l'alberatura punta esattamente a uno specifico oggetto di ciascun file che contiene (l'hash).</p><p>Ora è il momento di parlare dei <strong><strong>branch</strong></strong>! Il nostro primo commit ha aggiunto qualcosa anche a <code>.git/</code>. Ora il nostro interesse si sposta verso <code>.git/refs/heads/master</code>:</p><pre><code>$ cat .git/refs/heads/master 
a39b9fdd624c35eee08a36077f411e009da68c2f</code></pre><p>Ecco quello che ti serve sapere sui branch:</p><blockquote>Un branch in Git è un puntatore mobile e leggero verso uno di questi commit. Il nome del branch predefinito in Git è master.</blockquote><p>Cosa? Mi piace pensare ai branch come a biforcazioni del codice. Vuoi fare qualche modifica ma non vuoi rompere le cose. Decidi di avere una demarcazione più forte di un log di commit, e qui entrano in gioco i branch. <code>master</code> è il branch predefinito, anche usato de-facto come branch di produzione. Da qui, la creazione del file qui sopra. Come puoi dedurre dal contenuto del file, punta al nostro primo commit. Di conseguenza, è un puntatore a un commit.</p><p>Esploriamo ulteriormente. Diciamo che ho creato un nuovo branch:</p><pre><code>$ git branch the-ending
$ git branch
* master
  the-ending</code></pre><p>Eccolo qui, un nuovo branch! Come puoi dedurre, una nuova voce deve essere stata aggiunta a &nbsp;<code>.git/refs/heads/</code> e visto che non ci sono commit ulteriori, dovrebbe puntare anche questo al nostro primo commit, proprio come <code>master</code>.</p><pre><code>$ cat .git/refs/heads/the-ending
a39b9fdd624c35eee08a36077f411e009da68c2f</code></pre><p>Sì, esattamente! Ora ricordi il file <code>byeworld</code>? Questo file non era ancora tracciato, quindi non importa in quale branch ti trovi, quel file sarà sempre lì. Diciamo che voglio spostarmi in questo branch ora, quindi eseguo l'azione di <code>checkout</code> verso il branch.</p><pre><code>$ git checkout the-ending
Switched to branch 'the-ending'
$ git branch
  master
* the-ending</code></pre><p>Ora, dietro le quinte, Git modificherà tutto il contenuto della directory di lavoro per farlo corrispondere al contenuto indicato dal commit del branch. Per ora, visto che è esattamente lo stesso di master, sembra uguale.</p><p>Aggiungo il file <code>byeworld</code> con il comando <code>add</code> ed eseguo il commit.</p><p>Cosa ti aspetti che cambi nella cartella <code>objects</code>?</p><p>Cosa ti aspetti che cambi nella cartella <code>refs/heads</code>?</p><p>Pensaci prima di proseguire.</p><pre><code>$ tree .git/
.git/
├── COMMIT_EDITMSG
├── HEAD
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
│       └── heads
│           ├── master
│           └── the-ending
├── objects
│   ├── 0b
│   │   └── 17be9dbc34c5a5fbb0b94d57680968efd035ca
│   ├── a0
│   │   └── 423896973644771497bdc03eb99d5281615b51
│   ├── a3
│   │   └── 9b9fdd624c35eee08a36077f411e009da68c2f
│   ├── b3
│   │   └── 00387d818adbbd6e7cc14945fdf4c895de6376
│   ├── d1
│   │   └── 8affe001488123b496ceb34d8b13b120ab4cb6
│   ├── fb
│   │   └── 26ca0289762a454db2ef783c322fedfc566d38
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   ├── master
    │   └── the-ending
    └── tags
17 directories, 27 files</code></pre><p>3 nuovi oggetti, 1 per l'aggiunta del file, 2 per il commit! Ha senso? Cosa pensi che contengano gli oggetti?</p><ul><li>I metadati di commit</li><li>Il contenuto dell'oggetto generato da <code>add</code> </li><li>La descrizione dell'alberatura</li></ul><p>L'ultima parte del quadro è: come funzionano questi metadati di commit con i metadati del precedente. Bene, <code>cat-file</code>!</p><pre><code class="language-shell">$ git cat-file 0b17be9dbc34c5a5fbb0b94d57680968efd035ca -p
100644 blob d18affe001488123b496ceb34d8b13b120ab4cb6 byeworld
100644 blob a0423896973644771497bdc03eb99d5281615b51 helloworld
$ git cat-file b300387d818adbbd6e7cc14945fdf4c895de6376 -p
tree 0b17be9dbc34c5a5fbb0b94d57680968efd035ca
parent a39b9fdd624c35eee08a36077f411e009da68c2f
author = &lt;=&gt; 1537770989 +0100
committer = &lt;=&gt; 1537770989 +0100
add byeworld
$ git cat-file d18affe001488123b496ceb34d8b13b120ab4cb6 -p
Bye world!
$ cat .git/refs/heads/the-ending 
b300387d818adbbd6e7cc14945fdf4c895de6376</code></pre><p>Lo vedi? Il puntatore al genitore ("parent")! Esattamente quello che avevi pensato, una lista collegata, che collega i commit insieme!</p><p>Vedi l'implementazione del branch? Punta a un commit, l'ultimo che abbiamo effettuato dopo l'azione di checkout! Naturalmente il master dovrebbe ancora puntare al commit di helloworld, giusto?</p><pre><code>$ cat .git/refs/heads/master
a39b9fdd624c35eee08a36077f411e009da68c2f</code></pre><p>Va bene, abbiamo esaminato tante cose, riassumiamole fino a qui.</p><h3 id="tl-dr"><strong>TL;DR</strong></h3><p>Git lavora con gli oggetti, versioni compresse dei file che chiedi a Git di tracciare.</p><p>Ogni oggetto ha un ID(entificativo), un hash generato da Git in base al contenuto del file a cui si riferisce.</p><p>Ogni volta che esegui il comando <code>add</code> per aggiungere/aggiornare un file, git aggiunge un nuovo oggetto all'object store. <strong>Questa è esattamente la ragione per cui non puoi avere a che fare con file molto grandi in Git</strong> – salva l'intero file ogni volta che esegui il comando <code>add</code> per aggiungere modifiche, non le differenze tra le versioni (contrariamente a quanto si crede comunemente).</p><p>Ogni commit crea 2 oggetti:</p><ol><li><strong>L'alberatura</strong>: un ID per l'alberatura, che agisce esattamente come una directory unix, che punta ad altre alberature (directory) o blob (file). Questo genera la costruzione dell'intera struttura di directory in base agli oggetti presenti al momento. I blob sono rappresentati dagli oggetti correnti creati dal comando <code>add</code>.</li><li><strong>I metadati di <strong>commit</strong></strong>: un ID per i commit, chi ha eseguito il commit, un alberatura che rappresenta il commit, il messaggio di commit e il commit genitore. Forma una struttura a lista collegata che mette insieme i commit.</li></ol><p>I branch sono puntatori a metadati degli oggetti di commit, tutti conservati in <code>.git/refs/heads</code></p><p>Questo è tutto per la comprensione di quanto succede dietro le quinte! <a href="https://medium.freecodecamp.org/now-that-youre-not-afraid-of-git-anymore-here-s-how-to-leverage-what-you-know-11e710c7f37b">Nella prossima parte</a>, esamineremo alcune delle azioni di Git che fanno venire gli incubi alle persone:</p><p><code>reset</code>, <code>merge</code>, <code>pull</code>, <code>push</code>, <code>fetch</code> e come modificano la struttura interna in <code>.git/</code>.</p><p>Altri articoli in questa serie:</p><ul><li><a href="https://www.freecodecamp.org/italian/news/come-non-avere-piu-paura-di-vim/">Come non avere più paura di Vim</a></li><li><a href="https://medium.freecodecamp.org/how-not-to-be-afraid-of-python-anymore-b37b58871795" rel="noopener">Come non avere più paura di Python</a></li></ul><p>Ti è piaciuto? <a href="http://neilkakkar.com/subscribe/" rel="noopener">Non perdere più un post — iscriviti alla mia mailing list!</a></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Il Comando Git Log Spiegato ]]>
                </title>
                <description>
                    <![CDATA[ Cosa fa git log? Il comando git log visualizza tutti i commit nella cronologia di un repository. Nella modalità predefinita, il comando visualizza per ogni commit:  * Secure Hash Algorithm (SHA)  * autore  * data  * messaggio di commit Spostarsi in Git Log Git usa l'impaginatore ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/il-comando-git-log-spiegato/</link>
                <guid isPermaLink="false">63762d088ad83006d39e0941</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Roberto Pauletto ]]>
                </dc:creator>
                <pubDate>Fri, 02 Dec 2022 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/11/5f9c9dfc740569d1a4ca3abd.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/git-log-command/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Git Log Command Explained</a>
      </p><h2 id="cosa-fa-git-log"><strong><strong>Cosa fa git log<strong><strong>?</strong></strong></strong></strong></h2><p>Il comando <code>git log</code> visualizza tutti i commit nella cronologia di un repository.</p><p>Nella modalità predefinita, il comando visualizza per ogni commit:</p><ul><li>Secure Hash Algorithm (SHA)</li><li>autore</li><li>data</li><li>messaggio di commit</li></ul><h2 id="spostarsi-in-git-log"><strong>Spostarsi in<strong> Git Log</strong></strong></h2><p>Git usa l'impaginatore Less del terminale per sfogliare la cronologia dei commit. Puoi spostarti al suo interno usando i seguenti comandi:</p><ul><li>per andare alla riga successiva, usa il tasto &nbsp;j oppure ↓</li><li>per andare alla riga precedente, usa il tasto k oppure ↑</li><li>per spostarti alla videata (pagina) successiva usa la barra spaziatrice oppure il tasto Pagina Giù</li><li>per spostarti alla videata (pagina) precedente, usa il tasto b oppure il tasto Pagina Su</li><li>per uscire dal log, usa il tasto q</li></ul><h2 id="opzioni-di-git-log"><strong>Opzioni di Git Log</strong></h2><p>Puoi personalizzare le informazioni presentate da &nbsp;<code>git log</code> tramite opzioni.</p><h3 id="-oneline"><strong><strong>--oneline</strong></strong></h3><p><code>git log --oneline</code></p><p>L'opzione <code>--oneline</code> fa in modo che &nbsp;<code>git log</code> visualizzi:</p><ul><li>un commit per riga</li><li>i primi sette caratteri del SHA</li><li>il messaggio di commit</li></ul><h3 id="-stat"><strong><strong>--stat</strong></strong></h3><p><code>git log --stat</code></p><p>L'opzione <code>--stat</code> fa in modo che <code>git log</code> visualizzi:</p><ul><li>i file che sono stati modificati in ogni commit</li><li>il numero di righe aggiunte o rimosse</li><li>una riga di riepilogo con il numero totale di file e righe modificati</li></ul><h3 id="-patch-oppure-p"><strong><strong>--patch o</strong>ppure<strong> -p</strong></strong></h3><p><code>git log --patch</code></p><p>oppure nella versione abbreviata</p><p><code>git log -p</code></p><p>L'opzione <code>--patch</code> fa in modo che <code>git log</code> visualizzi:</p><ul><li>i file che hai modificato</li><li>la posizione delle righe che hai aggiunto o rimosso</li><li>le modifiche specifiche che hai effettuato</li></ul><h2 id="visualizzare-un-numero-specifico-di-commit-per-autore"><strong><strong>Vi</strong>sualizzare un numero specifico di commit per autore</strong></h2><p>Per visualizzare un numero specifico di commit eseguiti da un autore nel repository corrente (con l'opzione <code>--pretty</code> per un formato abbellito) si può usare il comando seguente:</p><p><code>git log --pretty=format:"%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)&lt;%an&gt;%Creset" -n {NUMERO_DI_COMMIT} --author="{NOME_AUTORE}" --all</code></p><h3 id="partire-da-uno-specifico-commit"><strong>Partire da uno specifico<strong> commit</strong></strong></h3><p>Per far partire <code>git log</code> da uno specifico commit usa il suo SHA:</p><p><code>git log 7752b22</code></p><p>Questo visualizzerà il commit con SHA 7752b22 e tutti i commit effettuati prima di quello. Puoi aggiungere qualsiasi altra opzione.</p><h3 id="-graph"><strong><strong>--graph</strong></strong></h3><p><code>git log --graph</code></p><p>L'opzione <code>--graph</code> ti consente di visualizzare il tuo <code>git log</code> come un grafico. Per rendere le cose interessanti, puoi aggiungere l'opzione <code>--oneline</code> che hai appreso qui sopra.</p><p><code>git log --graph --oneline</code></p><p>Il risultato sarebbe simile a questo:</p><pre><code class="language-text">* 64e6db0 Update index.md
* b592012 Update Python articles (#5030)
* ecbf9d3 Add latest version and remove duplicate link (#8860)
* 7e3934b Add hint for Compose React Components (#8705)
* 99b7758 Added more frameworks (#8842)
* c4e6a84 Add hint for "Create a Component with Composition" (#8704)
*   907b004 Merge branch 'master' of github.com:freeCodeCamp/guide
|\  
| * 275b6d1 Update index.md
* |   cb74308 Merge branch 'dogb3rt-patch-3'
|\ \  
| |/  
|/|   
| *   98015b6 fix merge conflicts after folder renaming
| |\  
|/ /  
| * fa83460 Update index.md
* | 6afb3b5 rename illegally formatted folder name (#8762)
* | 64b1fe4 CSS3: border-radius property (#8803)</code></pre><p>Uno dei vantaggi dell'utilizzo di questo comando è che ti consente di ottenere un riepilogo di come i commit si sono integrati e come si è formata la cronologia.</p><p>Ci sono molte altre opzioni che potresti usare assieme a <code>--graph</code>. Un paio di queste sono &nbsp;<code>--decorate</code> e <code>--all</code>. Assicurati di provare anche queste. Puoi fare riferimento alla <a href="https://git-scm.com/docs/git-log">documentazione</a> (in lingua inglese) per ulteriori informazioni utili.</p><h3 id="ulteriori-informazioni-in-lingua-inglese-"><strong>Ulteriori<strong> Informa</strong>z<strong>ion</strong>i (in lingua inglese)<strong>:</strong></strong></h3><ul><li><a href="https://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History">Git Basics - Viewing the Commit History</a></li><li><a href="https://git-scm.com/docs/git-log">Git Log</a></li></ul><h2 id="altre-risorse-su-git"><strong>Altre Risorse su<strong><strong><strong> Git</strong></strong></strong></strong></h2><ul><li><a href="https://www.freecodecamp.org/italian/news/git-checkout-spiegato-come-effettuare-il-checkout-modificare-o-cambiare-un-branch-in-git/">Git Checkout</a></li><li><a href="https://www.freecodecamp.org/italian/news/il-comando-git-commit-spiegato/">Git Commit</a></li><li><a href="https://www.freecodecamp.org/italian/news/git-stash-spiegato-come-conservare-temporaneamente-modifiche-locali-in-git/">Git Stash</a></li><li><a href="https://www.freecodecamp.org/italian/news/git-delete-branch-come-rimuovere-un-branch-locale-o-remoto/">Git Branch</a></li></ul> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Git Delete Branch – Come Rimuovere un Branch Locale o Remoto ]]>
                </title>
                <description>
                    <![CDATA[ Git è un popolare sistema di controllo della versione e uno strumento essenziale nella cassetta degli attrezzi di uno sviluppatore. I branch sono una parte potente e integrante del lavoro con Git. In questo articolo, imparerai le basi per quanto riguarda l'eliminazione di branch locali e remoti in Git. Cosa ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/git-delete-branch-come-rimuovere-un-branch-locale-o-remoto/</link>
                <guid isPermaLink="false">637635ca8ad83006d39e0ab5</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Roberto Pauletto ]]>
                </dc:creator>
                <pubDate>Thu, 01 Dec 2022 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/11/elaine-alex-OFMEk4ar9RA-unsplash--1-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/git-delete-branch-how-to-remove-a-local-or-remote-branch/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Git Delete Branch – How to Remove a Local or Remote Branch</a>
      </p><p>Git è un popolare sistema di controllo della versione e uno strumento essenziale nella cassetta degli attrezzi di uno sviluppatore.</p><p>I branch sono una parte potente e integrante del lavoro con Git.</p><p>In questo articolo, imparerai le basi per quanto riguarda l'eliminazione di branch locali e remoti in Git.</p><h2 id="cosa-sono-i-branch-in-git"><strong>Cosa sono i branch in Git?</strong></h2><p>Un branch è un puntatore a un commit.</p><p>I branch di Git sono un'istantanea di un progetto e delle sue modifiche, in uno specifico punto nel tempo.</p><p>Quando si lavora su un grande progetto, c'è un repository principale con tutto il codice, spesso chiamato <code>main</code> o <code>master</code>.</p><p>Usando un branch sei in grado di creare versioni nuove e indipendenti dall'originale progetto di lavoro principale. Potresti creare un branch per fare modifiche, aggiungere una nuova caratteristica, o scrivere dei test quando stai tentando di risolvere un bug. Un nuovo branch ti consente di fare questo senza influenzare il codice principale in alcun modo.</p><p>Riepilogando, i branch ti consentono di fare modifiche al codebase senza influenzare il codice principale, fino a quando sei assolutamente pronto per implementare queste modifiche.</p><p>Questo ti aiuta a mantenere il codebase pulito e organizzato.</p><h2 id="perch-eliminare-i-branch-in-git"><strong>Perché eliminare i branch in Git?</strong></h2><p>Hai creato un branch che contiene del codice per una modifica che vorresti effettuare nel tuo progetto.</p><p>Poi hai incorporato quella modifica o nuova funzionalità nella versione originale del progetto.</p><p>Ciò significa che non è più necessario mantenere o usare quel branch, quindi è buona prassi comunemente usata eliminarlo in modo che non ingombri il tuo codice.</p><h2 id="come-eliminare-un-branch-locale-in-git"><strong>Come eliminare un branch locale in Git</strong></h2><p>I branch locali sono branch sulla tua macchina locale e non influiscono sui branch remoti.</p><p>Il comando per eliminare un branch locale in Git è:</p><pre><code>git branch -d  nome_branch_locale
</code></pre><ul><li><code>git branch</code> è il comando che lavora sui branch.</li><li><code>-d</code> è un'opzione del comando, e un alias per &nbsp;<code>--delete</code> (elimina). &nbsp;Denota che tu vuoi eliminare qualcosa come suggerisce il nome (inglese). </li><li><code>nome_branch_locale</code> è il nome del branch che vuoi rimuovere.</li></ul><p>Diamo un'occhiata a questo in modo un po' più dettagliato con un esempio.</p><p>Per elencare tutti i branch puoi usare il comando seguente:</p><pre><code>git branch
</code></pre><p>Nel mio caso ho due branch, <code>master</code> e <code>test2</code>. Sono attualmente sul branch <code>test2</code> come mostra l'asterisco <code>(*)</code> a fianco del nome del branch:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-4.13.14-PM.png" class="kg-image" alt="Screenshot-2021-08-25-at-4.13.14-PM" width="600" height="400" loading="lazy"></figure><p>Voglio eliminare il branch <code>test2</code> , ma non è possibile eliminare il branch sul quale si è attualmente posizionati.</p><p>Se provassi a farlo, otterresti un errore come questo:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-4.17.50-PM.png" class="kg-image" alt="Screenshot-2021-08-25-at-4.17.50-PM" width="600" height="400" loading="lazy"></figure><p>Quindi, prima di eliminare un branch locale, spostati in un altro branch che NON vuoi eliminare, con il comando <code>git checkout</code> :</p><pre><code>git checkout nome_branch

#dove nome_branch è il nome del branch nel quale vuoi spostarti
#nel mio caso l'altro branch che ho è master quindi eseguo:
#git checkout master
</code></pre><p>Ecco il risultato:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-4.20.40-PM.png" class="kg-image" alt="Screenshot-2021-08-25-at-4.20.40-PM" width="600" height="400" loading="lazy"></figure><p>Ora posso eliminare il branch:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-5.10.13-PM.png" class="kg-image" alt="Screenshot-2021-08-25-at-5.10.13-PM" width="600" height="400" loading="lazy"></figure><p>Il comando che abbiamo appena usato per eliminare un branch locale non funziona sempre.</p><p>Se il branch contiene modifiche al codice che non sono state integrate oppure che si trovano in commit non inviati al repository remoto, l'opzione <code>-d</code> non consente l'eliminazione del branch locale.</p><p>Questo perché i commit non sono visti da alcun altro branch e Git ti sta proteggendo contro la perdita accidentale di dati passati a commit.</p><p>Se provi a fare questo, Git ti mostra un errore, il cui testo tradotto è "errore: Il branch 'test_2' non è stato interamente integrato. Se sei sicuro di volerlo cancellare, esegui 'git branch -D test_2'"</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-5.23.46-PM.png" class="kg-image" alt="Screenshot-2021-08-25-at-5.23.46-PM" width="600" height="400" loading="lazy"></figure><p>Come suggerito dal messaggio di errore, devi usare il flag <code>-D</code> al posto di <code>-d</code>:</p><pre><code>git branch -D nome_branch_locale
</code></pre><p>L'opzione <code>-D</code> maiuscola (che è un alias per <code>--delete --force</code> – eliminazione forzata), forza l'eliminazione del branch locale a prescindere dallo stato delle integrazioni.</p><p>Nota che <strong>dovresti usare questo comando con cautela</strong>, visto che non ti verrà richiesta conferma per questa azione.</p><p>Usalo solo se se sei assolutamente sicuro che vuoi eliminare un branch locale.</p><p>Se non hai integrato il branch in un altro branch locale o inviato il commit a un branch remoto nel codebase, rischierai di perdere tutte le modifiche che hai effettuato.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-5.33.41-PM.png" class="kg-image" alt="Screenshot-2021-08-25-at-5.33.41-PM" width="600" height="400" loading="lazy"></figure><h2 id="come-eliminare-un-branch-remoto-in-git"><strong>Come eliminare un branch remoto in Git</strong></h2><p>I branch remoti sono separati da quelli locali.</p><p>Sono dei repository ospitati in un server remoto ai quali si può accedere, al contrario dei branch locali, che sono repository nel tuo sistema locale.</p><p>Il comando per eliminare un branch remoto è:</p><pre><code>git push nome_remoto -d nome_branch_remoto
</code></pre><ul><li>Invece di usare il comando <code>git branch</code>, utilizzato per i branch locali, puoi eliminare un branch remoto con il comando <code>git push</code>.</li><li>Poi specifichi il nome del repository remoto, che nella maggior parte dei casi è <code>origin</code>.</li><li><code>-d</code> è l'opzione per l'eliminazione, alias per <code>--delete</code>.</li><li><code>nome_branch_remoto</code> è il branch remoto che vuoi eliminare.</li></ul><p>Ora vediamo un esempio di come eliminare un branch remoto.</p><p>Per visualizzare tutti i &nbsp;branch remoti usa questo comando:</p><pre><code>git branch -a
</code></pre><p>L'opzione <code>-a</code> (a alias per <code>--all</code> - tutto-) mostra tutti i branch, sia locali che remoti.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-7.35.31-PM.png" class="kg-image" alt="Screenshot-2021-08-25-at-7.35.31-PM" width="600" height="400" loading="lazy"></figure><p>Ho due branch locali, chiamati <code>master</code> e <code>test</code> e due remoti, <code>origin/master</code> e <code>origin/test</code>.</p><p>L'opzione <code>-r</code>, un alias per <code>--remotes</code> (remoti), mostra <em>solo</em> i branch nei repository remoti.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-7.37.12-PM.png" class="kg-image" alt="Screenshot-2021-08-25-at-7.37.12-PM" width="600" height="400" loading="lazy"></figure><p>Voglio eliminare il branch remoto <code>origin/test</code> , quindi uso il comando:</p><pre><code>git push origin -d test
</code></pre><p>Risultato:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-7.39.34-PM.png" class="kg-image" alt="Screenshot-2021-08-25-at-7.39.34-PM" width="600" height="400" loading="lazy"></figure><p>Il comando ha eliminato il branch <code>test</code> nel repository chiamato <code>origin</code>.</p><p>Il branch <code>origin/test</code> sul repository remoto non è più presente:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-7.42.01-PM.png" class="kg-image" alt="Screenshot-2021-08-25-at-7.42.01-PM" width="600" height="400" loading="lazy"></figure><h2 id="conclusione"><strong>Conclusione</strong></h2><p>Ora sai come eliminare branch locali e remoti in Git.</p><p>Se vuoi saperne di più su Git, puoi vedere i seguenti corsi nel canale YouTube di freeCodeCamp:</p><ul><li>Per imparare come impostare Git, &nbsp;per una panoramica dei comandi Git più importanti, e sul tipico flusso di lavoro di git: <a href="https://www.youtube.com/watch?v=RGOj5yH7evk">Git and GitHub for beginners - Crash course</a> (in lingua inglese).</li><li>Per esaminare più in profondità i branch e come funzionano: <a href="https://www.youtube.com/watch?v=e2IbNHi4uCI&amp;t=6s">Git Branches Tutorial</a> (in lingua inglese).</li></ul><p>Grazie per aver letto questo articolo e buon apprendimento!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Git Branch Spiegato: Come Eliminare, Cambiare, Creare e Rinominare un Branch in Git ]]>
                </title>
                <description>
                    <![CDATA[ Git Branch È una funzionalità che ti consente di creare nuovi branch di un progetto per provare idee, isolare nuove funzionalità, oppure sperimentare senza impatti sul progetto principale. Sommario  * Visualizzare i branch  * Passare da un branch a un altro  * Creare un nuovo branch  ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/git-branch-spiegato-come-eliminare-cambiare-creare-e-rinominare-un-branch-in-git/</link>
                <guid isPermaLink="false">636f782f431671062c019849</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Roberto Pauletto ]]>
                </dc:creator>
                <pubDate>Tue, 29 Nov 2022 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/11/5f9c9cda740569d1a4ca348c.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/git-branch-explained-how-to-delete-checkout-create-and-rename-a-branch-in-git/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Git Branch Explained: How to Delete, Checkout, Create, and Rename a branch in Git</a>
      </p><h2 id="git-branch"><strong><strong><strong>Git Branch</strong></strong></strong></h2><p>È una funzionalità che ti consente di creare nuovi branch di un progetto per provare idee, isolare nuove funzionalità, oppure sperimentare senza impatti sul progetto principale.</p><p><strong><strong>Sommario</strong></strong></p><ul><li><a href="#visualizzare-i-branch">Visualizzare i branch</a></li><li><a href="#passare-da-un-branch-a-un-altro">Passare da un branch a un altro</a></li><li><a href="#creare-un-nuovo-branch">Creare un nuovo branch</a></li><li><a href="#rinominare-un-branch">Rinominare un branch</a></li><li><a href="#eliminare-un-branch">Eliminare un branch</a></li><li><a href="#confrontare-dei-branch">Confrontare dei branch</a></li><li><a href="#aiuto-per-git-branch">Aiuto per git branch</a></li><li><a href="#ulteriori-informazioni">Ulteriori informazioni</a></li></ul><h3 id="visualizzare-i-branch"><strong>Visualizzare i branch</strong></h3><p>Per visualizzare i branch in un repository Git esegui il comando:</p><pre><code class="language-shell">git branch</code></pre><p>Per vedere sia i branch tracciati su remoto che i branch locali esegui il comando:</p><pre><code class="language-shell">git branch -a</code></pre><p>Ci sarà un asterisco (*) a fianco del branch sul quale ti trovi attualmente.</p><p>Ci sono svariate opzioni che puoi specificare con <code>git branch</code> per vedere informazioni differenti. Per maggiori dettagli sui branch puoi usare l'opzione <code>-v</code> (oppure <code>-vv</code> o <code>--verbose</code>). L'elenco dei branch includerà a fianco del nome il valore SHA-1 e la riga di oggetto del commit per l'<code>HEAD</code> di ogni branch.</p><p>Puoi usare l'opzione <code>-a</code> (oppure <code>--all</code>) per mostrare tutti i branch di un repository, sia locali che remoti. Se vuoi vedere solo i branch remoti usa l'opzione <code>-r</code> (oppure<code>--remotes</code>).</p><h3 id="passare-da-un-branch-a-un-altro"><strong><strong>Passare da un branch a un altro</strong></strong></h3><p>Per passare da un branch a un altro branch esistente (azione di checkout) esegui il comando:</p><pre><code class="language-shell">git checkout NOME-BRANCH</code></pre><p>In genere Git non ti lascerà uscire per passare a un altro branch, a meno che la tua directory di lavoro sia pulita, in quanto perderesti qualsiasi modifica fatta che non sia stata soggetta a commit. Hai tre opzioni per gestire le tue modifiche:</p><ol><li>sbarazzartene (vedi <a href="https://www.freecodecamp.org/italian/news/git-checkout-spiegato-come-effettuare-il-checkout-modificare-o-cambiare-un-branch-in-git/">Git checkout per dettagli</a>) oppure</li><li>effettuare un'azione di commit (vedi <a href="https://www.freecodecamp.org/italian/news/il-comando-git-commit-spiegato/">Git commit per dettagli</a>) oppure</li><li>accantonarle (vedi <a href="https://www.freecodecamp.org/italian/news/git-stash-spiegato-come-conservare-temporaneamente-modifiche-locali-in-git/">Git stash per dettagli</a>).</li></ol><h3 id="creare-un-nuovo-branch"><strong><strong><strong>Crea</strong></strong>r<strong><strong>e </strong></strong>un nuovo<strong><strong> </strong></strong>b<strong><strong>ranch</strong></strong></strong></h3><p>Per creare un nuovo branch esegui il comando:</p><pre><code class="language-shell">git branch NOME-NUOVO-BRANCH</code></pre><p>Nota che questo comando crea solamente il nuovo branch. Per spostarti devi eseguire il comando <code>git checkout NOME-NUOVO-BRANCH</code>.</p><p>Esiste una scorciatoia per creare e passare direttamente a un nuovo branch. Puoi eseguire <code>git checkout</code> con l'opzione <code>-b</code> (per branch). I seguenti comandi fanno la stessa cosa:</p><pre><code class="language-shell"># Metodo a due passaggi
git branch NOME-NUOVO-BRANCH
git checkout NOME-NUOVO-BRANCH

# Scorciatoia
git checkout -b NOME-NUOVO-BRANCH</code></pre><p>Quando crei un nuovo branch, verranno inclusi tutti i commit del branch genitore. Il branch genitore è quello nel quale di trovi quando crei il nuovo branch.</p><h3 id="rinominare-un-branch"><strong><strong><strong>R</strong></strong>inominare un<strong><strong> </strong></strong>b<strong><strong>ranch</strong></strong></strong></h3><p>Per rinominare un branch esegui il comando:</p><pre><code class="language-shell">git branch -m VECCHIO-NOME-BRANCH NUOVO-NOME-BRANCH

# Alternativa
git branch --move VECCHIO-NOME-BRANCH NUOVO-NOME-BRANCH</code></pre><h3 id="eliminare-un-branch"><strong>Eliminare un<strong><strong> </strong></strong>b<strong><strong>ranch</strong></strong></strong></h3><p>Git non ti consente di eliminare il branch sul quale ti trovi attualmente. Prima devi passare a un altro branch, quindi eseguire il comando:</p><pre><code class="language-shell">git branch -d BRANCH-DA-ELIMINARE

# Alternativa:
git branch --delete BRANCH-DA-ELIMINARE</code></pre><p>Il branch nel quale passi prima dell'eliminazione fa la differenza. Git solleverà un errore se su tutte le modifiche nel branch che stai tentando di eliminare non è stata eseguita un'azione di merge all'interno del branch corrente. Puoi inibire questo comportamento e forzare Git a eliminare il branch con l'opzione <code>-D</code> (nota la lettera maiuscola) oppure usando l'opzione <code>--force</code> con <code>-d</code> oppure <code>--delete</code>:</p><pre><code class="language-shell">git branch -D BRANCH-DA-ELIMINARE

# Alternativa
git branch -d --force BRANCH-DA-ELIMINARE
git branch --delete --force BRANCH-DA-ELIMINARE</code></pre><h3 id="confrontare-dei-branch"><strong>Confrontare<strong><strong> </strong></strong>dei b<strong><strong>ranch</strong></strong></strong></h3><p>Puoi confrontare dei branch con il comando <code>git diff</code>:</p><pre><code class="language-shell">git diff PRIMO-BRANCH..SECONDO-BRANCH</code></pre><p>Vedrai un risultato con testo colorato per evidenziare le modifiche tra i branch. Per tutte le righe modificate, la versione <code>SECONDO-BRANCH</code> avrà una riga verde che inizia con un &nbsp;”+”, e la versione <code>PRIMO-BRANCH</code> avrà una riga rossa che inizia con un &nbsp;”-“. Se non vuoi che Git visualizzi due righe per ogni modifica, puoi usare l'opzione <code>--color-words</code> (colora parole), nel qual caso Git mostrerà una riga con il testo eliminato in rosso e il testo aggiunto in verde.</p><p>Se vuoi vedere un elenco di tutti i branch sui quali è stata eseguita un'azione di merge per tutte le modifiche verso il branch corrente (in altre parole se il tuo branch corrente include tutte le modifiche fatte negli altri branch in elenco), esegui il comando <code>git branch --merged</code>.</p><h3 id="aiuto-per-git-branch"><strong>Aiuto per<strong><strong> Git </strong></strong>b<strong><strong>ranch</strong></strong></strong></h3><p>Se non ti ricordi come si usa un'opzione, oppure vuoi esplorare altre funzionalità del comando <code>git branch</code>, puoi eseguire uno qualunque di questi comandi:</p><pre><code class="language-shell">git help branch
git branch --help
man git-branch</code></pre><h3 id="ulteriori-informazioni"><strong>Ulteriori informazioni</strong></h3><ul><li><a href="https://www.freecodecamp.org/italian/news/la-guida-definitiva-a-git-merge-e-git-rebase/">Il comando <code>git merge</code> </a></li><li><a href="https://www.freecodecamp.org/italian/news/git-checkout-spiegato-come-effettuare-il-checkout-modificare-o-cambiare-un-branch-in-git/">Il comando <code>git checkout</code> </a></li><li><a href="https://www.freecodecamp.org/italian/news/il-comando-git-commit-spiegato/">Il comando <code>git commit</code> </a></li><li><a href="https://www.freecodecamp.org/italian/news/git-stash-spiegato-come-conservare-temporaneamente-modifiche-locali-in-git/">Il comando <code>git stash</code> </a></li><li>Documentazione di Git: <a href="https://git-scm.com/docs/git-branch" rel="nofollow">branch</a></li></ul> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ La Guida Definitiva a Git Merge e Git Rebase ]]>
                </title>
                <description>
                    <![CDATA[ Benvenuto nella nostra guida definitiva ai comandi git merge e git rebase. Questo tutorial ti insegnerà tutto quello che devi sapere per combinare più branch con Git. Git Merge Il comando git merge incorporerà nel tuo branch corrente tutte le modifiche fatte sul codice in un branch diverso, sotto forma ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/la-guida-definitiva-a-git-merge-e-git-rebase/</link>
                <guid isPermaLink="false">6370aefe431671062c019a0f</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Roberto Pauletto ]]>
                </dc:creator>
                <pubDate>Mon, 21 Nov 2022 11:18:53 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/11/5f9c9f05740569d1a4ca4068.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/the-ultimate-guide-to-git-merge-and-git-rebase/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The Ultimate Guide to Git Merge and Git Rebase</a>
      </p><p>Benvenuto nella nostra guida definitiva ai comandi <code>git merge</code> e <code>git rebase</code>. Questo tutorial ti insegnerà tutto quello che devi sapere per combinare più branch con Git.</p><h2 id="git-merge"><strong>Git Merge</strong></h2><p>Il comando <code>git merge</code> incorporerà nel tuo branch corrente tutte le modifiche fatte sul codice in un branch diverso, sotto forma di nuovo commit.</p><p>La sintassi del comando è la seguente:</p><pre><code class="language-shell">git merge NOME-BRANCH</code></pre><p>Per esempio, se stai attualmente lavorando in un branch chiamato <code>dev</code> e vorresti incorporare tutte le nuove modifiche fatte in un branch chiamato <code>new-features</code>, dovrai eseguire il seguente comando:</p><pre><code class="language-shell">git merge new-features</code></pre><p><strong><strong><strong><strong>Not</strong></strong></strong>a<strong><strong><strong>:</strong></strong></strong></strong> Git non ti consentirà l'azione di merge se nel tuo branch corrente ci sono modifiche per le quali non hai ancora eseguito l'azione di commit. Per gestire queste modifiche puoi in alternativa:</p><ul><li>Creare un nuovo branch ed eseguire il commit delle modifiche</li></ul><pre><code class="language-shell">git checkout -b nome-nuovo-branch
git add .
git commit -m "&lt;il tuo messaggio di commit&gt;"</code></pre><ul><li>Accantonarle</li></ul><pre><code class="language-shell">git stash               # accantona nell'area di stash
git merge new-features  # esegui le tue incorporazioni
git stash pop           # recupera nuovamente la modifiche nella tua alberatura di lavoro</code></pre><ul><li>Abbandonare tutte le modifiche</li></ul><pre><code class="language-shell">git reset --hard        # elimina tutte le modifiche in sospeso</code></pre><h2 id="git-rebase"><strong>Git Rebase</strong></h2><p>L'azione di rebase di un branch in Git è un modo per spostare un intero branch in un altro punto nell'alberatura. L'esempio più semplice è spostare un branch più in alto nell'alberatura. Diciamo che abbiamo un branch che si discosta dal branch master al punto A:</p><pre><code class="language-text">        /o-----o---o--o-----o--------- branch
--o-o--A--o---o---o---o----o--o-o-o--- master</code></pre><p>Quando esegui l'azione di rebase puoi spostarlo in questo modo:</p><pre><code class="language-text">                                   /o-----o---o--o-----o------ branch
--o-o--A--o---o---o---o----o--o-o-o master</code></pre><p>Per effettuare il rebase, assicurati di avere tutti i commit che vuoi portarti nel rebase nel tuo branch master. Entra (checkout) nel branch per il quale vuoi effettuare l'azione di rebase ed esegui <code>git rebase master</code> (dove master è il branch verso il quale vuoi effettuare lo spostamento).</p><p>È anche possibile effettuare il rebase su un branch diverso, in modo che, per esempio, un branch basato su un altro branch (chiamiamolo "feature") sia spostato sul master:</p><pre><code class="language-text">                            /---o-o branch
           /---o-o-o-o---o--o------ feature
----o--o-o-A----o---o--o-o-o--o--o- master</code></pre><p>Dopo <code>git rebase master branch</code> oppure <code>git rebase master</code> se sei entrato nel branch, otterrai:</p><pre><code class="language-text">           /---o-o-o-o---o--o------ feature
----o--o-o-A----o---o--o-o-o--o--o- master
                                  \---o-o branch</code></pre><h3 id="git-rebase-interattivo-nella-console"><strong>Git rebase interattivo nella console</strong></h3><p>Puoi usare <code>git rebase</code> con l'opzione <code>-i</code>, iniziando in questo modo un'azione interattiva nella console, con un elenco di commit che puoi scegliere, modificare, o scartare nel rebase:</p><ul><li>Digita <code>git rebase -i HEAD~5</code>, con l'ultimo numero che corrisponde a quanti commit vuoi esaminare all'indietro rispetto al più recente.</li><li>Si aprirà il tuo editor predefinito con un testo che puoi iniziare a modificare</li><li>Sul lato sinistro, puoi sovrascrivere la parola &nbsp;<code>pick</code> con uno dei comandi qui sotto. Se vuoi raggruppare un commit con uno precedente e scartare il messaggio di commit, inserisci <code>f</code> al posto di <code>pick</code> per quel commit.</li><li>Salva ed esci dall'editor di testo, a questo punto git inizierà a rieseguire i commit utilizzando i comandi di rebase specificati al punto precedente. </li><li>Se il rebase si ferma, esegui gli aggiustamenti necessari, poi usa <code>git rebase --continue</code> fino a che l'azione di rebase non si conclude positivamente.</li><li>In caso di successo, devi forzare l'invio delle tue modifiche con <code>git push -f</code> per aggiungere la versione dopo il rebase al tuo repository remoto.</li><li>Se c'è un conflitto nell'azione di merge, ci diversi modi per sistemarlo, compreso il seguire le istruzioni di <a href="https://docs.github.com/en/get-started/using-git/resolving-merge-conflicts-after-a-git-rebase">questa guida</a> (in lingua inglese). Un modo è aprire i file in un editor di testo ed eliminare le parti di codice indesiderate. Poi usa <code>git add &lt;nome file&gt;</code> seguito da <code>git rebase --continue</code>. Puoi saltare il commit che causa conflitto digitando <code>git rebase --skip</code>, oppure interrompere l'azione di rebase digitando nella console <code>git rebase --abort</code>.</li></ul><blockquote>N.d.T.<br>La descrizione dei comandi di rebase nel testo che segue è stata tradotta per una migliore comprensione dell'esposizione, ma nella realtà è in lingua inglese.</blockquote><pre><code class="language-text">pick 452b159 &lt;messaggio per questo commit&gt;
pick 7fd4192 &lt;messaggio per questo commit&gt;
pick c1af3e5 &lt;messaggio per questo commit&gt;
pick 5f5e8d3 &lt;messaggio per questo commit&gt;
pick 5186a9f &lt;messaggio per questo commit&gt;

# Rebase 0617e63..5186a9f onto 0617e63 (30 comandi)
#
# Comandi:
# p, pick = usa il commit
# r, reword = usa il commit, ma interrompi la modifica del  messaggio di commit.
# e, edit = usa il commit, ma interrompi l'amend e interrompi la modifica del messaggio di commit.
# s, squash = usa il commit, uniscilo al commit precedente e interrompi la modifica del messaggio di commit
# f, fixup = come "squash", ma scarta il messaggio di questo commit, pertanto non interrompe.
# x, exec = esegui il comando (il resto della riga) usando la shell
# d, drop = rimuovi il commit
#
# Queste righe possono essere riordinate, vengono eseguite dall'inizio alla fine. 
#
# Se elimini una riga di commit QUEL COMMIT VERRÀ PERDUTO.
#
# Tuttavia, se elimini tutto, l'azione di rebase verrà interrotte.
#
# Nota che i commit vuoti sono commentati (esclusi)</code></pre><p></p><h2 id="conflitti-in-merge"><strong>Conflitti in Merge</strong></h2><p>Un conflitto in merge è quando esegui commit in branch separati che modificano la stessa riga in maniera conflittuale. Se questo accade, Git non saprà quale versione del file mantenere e stamperà un messaggio di errore simile al seguente:</p><pre><code class="language-shell">CONFLICT (content): Merge conflict in resumé.txt Automatic merge failed; fix conflicts and then commit the result.</code></pre><p>Se osservi il file <code>resumé.txt</code> citato nel messaggio nel tuo editor testi, vedrai dove avviene il conflitto:</p><pre><code class="language-shell">&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD
Address: 808 South Street
=======
Address: 505 North Street
&gt;&gt;&gt;&gt;&gt;&gt;&gt; updated_address</code></pre><p>Git ha aggiunto alcune righe al file:</p><ul><li><code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD</code></li><li><code>=======</code></li><li><code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; updated_address</code></li></ul><p>Pensa a <code>=======</code> come la riga che divide il conflitto. Tutto quello che sta fra <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD</code> e <code>=======</code> è il contenuto nel branch corrente al quale il riferimento HEAD sta puntando. Mentre tutto quello che sta tra &nbsp;<code>=======</code> e <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; updated_address</code> è il contenuto nel branch che si sta incorporando, <code>updated_address</code>.</p><h2 id="git-merge-vs-git-rebase"><strong>Git Merge vs Git Rebase</strong></h2><p>Sia <code>git merge</code> che <code>git rebase</code> sono comandi molto utili, e uno non è migliore dell'altro. Tuttavia ci sono alcune differenze molto importanti tra i due comandi che tu e la tua squadra dovreste tenere in considerazione.</p><p>Ogniqualvolta <code>git merge</code> viene eseguito, viene creato un commit di merge supplementare. Ogni volta che lavori nel tuo repository locale, avere troppi commit di merge potrebbe rendere confusa la cronologia dei commit. Un modo per evitare il commit di merge è usare invece <code>git rebase</code>.</p><p><code>git rebase</code> è una funzionalità molto potente. Ciò detto, è anche <strong>rischiosa</strong> se non usata nel giusto modo. <code>git rebase</code> altera la cronologia dei commit, quindi usalo con cautela. Se il rebase viene fatto nel repository remoto, allora può creare molti problemi quando gli altri sviluppatori tentano di ottenere le ultime modifiche al codice dal repository remoto. Ricorda di eseguire <code>git rebase</code> in un repository locale.</p><p>Questo è tutto ciò che devi sapere per eseguire al meglio merge e rebase.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Il Comando Git Commit Spiegato ]]>
                </title>
                <description>
                    <![CDATA[ Il comando git commit salverà all'interno del repository locale tutte le modifiche presenti nell'area di stage, oltre a una breve descrizione inserita dall'utente . I commit sono al centro dell'utilizzo di Git. Puoi pensare a un commit come un'istantanea del tuo progetto, in cui una sua nuova versione viene creata ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/il-comando-git-commit-spiegato/</link>
                <guid isPermaLink="false">6370af8c431671062c019a18</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Roberto Pauletto ]]>
                </dc:creator>
                <pubDate>Mon, 14 Nov 2022 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/11/5f9c9e64740569d1a4ca3cdf.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/git-commit-command-explained/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Git Commit Command Explained</a>
      </p><p>Il comando <code>git commit</code> salverà all'interno del repository locale tutte le modifiche presenti nell'area di stage, oltre a una breve descrizione inserita dall'utente .</p><p>I commit sono al centro dell'utilizzo di Git. Puoi pensare a un commit come un'istantanea del tuo progetto, in cui una sua nuova versione viene creata nel repository corrente. Due importanti caratteristiche dei commit sono:</p><ul><li>è possibile recuperare la modifiche inserite in un commit successivamente, oppure riportare il progetto a una versione referenziata da un certo commit (<a href="https://www.freecodecamp.org/italian/news/git-checkout-spiegato-come-effettuare-il-checkout-modificare-o-cambiare-un-branch-in-git/">vedi Git checkout</a>)</li><li>se più commit modificano diverse parti del progetto, non si sovrascrivono anche se gli autori del commit non sono consapevoli l'uno dell'altro. Questo è uno dei vantaggi dell'utilizzo di Git rispetto a strumenti come Dropbox o Google Drive.</li></ul><h2 id="opzioni"><strong>Opzioni</strong></h2><p>Esistono diverse opzioni che puoi includere con <code>git commit</code>. Tuttavia, questa guida coprirà solo le due opzioni più comuni. Per un elenco più esaustivo di opzioni, consulta la <a href="https://git-scm.com/docs/git-commit">documentazione di GIT</a>.</p><h3 id="l-opzione-m"><strong>L'Opzione -m </strong></h3><p>L'opzione <code>-m</code> è quella più comune usata con <code>git commit</code>. La <code>-m</code> sta per messaggio. Quando si chiama <code>git commit</code>, occorre includere un messaggio. Il messaggio dovrebbe essere una breve descrizione delle modifiche comprese nel commit. Il messaggio dovrebbe essere alla fine del comando e deve essere racchiuso tra virgolette <code>" "</code>.</p><p>Un esempio di come usare l'opzione <code>-m</code> :</p><pre><code class="language-shell">git commit -m "Il mio messaggio"</code></pre><p>Il risultato nel tuo terminale dovrebbe essere circa questo:</p><pre><code class="language-shell">[master 13vc6b2] Il mio messaggio
 1 file changed, 1 insertion(+)</code></pre><p><strong><strong><strong><strong>NOT</strong></strong></strong>A<strong><strong><strong>:</strong></strong></strong></strong> Se l'opzione <code>-m</code> non è stata passata al comando <code>git commit</code>, ti verrà presentata la richiesta di aggiungere un messaggio usando il tuo editor di testo predefinito – vedi "Usare messaggi di commit dettagliati" qui sotto.</p><h3 id="l-opzione-a"><strong>L'Opzione -a </strong></h3><p>Un'altra popolare opzione è <code>-a</code>. La <code>-a</code> sta per all (tutto). Questa opzione fa sì che tutti i file modificati siano passati all'area di stage per il commit. Tuttavia se ci sono nuovi file non tracciati, con l'opzione <code>-a</code> non verranno considerati, in quanto sono soggetti all'azione di commit solo i file noti al repository Git.</p><p>Per esempio:</p><p>Diciamo che hai un file <code>README.md</code> che è già stato incluso in un commit al tuo repository. Se apporti modifiche a questo file, puoi usare l'opzione <code>-a</code> nel comando di commit per aggiungere le modifiche al tuo repository. Tuttavia, cosa succede se hai anche creato un nuovo file chiamato<code>index.html</code> che non hai ancora aggiunto al repository? L'opzione <code>-a</code> non lo porterà nell'area di stage, in quanto non esiste nel repository. Quando vengono aggiunti nuovi file, si dovrebbe usare il comando <code>git add</code> per passare i nuovi file nell'area di stage affinché possano essere successivamente soggetti all'azione di commit.</p><p>Un esempio di come usare l'opzione <code>-a</code>:</p><pre><code class="language-shell">git commit -am “Le mie nuove modifiche”</code></pre><p>Il risultato nel tuo terminale dovrebbe essere circa questo:</p><pre><code class="language-shell">[master 22gc8v1] Le mie nuove modifiche
 1 file changed, 1 insertion(+)</code></pre><h2 id="usare-messaggi-di-commit-dettagliati"><strong>Usare messaggi di commit dettagliati</strong></h2><p>Anche se <code>git commit -m "messaggio di commit"</code> va bene, può essere utile fornire informazioni più dettagliate e sistematiche.</p><p>Se l'azione di commit viene eseguita senza l'opzione <code>-m</code>, git aprirà il tuo editor di testo predefinito con un nuovo file, che include come commento un elenco di tutti i file/modifiche che saranno soggetti al commit. Poi puoi inserire il tuo messaggio di commit dettagliato (la prima riga viene considerata come oggetto del messaggio) e il commit verrà eseguito quando salvi/chiudi il file.</p><p>Ricorda che:</p><ul><li>È una pratica standard mantenere la lunghezza di ciascuna riga del messaggio di commit entro i 72 caratteri.</li><li>Va benissimo, ed è addirittura consigliato, scrivere messaggi di commit su più righe.</li><li>Puoi anche fare riferimento ad altre issue (problemi) o pull request (richieste di modifica) nel tuo messaggio di commit. GitHub alloca un numero di riferimento per tutte le issue e pull request. Quindi, se per esempio vuoi fare riferimento alla pull request #788, lo puoi fare sia nella riga di oggetto che nel corpo del messaggio.</li></ul><h3 id="l-opzione-amend"><strong>L'opzione —amend</strong></h3><p>L'opzione <code>--amend</code> ti consente di modificare il tuo ultimo commit. Diciamo che hai appena eseguito un commit e ti accorgi di un errore nel messaggio che hai inserito. Puoi comodamente modificare il commit più recente usando il comando:</p><pre><code class="language-shell">git commit --amend -m "un messaggio di commit aggiornato"</code></pre><p>Se ti sei dimenticato di includere un file nel commit:</p><pre><code class="language-shell">git add NOME-FILE-DIMENTICATO
git commit --amend -m "un messaggio di commit aggiornato"

# Se non devi cambiare il messaggio di commit, usa l'opzione --no-edit
git add NOME-FILE-DIMENTICATO
git commit --amend --no-edit</code></pre><p>I commit prematuri avvengono continuamente nel corso del tuo sviluppo quotidiano. È facile dimenticare di passare un file all'area di stage o come formattare correttamente il tuo messaggio di commit. L'opzione <code>--amend</code> è un modo conveniente per correggere questi errori minori. Questo comando sostituirà il vecchio messaggio di commit con quello aggiornato specificato nel comando.</p><p>I commit modificati con l'opzione <code>--amend</code> sono in realtà commit nuovi e il commit precedente non sarà più nel tuo branch corrente. Quando lavori assieme ad altri, dovresti cercare di evitare di modificare un commit se quest'ultimo è già stato inviato al repository remoto.</p><p>Con <code>--amend</code>, una delle altre opzioni più utili che potresti usare è <code>--author</code> che ti consente di modificare l'autore dell'ultimo commit che hai eseguito. Immagina una situazione nella quale non hai propriamente impostato il tuo nome o email nella configurazione di git, ma hai già eseguito un commit. Con l'opzione <code>--author</code> puoi semplicemente modificarli senza resettare l'ultimo commit.</p><pre><code class="language-text">git commit --amend --author="John Doe &lt;johndoe@email.com&gt;"</code></pre><h3 id="l-opzione-v-oppure-verbose"><strong>L'opzione -v oppure —verbose </strong></h3><p>L'opzione <code>-v</code> oppure<code>--verbose</code> viene usata senza l'opzione <code>-m</code> e può essere utile quando vuoi inserire un messaggio di commit con il tuo editor testi predefinito ed essere in grado di vedere le modifiche che hai effettuato per questo commit. Il comando apre il tuo editor di testo predefinito con un modello di messaggio di commit <em>assieme</em> a<em> </em>una copia delle modifiche effettuate per questo commit. Le modifiche, o diff, non saranno incluse nel messaggio di commit ma ti offrono un buon metodo per fare riferimento alle tue modifiche mentre le descrivi nel messaggio di commit.</p><h2 id="come-raggruppare-pi-commit-in-uno"><strong>Come raggruppare più commit in uno</strong></h2><p>Questa è una caratteristica fantastica di <code>rebase</code> che può essere utilizzata in modalità interattiva. Per raggruppare gli ultimi <em>n </em>commit in uno, esegui il comando seguente:</p><pre><code class="language-text">git rebase -i HEAD~n</code></pre><p>Questo farà aprire l'editor di testo con un contenuto simile al seguente:</p><pre><code class="language-text">pick commit_1
pick commit_2
pick commit_3
...
pick commit_n
# Alcuni commenti</code></pre><p>Lascia da parte il primo commit, e per i restanti commit che vuoi raggruppare modifica il corrispondente testo da <code>pick</code> a <code>squash</code>. Salva ed esci dall'editor.</p><p>Per esempio se avessi voluto raggruppare gli ultimi tre commit, avresti prima eseguito <code>git rebase -i HEAD~3</code> quindi avresti modificato i tuoi commit in questo modo:</p><pre><code class="language-text">pick dd661ba Commit 1
squash 71f5fee Commit 2
squash f4b4bf1 Commit 3</code></pre><p>Se hai già inviato i commit a un repository remoto prima di raggrupparli, li devi nuovamente inviare al remoto, con l'opzione <code>-f</code> , altrimenti git darà un errore.</p><p>È fortemente consigliato che tu legga le informazioni inserite nel file aperto nell'editor in quanto ci sono parecchie cose che potresti fare.</p><h3 id="ulteriori-informazioni-"><strong>Ulteriori <strong><strong>Informa</strong></strong>z<strong><strong>ion</strong></strong>i<strong><strong>:</strong></strong></strong></h3><ul><li>Documentazione di Git: <a href="https://git-scm.com/docs/git-commit">commit</a></li></ul> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
