Git domina il versionamento del codice da oltre quindici anni, ma il suo modello mentale resta quello pensato nel 2005 per il kernel Linux. Concetti come staging area, detached HEAD, reflog e stash sono potenti, eppure anche chi li padroneggia da tempo finisce regolarmente per inciampare, soprattutto quando si tratta di riscrivere la cronologia o gestire contesti di lavoro paralleli.
Jujutsu, abbreviato in jj, è un version control system nato per ripensare quell’esperienza senza buttare via l’ecosistema Git. Sviluppato da Martin von Zweigbergk e adottato internamente da Google, è scritto in Rust e funziona come strato sopra un repository Git regolare. In pratica si può clonare un repo da GitHub, lavorare con jj in locale, e fare push verso colleghi che continuano a usare git senza che se ne accorgano.
A differenza di altri tentativi come Pijul, Sapling o Fossil, jj non chiede di abbandonare Git. Lo abbraccia come backend di storage, ma sostituisce l’intera CLI con qualcosa di più coerente. La versione 0.38.0, rilasciata a febbraio 2026, ha consolidato la stabilità del progetto al punto che la maggior parte dei core developer ha iniziato ad usarlo quotidianamente. Per chi passa giornate a manipolare cronologie complesse, fare rebase tra branch lunghi e sistemare merge conflict ricorrenti, conviene capire cosa offre jj.
La working copy è un commit: addio staging area
Il primo cambio di paradigma che jj impone riguarda la working copy, ovvero la cartella in cui si modificano i file. In Git esistono tre stati separati (working tree, staging area e HEAD). Per portare una modifica nella history bisogna fare git add e poi git commit, e questo doppio passaggio nasconde una quantità sproporzionata di problemi, tra cui file dimenticati nello staging, modifiche perse con un checkout e conflitti tra index e working tree.
Jujutsu elimina la staging area in modo radicale: ogni modifica nella working copy vive già dentro un commit, che jj aggiorna in automatico prima di qualsiasi operazione. Ogni modifica che fai sui file viene già tracciata come parte di un commit “in costruzione“.
Non esiste git stash, perché quando vuoi mettere da parte qualcosa basta lasciare la working copy così com’è e crearne una nuova con jj new. Non esiste un checkout che ti perde le modifiche, perché jj non te lo permetterebbe nemmeno. Il messaggio del commit puoi scriverlo prima, durante o dopo aver finito di modificare il codice, con jj describe.
Il concetto di “commit pulito o sporco” sparisce del tutto. La modifica vive già in un commit, e quel commit può essere riscritto, spostato, splittato o abbandonato come qualunque altro nodo del grafo. Per chi usa intensivamente git stash come strumento di context switching, è una semplificazione che si nota immediatamente.
Jujutsu: change ID e commit ID
La differenza più profonda tra Git e Jujutsu è invisibile finché non la si tocca con mano. Ogni modifica in jj ha due identificatori distinti: il commit ID, ovvero lo stesso SHA-1 esadecimale di Git, e il change ID, una stringa di lettere k-z. Il commit ID identifica il contenuto esatto di un commit, e cambia ogni volta che lo riscrivi. Il change ID, invece, è stabile attraverso le riscritture ed esprime l’idea di “questa modifica logica”, indipendentemente da quante volte ne aggiusti il contenuto.
Questa distinzione apre scenari che in Git richiedono acrobazie. Se hai una catena di tre commit e modifichi quello in mezzo, jj ribasa automaticamente i discendenti. Niente più git rebase --interactive da gestire a mano, niente flag --rebase-merges da ricordare.
Il sistema sa che il change dei discendenti è la stessa cosa logica di prima, e lo ricostruisce sopra il nuovo contenuto. Quando si presenta un conflitto, jj lo registra come oggetto first-class dentro la cronologia: il rebase non si interrompe, il conflitto rimane visibile, e puoi risolverlo quando vuoi con jj resolve.
Il linguaggio di query revset, ispirato a Mercurial, è il complemento naturale a questa logica. Comandi come jj log -r 'author(alice) & file(glob:"*.py")' diventano triviali, mentre in Git richiederebbero pipe complicate con git log e grep. Per chi gestisce repository monolitici con centinaia di branch, la differenza in produttività è netta dopo poche settimane.
Operation log: l’undo che Git non ha mai avuto davvero
Git ha il reflog, una sorta di registro di emergenza che permette di recuperare commit “persi” dopo un rebase mal riuscito. Funziona, ma è scomodo, opera per singolo riferimento e richiede di riconoscere lo stato precedente leggendo SHA criptici.
Jujutsu sostituisce questo meccanismo con l’operation log, una cronologia atomica di ogni azione fatta sul repository. Ogni jj undo torna indietro di un passo, in modo simile al Ctrl+Z di un editor di testo, e lo fa anche su operazioni complesse come push, fetch o rebase.
L’operation log non è solo un sistema di sicurezza, ma anche un modo per ispezionare cosa è successo durante una sessione lunga, condividere stati di lavoro con altri developer, o tornare a uno stato di tre giorni fa con un singolo comando. Combinato con il fatto che jj non fa garbage collection aggressiva sui dati propri, lo spazio per recuperare errori è molto più ampio rispetto a Git.
La versione 0.38.0 ha introdotto anche jj bisect run, l’equivalente di git bisect ma con un’interfaccia più pulita e integrata con il modello a change. Per un team che debugga regressioni in repository di grandi dimensioni, è uno strumento che riduce il tempo necessario a isolare il commit colpevole. Il vantaggio non è nella novità tecnica, la binary search è la stessa, ma nella coerenza con il resto del workflow, ovvero stesso linguaggio di revset, stesso operation log, stesso undo a portata di mano.
Jujutsu: installazione, primo repository, comandi quotidiani
L’installazione di jj è semplice su tutte le piattaforme. Su macOS basta brew install jj, su Arch Linux pacman -S jujutsu, su Windows winget install jj-vcs.jj, mentre per chi ha cargo a portata di mano funziona cargo install --locked --bin jj jj-cli.
Una volta installato, conviene impostare nome ed email globali con jj config set --user user.name "Tuo Nome" e jj config set --user user.email "[email protected]".
Per provarlo su un repository Git esistente senza rischi, posizionati nella cartella e lancia jj git init --colocate. Il flag colocate crea una cartella .jj accanto a .git, permettendo di alternare comandi git e jj sullo stesso repo durante la fase di transizione. Per clonare da remoto, usa invece jj git clone https://github.com/tuonome/repo.
I comandi quotidiani da memorizzare sono pochi:
jj status # stato della working copy
jj log # cronologia (mostra il grafo per default)
jj new # crea un nuovo change vuoto
jj describe -m "msg" # imposta o modifica il messaggio
jj squash # sposta modifiche dal change corrente al parent
jj split # divide un change in due
jj rebase -d main # ribasa il change corrente su main
jj git push # pubblica i bookmark sui remote
Tieni presente che i branch in jj si chiamano bookmark e vanno gestiti esplicitamente con jj bookmark create. Il consiglio è di iniziare su un repo personale per qualche settimana, prima di portare il workflow su progetti condivisi. La curva di apprendimento è breve, ma serve tempo per disabituarsi dagli automatismi di Git.
TUI, estensioni VS Code e plugin JetBrains
Anche se jj nasce per la riga di comando, l’ecosistema di tool grafici e TUI sta crescendo in fretta. Sul fronte terminale, lazyjj è il riferimento per chi ama l’approccio di lazygit. Scritto in Rust con Ratatui, mostra log, file e bookmark in pannelli separati, supporta mouse e tasti di scelta rapida e permette di eseguire comandi jj arbitrari da un popup. È stabile e richiede jj 0.33 o superiore.
Un’alternativa più recente è jjui, sviluppato in Go, che si distingue per la visualizzazione interattiva del rebase, dove puoi spostare nodi nel grafo come fossero blocchi, e per l’autocompletamento dei revset durante la digitazione. Richiede jj 0.36+ e ha un design orientato alla manipolazione visiva della cronologia.
Per chi lavora prevalentemente in VS Code, la situazione è più frammentata ma in evoluzione. Jujutsu Kaizen e JJ View sono due estensioni open-source che portano una vista SCM Git-style direttamente nell’IDE, con grafo dei commit interattivo e operazioni come squash, abandon e absorb accessibili dalla palette dei comandi.
VisualJJ è un’alternativa proprietaria con integrazione nativa che non richiede colocation con un repository Git, comoda se vuoi usare jj come VCS principale senza la doppia cartella .git/.jj. Per chi sviluppa in JetBrains, il plugin Selvejj integra jj come VCS di prima classe in IntelliJ, PyCharm e simili.
Conclusione: vale la pena passare a jj?
Jujutsu non è ancora alla versione 1.0: alcune funzionalità Git, tra cui annotated tag, submodule e certe integrazioni con tool di terze parti, sono parziali o mancanti. Chi lavora in team dove l’allineamento sui tool è critico deve valutare se il workflow colocate basta a mascherare l’adozione, oppure se sia meglio aspettare che il progetto maturi. La buona notizia è che la compatibilità Git è ormai stabile da diverse release e Google la usa in produzione su scala enorme, il che è un test di stress non trascurabile.
Per il developer che passa ore a manipolare cronologia, fare cherry-pick fra branch lunghi, gestire stash sovrapposti e ribasare merge complessi, il guadagno di produttività è tangibile dopo la prima settimana. L’eliminazione della staging area, l’undo universale, il rebase automatico dei discendenti e i revset rendono molte operazioni che oggi richiedono cinque comandi. Anche chi non vuole abbandonare Git completamente può usare jj come “client locale” su repo che continuano a essere git puri lato server.
La strategia più ragionevole è installare jj su un fork personale, lavorare per due settimane senza pretendere di replicare il workflow Git operazione per operazione, e osservare quali abitudini si possono semplificare. La filosofia di jj ripensa il version control per come lo userebbe oggi qualcuno che parte da zero, conservando la compatibilità con l’ecosistema esistente.













