Salta al contenuto principale

git fetch vs git pull: Remote Tracking e Workflow con Rebase

·5 minuti
Indice dei contenuti
git fetch è sempre sicuro. git pull è fetch più merge (o rebase), e quel secondo passaggio è dove le cose vanno storte. Capire la differenza cambia il modo in cui collabori sui branch condivisi.

La maggior parte dei developer impara prima git pull e lo usa in modo riflesso. Funziona bene in isolamento, ma su un team con un branch condiviso attivo aggiunge silenziosamente commit di merge alla storia, può fallire a metà operazione se il working tree non è pulito e oscura ciò che è effettivamente arrivato dal remote. Sapere quando usare fetch invece ti ridà il controllo.

Cosa Sono Davvero i Remote Tracking Branch
#

Quando cloni un repository, Git crea due tipi di puntatori ai branch:

  • main – il tuo branch locale, che punta al commit su cui stai lavorando.
  • origin/main – un remote tracking branch, che punta all’ultimo stato conosciuto di main sul remote origin.

origin/main è uno snapshot di sola lettura. Git lo aggiorna ogni volta che esegui git fetch, ma non ci committi mai direttamente. È il modo in cui Git risponde alla domanda “come appare il remote dall’ultima volta che mi sono sincronizzato?”

# Vedi tutti i remote tracking branch
git branch -r

# Confronta il tuo main locale con il ref di tracking remoto
git log main..origin/main --oneline

git fetch: Scarica, Non Integrare
#

git fetch contatta il remote, scarica nuovi commit e ref, e aggiorna i tuoi remote tracking branch. Non tocca il tuo working tree né i tuoi branch locali.

# Fetch di tutti i remote
git fetch

# Fetch di un remote specifico
git fetch origin

# Fetch di un branch specifico
git fetch origin main

Dopo un fetch puoi ispezionare cosa è arrivato prima di decidere cosa farci:

# Cosa è arrivato?
git log origin/main --oneline -10

# Come sarebbe il merge?
git diff main origin/main

Ecco perché git fetch è sempre sicuro. Non può rompere il tuo working tree, non può causare un conflitto di merge e non può interrompere lavoro in corso.

git pull: La Scorciatoia e i Suoi Compromessi
#

git pull è una scorciatoia per git fetch seguita da git merge FETCH_HEAD. Eseguirlo su un branch che è divergito dal remote produce un commit di merge:

*   a3b2c1d Merge branch 'main' of github.com:org/repo
|\
| * 9f8e7d6 Commit del collega
* | 4c5d6e7 Il tuo commit locale
|/
* 1a2b3c4 Antenato comune

Su un branch condiviso di lunga durata come main, questi commit di merge si accumulano rapidamente e rendono git log difficile da leggere. Complicano anche il bisecting.

git pull –rebase: Mantenere una Storia Lineare
#

git pull --rebase

Questo equivale a git fetch seguito da git rebase origin/main. Invece di creare un commit di merge, riproduce i tuoi commit locali sopra i commit remoti appena scaricati:

* 4c5d6e7 Il tuo commit locale (rebasato)
* 9f8e7d6 Commit del collega
* 1a2b3c4 Antenato comune

La storia è lineare. Il tuo commit contiene ancora esattamente le modifiche che hai creato, ma ora si trova in cima al lavoro di tutti gli altri.

Puoi rendere questo il comportamento predefinito per tutti i pull:

git config --global pull.rebase true
Nota

git pull --rebase fallirà comunque se il tuo working tree ha modifiche non committate che entrano in conflitto con i commit in arrivo. Fai lo stash o committa il tuo lavoro prima di fare pull.

git fetch –prune: Pulizia Bonus
#

git fetch --prune

Questo combina un fetch standard con la rimozione automatica dei remote tracking ref che non esistono più sul remote. Se un collega ha eliminato origin/feature-x su GitHub, --prune rimuove il ref obsoleto origin/feature-x dal tuo repo locale. È una buona abitudine usarlo al posto del semplice git fetch.

Diagramma di Sequenza: fetch vs pull –rebase
#

sequenceDiagram
    participant L as Locale (main)
    participant T as origin/main (tracking)
    participant R as Remote (main)

    Note over L,R: Un collega pusha un commit sul remote

    L->>R: git fetch
    R-->>T: Aggiorna origin/main con il nuovo commit
    Note over L: Il main locale è invariato. Ispezioni origin/main.

    L->>L: git rebase origin/main
    Note over L: I tuoi commit riprodotti sopra i nuovi. Storia lineare.

    alt Usando git pull --rebase invece
        L->>R: git pull --rebase
        R-->>T: Fetch: aggiorna origin/main
        T-->>L: Rebase: riproduce i commit locali sopra
        Note over L: Stesso risultato, un solo comando.
    end

Raccomandazione per il Workflow di Team
#

Il pattern che scala meglio sui branch condivisi:

# 1. Prima il fetch per vedere cosa c'è
git fetch --prune

# 2. Ispeziona cosa è arrivato
git log main..origin/main --oneline

# 3. Decidi: rebase per storia lineare, merge se serve un merge commit
git rebase origin/main
# oppure
git merge origin/main

Fare il fetch prima e decidere dopo ti mantiene in controllo. Non vieni mai sorpreso da un conflitto a metà operazione quando il working tree non è pulito.

**Fare pull con il working tree non pulito.** Se hai modifiche non committate ed esegui `git pull`, Git rifiuterà (se il pull sovrascrive i tuoi file) o produrrà uno stato confuso. Committa o fai lo stash prima di fare pull. **Non sapere quale remote e branch sono configurati per il branch corrente.** Esegui `git branch -vv` per vedere la configurazione del tracking upstream per ogni branch locale. Se non è impostato un upstream, `git pull` non saprà da dove scaricare. **Non fare mai il fetch prima di rivedere la PR di un collega.** Se revisioni una PR usando solo l'interfaccia web, potresti stare rivedendo dati obsoleti se il branch è stato force-pushato di recente. Scarica il branch localmente ed esegui `git log` e `git diff` prima di approvare. **Usare `git pull` su `main` in un workflow basato su rebase.** Se il tuo team usa rebase, configura `pull.rebase = true` globalmente in modo che il semplice `git pull` non crei mai accidentalmente commit di merge.

Se vuoi approfondire uno qualsiasi di questi argomenti, offro sessioni di coaching 1:1 per ingegneri che lavorano su integrazione AI, architettura cloud e platform engineering. Prenota una sessione (50 EUR / 60 min) o scrivimi a manuel.fedele+website@gmail.com.