Git subtree: l'alternativa al sottomodulo Git
Nicola Paolucci
Developer Advocate
Internet è pieno di articoli sul perché non si debbano usare i sottomoduli Git. Sebbene i sottomoduli siano utili per alcuni casi d'uso, presentano diversi inconvenienti.
Ci sono alternative? La risposta è sì! Esistono (almeno) due strumenti che possono aiutarti a tenere traccia della cronologia delle dipendenze software nel tuo progetto consentendoti di continuare a usare Git:
Sottoalbero Git
- Google repo
In questo post esamineremo git subtree
e mostreremo perché è un miglioramento, anche se non perfetto, rispetto al sottomodulo git.
Cos'è git subtree e perché dovrei usarlo?
Un git subtree
ti consente di annidare un repository all'interno di un altro come sottodirectory. È uno dei tanti modi in cui i progetti Git possono gestire le dipendenze dei progetti.
Perché potresti prendere in considerazione un git subtree
- La gestione di un flusso di lavoro semplice è facile.
- Sono supportate le versioni precedenti di Git (anche precedenti alla v1.5.2).
- Il codice del sottoprogetto è disponibile subito dopo il completamento del clone del super progetto.
git subtree
non richiede agli utenti del tuo repository di apprendere cose nuove. Possono ignorare il fatto che tu stia usandogit subtree
per gestire le dipendenze.git subtree
non aggiunge nuovi file di metadati come fa il sottomodulo git (ad esempio .gitmodule).- Il contenuto del modulo può essere modificato senza avere una copia separata della dipendenza nel repository altrove.
Svantaggi (ma a nostro avviso sono in gran parte accettabili):
- Devi apprendere una nuova strategia di merge (ad esempio
git subtree
). - Contribuire al codice a monte per i sottoprogetti è leggermente più complicato.
- La responsabilità di non mischiare il codice del super e del sottoprogetto nei commit spetta a te.
materiale correlato
Come spostare un repository Git completo
Scopri la soluzione
Impara a utilizzare Git con Bitbucket Cloud
Come usare git subtree
git subtree
è disponibile nella versione stock di Git da maggio 2012 – v1.7.11 e successive. La versione installata come homebrew su OSX ha già un sottoalbero correttamente cablato, ma su alcune piattaforme potrebbe essere necessario seguire le istruzioni di installazione.
Ecco un esempio canonico di tracciamento di un plug-in vim usando git subtree.
Il modo rapido e semplice senza tracciamento remoto
Se vuoi solo un paio di battute da tagliare e incollare, leggi questo paragrafo. Per prima cosa aggiungi git subtree
in una cartella con prefisso specificata:
git subtree add --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash
La prassi comune consiste nel non archiviare l'intera cronologia del sottoprogetto nel tuo repository principale, ma se vuoi conservarla, ometti il flag –squash.
Il comando precedente produce il seguente output:
git fetch https://bitbucket.org/vim-plugins-mirror/vim-surround.git main
warning: no common commits
remote: Counting objects: 338, done.
remote: Compressing objects: 100% (145/145), done.
remote: Total 338 (delta 101), reused 323 (delta 89)
Receiving objects: 100% (338/338), 71.46 KiB, done.
Resolving deltas: 100% (101/101), done.
From https://bitbucket.org/vim-plugins-mirror/vim-surround.git
* branch main -} FETCH_HEAD
Added dir '.vim/bundle/tpope-vim-surround'
Come puoi vedere, registra un commit di merge eseguendo lo squash dell'intera cronologia del repository vim-surround in un valore unico:
1bda0bd [3 minutes ago] (HEAD, stree) Merge commit 'ca1f4da9f0b93346bba9a430c889a95f75dc0a83' as '.vim/bundle/tpope-vim-surround' [Nicola Paolucci]
ca1f4da [3 minutes ago] Squashed '.vim/bundle/tpope-vim-surround/' content from commit 02199ea [Nicola Paolucci]
Se dopo un po' vuoi aggiornare il codice del plugin dal repository upstream, puoi semplicemente fare un pull di git subtree
:
git subtree pull --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash
Si tratta di un'operazione molto veloce e indolore, ma i comandi sono leggermente lunghi e difficili da ricordare. Possiamo abbreviarli aggiungendo il sottoprogetto come remoto.
Aggiunta del sottoprogetto come remoto
L'aggiunta del sottoalbero come remoto ci consente di farvi riferimento in forma più breve:
git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git
Ora possiamo aggiungere il sottoalbero (come prima), ma possiamo anche fare riferimento al remoto in forma abbreviata:
git subtree add --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash
Il comando per aggiornare il sottoprogetto in un secondo momento diventa:
git fetch tpope-vim-surround main
git subtree pull --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash
Contributo all'upstream
Ora possiamo eseguire liberamente il commit delle nostre correzioni al sottoprogetto nella nostra directory di lavoro locale. Quando è il momento di contribuire al progetto upstream, dobbiamo eseguire un fork del progetto e aggiungerlo come altro remoto:
git remote add durdn-vim-surround ssh://git@bitbucket.org/durdn/vim-surround.git
Ora possiamo usare il comando subtree push come segue:
git subtree push --prefix=.vim/bundle/tpope-vim-surround/ durdn-vim-surround main
git push using: durdn-vim-surround main
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 308 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
To ssh://git@bitbucket.org/durdn/vim-surround.git
02199ea..dcacd4b dcacd4b21fe51c9b5824370b3b224c440b3470cb -} main
Dopodiché siamo pronti e possiamo aprire una pull request per il responsabile del pacchetto.
Posso farlo senza usare il comando git subtree?
Sì! git subtree
è diverso dalla strategia di merge dei sottoalberi. Puoi comunque utilizzare la strategia di merge anche se per qualche motivo git subtree
non è disponibile. Ecco come procederesti.
Aggiungi la dipendenza come semplice git remote
:
git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git
Prima di leggere il contenuto della dipendenza nel repository, è importante registrare un merge in modo da poter tenere traccia dell'intera cronologia ad albero del plug-in fino a questo punto:
git merge -s ours --no-commit tpope-vim-surround/main
Quali output:
Automatic merge went well; stopped before committing as requested
Quindi abbiamo letto il contenuto dell'ultimo oggetto ad albero nel repository dei plugin nella nostra directory di lavoro, pronto per il commit
git read-tree --prefix=.vim/bundle/tpope-vim-surround/ -u tpope-vim-surround/main
Ora possiamo eseguire il commit, che sarà un commit di merge che conserverà la cronologia dell'albero che leggiamo:
git ci -m"[subtree] adding tpope-vim-surround"
[stree 779b094] [subtree] adding tpope-vim-surround
Quando vogliamo aggiornare il progetto, possiamo estrarlo utilizzando la strategia di merge di git subtree
:
git pull -s subtree tpope-vim-surround main
git subtree è un'ottima alternativa
Dopo aver usato i sottomoduli git per un po', vedrai che git subtree
risolve molti problemi con il sottomodulo git. Come al solito, con tutto ciò che riguarda Git, c'è una curva di apprendimento per sfruttare al meglio la funzionalità.
Seguimi su Twitter @durdn per altre notizie e curiosità su Git. E dai un'occhiata ad Atlassian Bitbucket se stai cercando un buon strumento per gestire i tuoi repository Git.
Aggiornamento: dopo aver pubblicato questo articolo, ho anche scritto un articolo sulla potenza di git subtree.
Condividi l'articolo
Argomento successivo
Letture consigliate
Aggiungi ai preferiti queste risorse per ricevere informazioni sui tipi di team DevOps e aggiornamenti continui su DevOps in Atlassian.