Architecture Decision Records - ADR260201b
2026/02/01Bare repository esterno come strategia di isolamento
Autore: Marco Orlandin, Architect
Data: 01 Febbraio 2026
Status: Implementato
Progetto: git-side (open-source, sviluppato per Solexma LLC)
Constraint principali: Zero inquinamento del repo principale, invisibilità totale per collaboratori che non usano git-side, compatibilità con qualsiasi workflow Git esistente
Contesto e problema
git-side deve versionare file che vivono nella directory di un progetto ma non appartengono al suo repository principale. Il meccanismo di storage deve essere completamente invisibile al repo originale: nessun submodule, nessun file di configurazione, nessuna modifica a .git/config.
Il vincolo è rigido: un collaboratore che non usa git-side non deve mai accorgersi della sua esistenza. Niente file estranei in git status, niente hook obbligatori, niente entry in .gitmodules.
La sfida è trovare un meccanismo Git-native che offra tutte le garanzie di versionamento (storia, diff, remote, branch) senza toccare il repo principale.
Requisiti non funzionali
- Zero file aggiunti al repo principale
- Nessuna modifica a
.git/configo.gitmodules - Compatibilità con qualsiasi versione di Git ragionevolmente recente
- Supporto completo per operazioni Git standard (commit, push, pull, log)
- Isolamento: errori nel side repo non devono mai impattare il repo principale
Opzioni valutate
Opzione 1: Git submodule
- Pro: Nativo Git, ben documentato, supporto per remote dedicato.
- Contro: Modifica
.gitmodulesnel repo principale. Visibile a tutti i collaboratori. Richiede init esplicito dopo ogni clone. Aggiunge complessità al workflow principale.
Opzione 2: Branch orfano nel repo principale
- Pro: Zero file aggiuntivi, tutto dentro lo stesso
.git. - Contro: Inquina la storia del repo principale. Visibile con
git branch -a. Rischio di checkout accidentale. Concettualmente sbagliato: mescola storie non correlate.
Opzione 3: Git worktree separato
- Pro: Supporto nativo per directory di lavoro multiple.
- Contro: Legato al repo principale (condivide
.git). Non isolato: operazioni sul worktree possono interferire. Non pensato per file indipendenti.
Opzione 4: Bare repository esterno con work-tree nella directory del progetto
- Pro: Isolamento totale: repo separato, storia separata, remote separato. Zero inquinamento. Pattern già validato (vcsh). Supporto completo Git via
--git-dire--work-tree. - Contro: Richiede gestione esplicita di
GIT_DIReGIT_WORK_TREEper ogni comando. Location del bare repo da decidere e mantenere.
Decisione
Scelto il bare repository esterno con GIT_DIR puntato al bare repo e GIT_WORK_TREE puntato alla directory del progetto.
Motivazioni principali:
- Isolamento perfetto: il repo principale non sa che il side repo esiste.
- Git-native: usa meccanismi standard, nessun formato custom.
- Pattern validato: ispirato a vcsh, usato da anni nella community.
- Flessibilità: supporta remote, branch, log, diff, tutto ciò che Git offre.
Il bare repo vive in una location di sistema: ~/Library/Application Support/git-side/<sha>/ su macOS, ~/.local/share/git-side/<sha>/ su Linux.
Implementazione passo-passo
- Init bare repo:
git init --barenella location di sistema, solo al primogit side add(lazy init). - Ogni comando git-side imposta
GIT_DIReGIT_WORK_TREEprima di invocare git, puntando rispettivamente al bare repo e alla directory del progetto. - Pulizia environment: In contesti hook (post-commit), git-side azzera variabili d'ambiente ereditate (
GIT_INDEX_FILE,GIT_OBJECT_DIRECTORY) per evitare interferenze con il repo principale. - Hook markers: Gli hook installati sono delimitati da marcatori (
# >>> git-side auto >>>) per coesistere con hook esistenti senza conflitti. - Info command:
git side infomostra la location del bare repo e lo stato attuale, per debug e trasparenza.
Conseguenze osservate
- Zero interferenze con il repo principale su tutti i repository testati.
- Collaboratori senza git-side non vedono alcuna traccia della sua esistenza.
- L'isolamento dell'environment nelle hook è risultato critico: senza pulizia delle variabili Git ereditate, i comandi del side repo potevano interferire con il repo principale.
- Lezioni apprese:
- Il pattern bare repo + work-tree è solido ma richiede attenzione alle variabili d'ambiente, specialmente nei contesti hook.
- La lazy initialization evita side repo vuoti e inutili.
- Rendere visibile la location del bare repo (via
git side info) è essenziale per il debugging e la fiducia dell'utente.
Stack utilizzato
- Linguaggio: Rust (Edition 2024, MSRV 1.85)
- Git:
git init --bare, flags--git-dire--work-tree - Path resolution: crate
dirs(XDG-compliant)
Quando considerare questo approccio
Se devi versionare contenuti legati a un progetto senza modificare il suo repository:
- Metadata di progetto (appunti, backlog, scratch)
- Configurazioni locali dell'ambiente di sviluppo
- Qualsiasi file che appartiene al contesto del progetto ma non alla sua storia condivisa
Il bare repo esterno è il pattern più pulito quando il vincolo "zero inquinamento" non è negoziabile.
Hai un caso simile? Contattami. Valutiamo insieme se questo pattern fa al caso tuo.