Copia un file da 200 MB e vola. Esegui git status nella stessa directory e l'attesa è abbastanza lunga da pensare ad altro. Le due osservazioni non si contraddicono, perché il trasferimento in blocco misura la velocità di trasferimento mentre Git misura quante piccole domande al filesystem può fare al secondo, e un albero remoto montato trasforma ogni domanda in un'andata e ritorno. Regolare la VPN non sistemerà un carico di lavoro mal formato.

Perché status è il metro sbagliato

Git deve sapere di molti file: quali sono modificati, quali non sono tracciati e se i dati dell'indice in cache corrispondono ancora a ciò che sta sul disco. Su SSHFS ognuna di queste osservazioni può essere un'operazione di rete. L'unità di lavoro qui è il numero di file, non i megabyte.

Ecco perché il primo status dopo un clone è lento, e perché i successivi possono esserlo ancora di più in un albero pieno di output di build. La scansione dei file non tracciati attraversa directory che forse non ti interessano, e ogni passo è un'altra richiesta attraverso il collegamento. Su un percorso da 40 ms un albero con qualche migliaio di voci diventa qualche migliaio di andate e ritorni. Non serve catturare pacchetti per confermare questa aritmetica.

Un test di download ti dice che il collegamento va bene; non dice nulla sul fatto che mille piccole letture finiranno oggi pomeriggio.

Sposta l'albero di lavoro, non le manopole

Un clone locale mette l'albero di lavoro, l'indice e le operazioni Git sulla stessa macchina. Un pull diventa un passo di rete visibile invece di esserlo ogni controllo di file.

Questo va bene ogni volta che lo sviluppatore può tenere la sorgente necessaria in locale, cosa che accade quasi sempre. Affina anche il confine tra commit e distribuzione, perché modificare un file locale non cambia più per caso un servizio remoto in esecuzione; la modifica va inviata e distribuita come qualsiasi altra cosa. Il prezzo è che il codice esiste in due posti, quindi decidi quale copia è autorevole e come una correzione urgente sul server torna nel repository. Quella conversazione costa meno di un comando status che nessuno vuole eseguire.

Se lo spazio di lavoro deve restare remoto, esegui Git lì

A volte lo spazio di lavoro non si può spostare: la build ha bisogno di quell'ambiente, i dati sono troppo grandi o la politica tiene la sorgente sull'host. Allora esegui Git e gli strumenti di sviluppo pertinenti accanto ai file, tramite una shell remota approvata o un ambiente di sviluppo remoto. L'editor può restare sul portatile mentre il suo backend lavora accanto all'albero di lavoro.

Le operazioni costose avvengono allora in locale sull'host remoto, e la rete trasporta il traffico dell'editor invece di migliaia di chiamate stat. È la stessa correzione di un clone locale, espressa come scelta di distribuzione e non come migrazione.

La sincronizzazione è un flusso di lavoro con proprietari, non una cache

Uno spazio di lavoro sincronizzato può ridurre le letture remote ripetute, ma non è una cache trasparente. Ha bisogno di un proprietario per ogni modifica, di una regola per i conflitti e di un accordo sui file generati che entrambe le parti credono propri. Senza queste regole la disposizione crea disaccordo invece di comodità.

Un sincronizzatore bidirezionale senza di esse produce un problema diverso da quello che ha risolto, di solito un'unione che nessuno riesce ad attribuire. Evita di eseguire due processi Git su un unico albero di lavoro condiviso se non capisci come si coordinano.

Poi regola, e tieni SSH ragionevole

Quando la disposizione è corretta, due impostazioni cambiano su quanti file Git deve chiedere: status.showUntrackedFiles e la cache dei non tracciati dietro core.untrackedCache. Nessuna delle due cambia quanto costa ogni domanda su 40 ms; cambiano solo quante domande ci sono. Gira una manopola solo quando le andate e ritorni sono locali.

Cronometra il comando che ti infastidisce invece di ragionare da un test che copia un file grande, e lascia in pace la crittografia SSH supportata. Un cifrario obsoleto non accorcia un'andata e ritorno; aggiunge un secondo problema che sopravvive al primo. La reference di git status merita una lettura, perché il comando fa molto più lavoro di quanto il nome suggerisca.

Articoli correlati