Lezione 20 di 35

Git 20

🔀 Git & GitHub · Modulo 4 · Lezione 20

Branch protection e required reviews 🛡️

Proteggere main · Richiedere approvazioni · Status check · Regole per un progetto sicuro

⏱️ Durata stimata: 60–75 min 📊 Livello: Intermedio-Avanzato (Modulo 4) 🔧 Strumenti: Browser (github.com) — configurazione via interfaccia 📋 Prerequisiti: Lezioni 17–19 (PR, review, fork)

🛡️ Le regole di team funzionano solo se sono automatizzate. Dire “nessuno faccia push diretto su main” non basta — basta una distrazione e qualcuno lo fa. Le branch protection rules trasformano le regole da accordi verbali a vincoli tecnici: GitHub blocca fisicamente i push diretti su main, richiede approvazioni prima del merge, e impedisce di integrare codice che non ha passato i test. Dopo questa lezione, il tuo main è blindato.

🎯 Obiettivi della lezione

  • Capire perché servono le branch protection rules
  • Configurare la protezione del branch main su GitHub
  • Richiedere review obbligatorie prima del merge
  • Impedire push diretti su main
  • Conoscere le altre regole disponibili (status check, linear history, ecc.)
  • Sapere cosa succede quando qualcuno viola una regola

📖 1. Teoria

1.1 — Il problema: main senza protezione

❌ Senza protezione
Chiunque nel team può fare push diretto su main — senza PR, senza review, senza test. Basta un git push origin main e il codice è in produzione. Un commit sbagliato alle 23:00 di venerdì rompe tutto. Nessuno sa chi ha fatto cosa.
✅ Con protezione
GitHub blocca il push diretto. L’unico modo per modificare main è tramite PR. Ogni PR richiede almeno 1 review approvata. I test devono passare. Nessuna scorciatoia — la qualità è garantita da regole automatiche.
# Senza protezione: chiunque può fare questo
$ git switch main
$ echo “oops” >> index.html
$ git add . && git commit -m “fix veloce”
$ git push origin main ← passa senza controlli

# Con protezione: GitHub rifiuta
$ git push origin main
remote: error: GH006: Protected branch update failed for refs/heads/main.
remote: error: Required status check is expected.
remote: error: At least 1 approving review is required.

1.2 — Le regole disponibili

GitHub offre diverse regole che puoi combinare a piacere. Ecco le più importanti, dalla più usata alla più avanzata:

Regola Cosa fa Consigliata?
Require a pull request before merging Nessuno può fare push diretto su main — tutto deve passare da una PR ⭐ Sempre
Require approvals La PR richiede N approvazioni prima del merge (es. almeno 1 compagno deve approvare) ⭐ Sempre
Dismiss stale pull request approvals Se l’autore fa nuovi push dopo l’approvazione, l’approvazione viene invalidata — serve ri-approvare Consigliata
Require status checks to pass I test automatici (GitHub Actions) devono passare prima del merge Se hai CI/CD (Modulo 5)
Require branches to be up to date Il branch deve essere aggiornato con l’ultimo main prima del merge Per team medi-grandi
Require linear history Impedisce i merge commit — solo squash o rebase. Main resta una linea dritta Opzionale
Do not allow bypassing the above settings Nemmeno gli admin possono bypassare le regole — tutti sono soggetti Per la massima sicurezza

1.3 — Configurare la protezione: passo per passo

Metodo: Rulesets (il metodo più recente di GitHub)
PASSO 1
Vai al repository su GitHub → Settings (tab in alto).
PASSO 2
Nel menu a sinistra, clicca “Rules” → “Rulesets”.
PASSO 3
Clicca “New ruleset” → “New branch ruleset”.
PASSO 4
Dai un nome (es. “Protezione main”). In Enforcement status seleziona “Active”.
PASSO 5
In “Target branches”, clicca “Add target” → “Include default branch” (questo seleziona main).
PASSO 6
In “Branch rules”, attiva le regole desiderate (vedi sezione successiva).
PASSO 7
Clicca “Create” in fondo alla pagina. Le regole sono attive immediatamente.

📌 Branch protection rules vs Rulesets: GitHub ha due sistemi. Le vecchie “Branch protection rules” (Settings → Branches) funzionano ancora ma sono in fase di sostituzione. I Rulesets (Settings → Rules → Rulesets) sono il sistema più recente, più flessibile e raccomandato. In questa lezione usiamo i Rulesets. Se il tuo repository non mostra “Rules” nel menu, usa il percorso alternativo: Settings → Branches → “Add branch protection rule”.

1.4 — La configurazione consigliata per un progetto scolastico

Regole da attivare nel ruleset
✅ ON
Restrict deletions — impedisce la cancellazione del branch main. Nessuno può eliminare main per errore.
✅ ON
Require a pull request before merging — blocca i push diretti. Tutto deve passare da una PR.
⚙️
Required approvals: 1 — almeno 1 compagno deve approvare la PR prima del merge. Per team di 4+ persone puoi mettere 2.
✅ ON
Dismiss stale reviews when new commits are pushed — se l’autore modifica la PR dopo l’approvazione, l’approvazione decade e serve una nuova review.
✅ ON
Block force pushes — impedisce git push --force su main. Il force push riscrive la storia e può cancellare il lavoro degli altri.

1.5 — Cosa succede quando una regola blocca

Azione bloccata Dove vedi il blocco Come procedere
Push diretto su main Nel terminale: remote: error: GH006: Protected branch update failed Crea un branch, pusha lì, apri una PR
Merge PR senza approvazioni Su GitHub: il pulsante “Merge” è grigio con messaggio “Review required” Chiedi a un compagno di revisionare e approvare
Merge PR con test falliti Su GitHub: sezione “Checks” in rosso, pulsante Merge disabilitato Correggi il codice, pusha — i test ripartono automaticamente
Force push su main Nel terminale: remote: error: Cannot force-push to this protected branch Non forzare mai push su main — usa revert se hai committato per errore
Cancellazione di main Su GitHub: il pulsante “Delete branch” non appare per main Non si cancella mai main — è il branch principale
La PR con protezione attiva: cosa vedi su GitHub
❌ Merge bloccato
🔴 Review required — not yet approved
🔴 1 approving review required

Merge pull request
(pulsante grigio, non cliccabile)
✅ Merge sbloccato
🟢 giulia-bianchi approved these changes
🟢 All checks have passed

Merge pull request
(pulsante verde, cliccabile)

1.6 — Configurazione avanzata: dismiss stale reviews

Questa regola merita una spiegazione dedicata perché previene un problema subdolo:

❌ Senza dismiss stale reviews
1. Marco apre una PR con codice buono.
2. Giulia approva: “Tutto ok!”
3. Marco fa un nuovo push che aggiunge codice rotto.
4. La PR ha ancora l’approvazione di Giulia — l’approvazione è rimasta valida anche se il codice è cambiato.
5. Marco fa merge. Main è rotto.
✅ Con dismiss stale reviews
1. Marco apre una PR con codice buono.
2. Giulia approva: “Tutto ok!”
3. Marco fa un nuovo push.
4. L’approvazione di Giulia viene automaticamente invalidata.
5. Giulia deve ri-revisionare il codice aggiornato e ri-approvare.
6. Solo dopo la nuova approvazione il merge è possibile.

1.7 — Chi può bypassare le regole?

Per default, i proprietari (owner) e gli admin del repository possono bypassare le protezioni. Se vuoi che nessuno possa fare eccezioni — nemmeno tu — attiva “Do not allow bypassing the above settings”.

Scenario Consiglio
Progetto scolastico di gruppo Lascia che il prof (admin) possa bypassare in caso di emergenza, ma gli studenti no.
Progetto open source Nessun bypass — nemmeno i maintainer. Tutti seguono le stesse regole.
Progetto personale Bypass per l’owner va bene — sei solo tu. Le regole servono più come reminder che come vincolo.

1.8 — Riepilogo: il workflow con le protezioni attive

Il flusso cambia leggermente: niente più scorciatoie
1. BRANCH + LAVORO
git switch -c feature/x
…commit…
git push origin feature/x
2. PR + REVIEW
Apri PR → compagno revisiona
→ approva (o chiede modifiche)
Merge bloccato finché non approvata
3. MERGE + PULISCI
Pulsante verde attivo
→ Merge pull request
→ Delete branch
La differenza rispetto a prima: il passo 2 è obbligatorio. Non puoi saltarlo. GitHub lo garantisce.

💻 2. Esempi guidati

Esempio A — Configurare la protezione di main con Rulesets

1
Su GitHub: Settings → Rules → Rulesets → New ruleset → New branch ruleset.
2
Nome: “Protezione main”. Enforcement: “Active”.
3
Target branches → Add target → “Include default branch”.
4
Attiva:
☑️ Restrict deletions
☑️ Require a pull request before merging
    → Required approvals: 1
    → ☑️ Dismiss stale pull request approvals when new commits are pushed
☑️ Block force pushes
5
Clicca “Create”. La protezione è attiva.

Esempio B — Provare che la protezione funziona

# Prova a fare push diretto su main
$ git switch main
$ echo “test” >> test.txt
$ git add . && git commit -m “Test push diretto”
$ git push origin main
remote: error: GH006: Protected branch update failed for refs/heads/main.
! [remote rejected] main -> main (protected branch hook declined)
Funziona! Il push è stato rifiutato. Devi usare un branch + PR.
# Il modo corretto: branch + push + PR
$ git switch -c fix/test-protezione
# Il commit è già nel branch (lo abbiamo fatto su main, ma non è stato pushato)
$ git push -u origin fix/test-protezione
# Vai su GitHub → apri PR → chiedi review → dopo approvazione → merge

# Ripulisci main locale (rimuovi il commit che non è stato pushato)
$ git switch main
$ git reset –hard origin/main

Esempio C — Configurazione alternativa con Branch protection rules (metodo classico)

Se il tuo repository non ha “Rules” nel menu:
1
Settings → Branches (nel menu a sinistra) → “Add branch protection rule”.
2
In “Branch name pattern” scrivi: main.
3
Attiva le stesse regole: “Require a pull request before merging” → “Require approvals” → 1 approvazione. “Dismiss stale pull request approvals”. “Do not allow force pushes”.
4
Clicca “Create”. Il risultato è identico.

🏋️ 3. Esercizi

🟢 Esercizio 1 — Attiva la protezione (Facile)

a) Scegli uno dei tuoi repository su GitHub.
b) Segui l’Esempio A per creare un ruleset con le protezioni base.
c) Prova a fare push diretto su main (come nell’Esempio B). Funziona? (Non deve funzionare!)
d) Se il push è stato rifiutato, la protezione funziona. Ripulisci il commit locale.
e) Verifica su GitHub: nella pagina del repository, accanto al branch main, appare un’icona di lucchetto?

🔵 Esercizio 2 — PR con required review (Medio)

a) Con la protezione attiva, crea un branch, fai un commit, pusha e apri una PR.
b) Guarda il pulsante “Merge”: è grigio? Dice “Review required”?
c) Se lavori da solo, puoi testare abbassando temporaneamente le approvazioni a 0, oppure aggiungere un compagno come collaboratore e chiedergli di approvare.
d) Dopo l’approvazione, il pulsante diventa verde? Fai merge.
e) Verifica che il commit è su main: git pull e git log --oneline -n 3.

🟠 Esercizio 3 — Testa dismiss stale reviews (Medio)

Questo esercizio richiede un compagno come collaboratore.

a) Crea un branch, fai un commit, pusha, apri una PR.
b) Il compagno approva la PR.
c) Prima di fare merge, fai un nuovo commit sul branch e pusha.
d) Vai sulla PR: l’approvazione è stata invalidata? (Deve esserlo, se “dismiss stale reviews” è attivo.)
e) Il compagno deve ri-revisionare e ri-approvare.
f) Ora fai merge.

🟣 Esercizio 4 — Configura un progetto di gruppo completo (Difficile)

Configura un repository per un progetto scolastico di 4 studenti con tutte le best practice:

a) Crea un repository con README, .gitignore e LICENSE.
b) Aggiungi i 3 compagni come collaboratori (Settings → Collaborators).
c) Configura la protezione di main con: PR obbligatoria, 1 approvazione richiesta, dismiss stale reviews, block force pushes.
d) Crea le etichette personalizzate per le issue (bug, feature, frontend, backend, priorità alta/bassa).
e) Crea i template per le issue (bug report e feature request).
f) Crea 4 issue (una per studente) e assegnale.
g) Ogni studente: fork (se esterno) o branch diretto → lavora → PR → review del compagno → merge.
h) Alla fine: main ha i contributi di tutti, la storia è pulita, ogni modifica è passata per una PR revisionata.

❓ 4. Quiz di verifica

1. Perché è importante proteggere il branch main?

Mostra risposta

Perché main è il branch di produzione — contiene il codice stabile e funzionante. Senza protezione, chiunque può fare push diretto e rompere il progetto senza che nessuno abbia controllato il codice. Le branch protection rules trasformano le regole di team da accordi verbali a vincoli tecnici che GitHub applica automaticamente. Anche la persona più attenta può dimenticarsi di creare una PR — la protezione elimina la possibilità di errore umano.


2. Cosa succede se provi a fare git push origin main quando main è protetto?

Mostra risposta

Il push viene rifiutato da GitHub con un messaggio di errore: remote: error: GH006: Protected branch update failed. Git non può inviare i commit direttamente a main. Devi creare un branch (es. git switch -c fix/qualcosa), pushare il branch, e aprire una Pull Request. Solo dopo l’approvazione della PR puoi fare merge in main tramite l’interfaccia di GitHub.


3. Cosa fa la regola “Dismiss stale pull request approvals”?

Mostra risposta

Invalida automaticamente le approvazioni quando l’autore fa nuovi push sulla PR dopo l’approvazione. Senza questa regola, un’approvazione resta valida anche se il codice cambia completamente — l’autore potrebbe aggiungere codice rotto dopo l’approvazione e fare merge. Con questa regola, ogni nuovo push richiede una nuova review. Garantisce che il codice approvato sia lo stesso codice che viene integrato in main.


4. Qual è la differenza tra Rulesets e Branch protection rules?

Mostra risposta

Sono due sistemi di GitHub per la stessa cosa: proteggere i branch. Le Branch protection rules (Settings → Branches) sono il sistema più vecchio, ancora funzionante ma in fase di sostituzione. I Rulesets (Settings → Rules → Rulesets) sono il sistema più recente e raccomandato — offrono più flessibilità (es. applicare regole a più branch con pattern, regole per tag, bypass granulari). Le regole fondamentali (PR obbligatoria, approvazioni, block force push) sono disponibili in entrambi i sistemi. Se il tuo repository mostra “Rules” nel menu, usa i Rulesets.


5. In un progetto di 3 studenti, quante approvazioni consiglieresti per la PR?

Mostra risposta

1 approvazione è sufficiente per un team di 3. Se richiedessi 2, servirebbe che entrambi i compagni approvino ogni PR — il che rallenterebbe molto il lavoro e potrebbe creare colli di bottiglia se qualcuno è assente. Con 1 approvazione, uno qualsiasi dei due compagni può revisionare e approvare, garantendo che almeno una seconda persona abbia visto il codice. Per team di 5+ persone, 2 approvazioni possono avere senso.


6. Cosa fa “Block force pushes” e perché è importante?

Mostra risposta

Impedisce l’uso di git push --force sul branch protetto. Il force push riscrive la storia del branch remoto — può cancellare commit, sovrascrivere il lavoro degli altri, e creare situazioni irrecuperabili. Su main, un force push potrebbe eliminare settimane di lavoro di tutto il team. Bloccando il force push, si garantisce che la storia di main sia append-only: si possono solo aggiungere commit (tramite merge), mai riscrivere o cancellare quelli esistenti. Il force push resta utilizzabile sui branch di feature personali.


📚 Riepilogo della lezione

Cosa hai imparato oggi:
  • Le branch protection trasformano le regole di team in vincoli tecnici automatici
  • Regole essenziali: PR obbligatoria + 1 approvazione + block force push
  • Dismiss stale reviews: invalida le approvazioni se il codice cambia dopo la review
  • Configurazione: Settings → Rules → Rulesets → New branch ruleset
  • Alternativa classica: Settings → Branches → Add branch protection rule
  • Push diretto su main protetto = errore GH006 — devi usare branch + PR
  • Il pulsante Merge resta grigio finché le regole non sono soddisfatte
  • Per la scuola: 1 approvazione è sufficiente per team di 3-4 persone

Prossima lezione →

Lezione 21 — GitHub Projects e Kanban
Organizzare il lavoro con le board. Colonne To Do, In Progress, Done.
Collegare issue e PR ai progetti. Gestione visuale del progetto.

Corso Git & GitHub · Per studenti e insegnanti · Lezione 20 di 45