---
id: git-101
title: Git 101
description: Una guida introduttiva alle basi di Git
author: Luca Lombardo
tags: [git, gitea]
---

Git è un sistema di controllo di versione distribuito creato per gestire progetti di qualsiasi dimensione, mantenendo traccia delle modifiche al codice sorgente. Questa guida ci accompagnerà dai concetti di base fino alle funzionalità avanzate.

---

## **1. Introduzione a Git**

### **Cos'è Git?**

-   **Sistema di controllo di versione**: Gestisce le modifiche al codice sorgente nel tempo.

-   **Distribuito**: Ogni sviluppatore ha una copia del repository.

-   **Veloce e leggero**: Ottimizzato per la velocità e le prestazioni.

### **Perché usare Git?**

-   **Tracciabilità**: Ogni modifica è tracciata e reversibile.

-   **Collaborazione**: Più persone possono lavorare sullo stesso progetto.

-   **Backup**: Repository remoto per il backup del codice.

-   **Branching**: Lavoriamo su nuove funzionalità senza influenzare il codice principale.

---

## **2. Installazione**

> Se ci troviamo al dipartimento di matematica a Pisa, è già installato su tutte le macchine dell'aula 3 ed aula 4!

### **Windows**

1. Scarichiamo [Git for Windows](https://git-scm.com/download/win).

2. Seguiamo il wizard di installazione.

3. Durante l'installazione:

    - Selezioniamo "Git Bash" come terminale.

    - Configuriamo un editor di testo (es. Vim o Nano).

### **macOS**

1. Usiamo `brew` per installare Git:

    ```bash
    brew install git
    ```

### **Linux**

1. Installiamo Git usando il nostro gestore di pacchetti:

    - **Debian/Ubuntu**:

        ```bash
        sudo apt update
        sudo apt install git
        ```

    - **Arch Linux**:

        ```bash
        sudo pacman -S git
        ```

---

## **3. Configurazione iniziale**

Una volta installato, configuriamo Git con il nostro nome e indirizzo email:

```bash
git config --global user.name "Il Nostro Nome"
git config --global user.email "nostro@email.com"
```

### **Verifica configurazione**

```bash
git config --list
```

---

## **4. Concetti fondamentali**

### **Repository**

-   **Repository locale**: Una cartella sul nostro computer che contiene il nostro progetto.

-   **Repository remoto**: Una versione del progetto ospitata su un server (es. GitHub, GitLab).

### **Branch**

Un ramo permette di lavorare su modifiche isolate rispetto al codice principale (branch `main` o `master`).

### **Commit**

Una snapshot del nostro codice in un determinato momento.

---

## **5. Creazione e gestione di un repository**

### **Inizializzare un nuovo repository**

Se stiamo iniziando un nuovo progetto, possiamo creare un nuovo repository con il comando:

```bash
git init
```

### **Clonare un repository esistente**

Se invece vogliamo lavorare su un progetto esistente, possiamo clonare da remoto con:

```bash
git clone <URL>
```

---

## **6. Lavorare con Git**

### **Aggiungere file**

Aggiungiamo file allo stage per includerli nel prossimo commit:

```bash
git add <nome-file>
# Oppure, per aggiungere tutti i file:
git add .
```

---

### **Commit**

Il comando **`git commit`** è utilizzato per registrare le modifiche nel repository locale. Ogni commit è una snapshot del progetto, contenente tutte le modifiche che sono state aggiunte tramite `git add`.

#### Come funziona:

1. **Aggiungiamo modifiche all'area di staging**:
   Prima di fare un commit, dobbiamo aggiungere i file che vogliamo includere al prossimo commit usando `git add`. Questo comando prepara i file per essere salvati nella cronologia del repository.

    Esempio:

    ```bash
    git add <nome-file>
    # Oppure per aggiungere tutti i file modificati
    git add .
    ```

2. **Effettuiamo il commit**:
   Una volta che i file sono nell'area di staging, possiamo fare un commit. Ogni commit dovrebbe avere un messaggio descrittivo che spieghi cosa è stato cambiato nel progetto.

    Comando per fare un commit:

    ```bash
    git commit -m "Descrizione chiara del cambiamento"
    ```

    L'opzione `-m` permette di aggiungere il messaggio direttamente dalla linea di comando. Se omettiamo `-m`, Git aprirà un editor di testo per scrivere il messaggio di commit.

#### Cosa succede dietro le quinte:

-   Git salva lo stato dei file nell'area di staging in un commit, che viene aggiunto alla cronologia del repository locale.

-   Ogni commit ha un identificatore unico (hash) che consente di risalire facilmente alle modifiche in qualsiasi momento.

---

### **Push**

**`git push`** è il comando che ci permette di inviare le modifiche dal nostro repository locale a un repository remoto (ad esempio su GitHub, GitLab, Bitbucket, ecc.).

#### Come funziona:

1. Dopo aver fatto uno o più commit locali, dobbiamo inviare queste modifiche al repository remoto.

2. Per fare questo, usiamo il comando **`git push`** seguito dal nome del remoto (di solito `origin` per il repository remoto di default) e dal nome del branch (di solito `main` o `master`, ma potrebbe essere qualsiasi altro nome di branch che stiamo utilizzando).

    Comando per inviare le modifiche:

    ```bash
    git push origin main
    ```

#### Cosa succede dietro le quinte:

-   Git confronta il nostro branch locale con il branch remoto. Se ci sono nuovi commit nel branch remoto che non sono ancora nel nostro branch locale, ci verrà richiesto di fare un **pull** per aggiornare prima di fare il push.

-   Il nostro repository locale viene sincronizzato con il remoto, rendendo le modifiche visibili a tutti gli altri che hanno accesso al repository remoto.

#### Errori comuni:

-   Se il repository remoto è stato aggiornato nel frattempo da qualcun altro (ad esempio, con un altro push), riceveremo un errore che ci avvisa che dobbiamo fare prima un `git pull` per sincronizzare il nostro lavoro.

---

### **Pull**

**`git pull`** è il comando che ci permette di scaricare e integrare le modifiche dal repository remoto al nostro repository locale. È una combinazione di due comandi: **`git fetch`** (scarica i cambiamenti dal remoto) e **`git merge`** (integra questi cambiamenti nel nostro branch attuale).

#### Come funziona:

1. Se altri collaboratori hanno fatto modifiche al repository remoto, possiamo ottenere queste modifiche con **`git pull`**. Questo comando aggiorna il nostro branch locale con le modifiche più recenti dal repository remoto.

2. Eseguiamo il comando:

    ```bash
    git pull origin main
    ```

    In questo caso, `origin` è il nome del repository remoto (il nome predefinito quando cloni un repository), e `main` è il branch che vogliamo aggiornare.

#### Cosa succede dietro le quinte:

-   **`git fetch`** scarica tutte le modifiche dal repository remoto, ma non le integra ancora nel nostro codice.

-   **`git merge`** unisce le modifiche scaricate al nostro branch attuale, risolvendo eventuali conflitti, se necessario.

#### Errori comuni:

-   Se ci sono conflitti tra il nostro lavoro e quello degli altri, Git ci avviserà che dovremo risolverli manualmente. Dopo aver risolto i conflitti, dovremo aggiungere i file risolti (`git add`) e completare il merge con un commit.

## **7. Lavorare con branch**

### Creare un nuovo branch

Per creare un nuovo branch in Git, utilizziamo il comando:

```bash
git branch <nome-branch>
```

Sostituiamo `<nome-branch>` con il nome desiderato per il nuovo branch.

### Spostarsi su un branch

Per spostarci su un branch esistente, usiamo:

```bash
git checkout <nome-branch>
```

Oppure, per creare e spostarci su un nuovo branch in un solo comando:

```bash
git switch -c <nome-branch>
```

### Unire un branch nel branch principale

Per unire un branch nel branch principale (di solito chiamato `main`):

1. Spostiamoci sul branch principale:

    ```bash
    git checkout main
    ```

2. Eseguiamo il merge del branch desiderato:

    ```bash
    git merge <nome-branch>
    ```

    Sostituiamo `<nome-branch>` con il nome del branch che vogliamo unire.

### Risoluzione dei conflitti

Quando due persone modificano lo stesso file, Git può generare un conflitto. Ecco come risolverlo:

1. Identifichiamo il file in conflitto:

    ```bash
    git status
    ```

2. Modifichiamo manualmente il file per risolvere il conflitto. Cerchiamo i segni di conflitto (`<<<<<<<`, `=======`, `>>>>>>>`) e scegliamo quali modifiche mantenere.

3. Aggiungiamo il file risolto allo stage:

    ```bash
    git add <file>
    ```

4. Concludiamo con un commit per salvare le modifiche risolte:

    ```bash
    git commit
    ```

---

## **9. Comandi utili**

### **Visualizzare le differenze**

```bash
git diff
```

### **Annullare modifiche**

1. **Prima del commit**:

    ```bash
    git checkout -- <file>
    ```

2. **Dopo il commit**:

    ```bash
    git reset --soft HEAD~1
    ```

### **Eliminare un branch**

```bash
git branch -d <nome-branch>
```

---

## **10. Best practices**

-   Scriviamo messaggi di commit chiari e descrittivi.

-   Creiamo branch per nuove funzionalità o bugfix.

-   Sincronizziamo frequentemente il nostro repository locale con quello remoto.

---

## **11. Risorse aggiuntive**

-   [Documentazione ufficiale di Git](https://git-scm.com/doc)

-   [Guida interattiva Learn Git Branching](https://learngitbranching.js.org/)

-   [GitHub Docs](https://docs.github.com/)
