·
  • #golang
  • #cli
  • #git
  • #tooling
  • #design

Gestire file locali fuori da Git: un problema piccolo ma reale

Alcuni file servono solo localmente e non dovrebbero finire nel repository. In questo post parto da un problema reale e spiego le scelte di design dietro una piccola CLI per gestirli senza usare .gitignore.

-

2 min read

Il problema (reale)

Nel mio lavoro utilizzo in modo abbastanza intensivo agenti IA per lo sviluppo. Questo comporta una serie di file e directory locali che:

  • servono solo a me
  • contengono configurazioni personali o sperimentali
  • non devono finire nel repository

Il problema è che questi file non sono sempre adatti a finire in .gitignore:

  • .gitignore è versionato
  • le regole diventano rapidamente rumorose
  • spesso valgono solo per una persona o un setup specifico

Git offre già una soluzione: .git/info/exclude.

Il punto è che:

  • è poco usato
  • è scomodo da gestire a mano
  • non scala quando i file iniziano ad essere tanti

Da qui nasce il problema che voglio risolvere.

Cosa NON volevo fare

Prima di spiegare cosa ho costruito, vale la pena chiarire cosa non volevo:

  • ❌ un nuovo formato tipo .gitignore
  • ❌ un tool che modifica il repository
  • ❌ un sistema di regole magiche o implicite
  • ❌ qualcosa di iper-configurabile

L’obiettivo non era “gestire Git meglio”. Era gestire file locali in modo esplicito e riproducibile.

L’idea di base

L’idea è molto semplice:

  1. definisco quali file o directory sono locali
  2. li individuo usando glob pattern
  3. li copio in una directory separata
  4. se il progetto è un repository Git, li escludo usando .git/info/exclude

Git è un effetto collaterale utile, non il cuore del tool.

Una decisione importante: cos’è la “root” del progetto

Una delle prime scelte di design è stata questa:

La root del progetto è sempre esplicita.

Regola finale:

  • se passo --root, quella è la root
  • altrimenti la root è la directory corrente
  • Git non influisce mai su questa scelta

Questo evita:

  • comportamenti impliciti
  • scan verso l’alto
  • ambiguità tra progetto e repository

Progetto e repository non sono la stessa cosa, anche se spesso coincidono.

Perché usare i glob

Ho scelto di usare i glob pattern (con supporto a **) perché:

  • sono semplici da leggere
  • sono espressivi quanto basta
  • non richiedono regex
  • funzionano bene su path relativi

Esempio:

exclude:
  - "**/.env.local"
  - "tools/agent/**"

L’idea è che il tool seleziona file, non directory logiche. Le directory vengono espanse solo come conseguenza.

Cosa fa (e cosa no) la prima versione

La v1 del tool fa solo questo:

  • scansiona una root usando glob
  • raccoglie i file matchati
  • li copia preservando i path relativi
  • opzionalmente aggiorna .git/info/exclude

E soprattutto non fa:

  • restore
  • sync bidirezionale
  • diff
  • include / exclude avanzati

Tutto questo potrà venire dopo, se servirà davvero.

Perché questo progetto ha senso per CeccheLab

Questo progetto rispetta alcune regole che per me sono importanti:

  • nasce da un problema reale
  • ha un perimetro chiaro
  • evita feature premature
  • separa bene concetti diversi

Ed è abbastanza piccolo da:

  • essere mantenibile
  • generare più di un articolo
  • restare onesto

Prossimi passi

Nei prossimi post entrerò più nel dettaglio:

  1. il design dell’algoritmo di scan
  2. la struttura della CLI
  3. l’implementazione in Go

Senza promettere troppo. Solo codice che serve davvero.