Git-substructuur: het alternatief voor de Git-submodule

Het internet staat vol met artikelen over waarom je geen Git-submodules zou moeten gebruiken. Hoewel submodules nuttig zijn voor een paar toepassingen, hebben ze wel verschillende nadelen.
Zijn er alternatieven? Het antwoord is ja! Er zijn (minstens) twee hulpmiddelen die kunnen helpen bij het bijhouden van de geschiedenis van softwareafhankelijkheden in je project, waarbij je Git kunt blijven gebruiken:
Git subtreeGoogle repo
In dit artikel kijken we naar git subtree en laten we zien waarom dit een verbetering is ten opzichte van Git-submodule, al is het niet perfect.
Wat is git subtree en waarom zou ik dat gebruiken?
Met git subtree kun je de ene repository in een andere opslaan als submap. Het is een van de verschillende manieren waarop Git-projecten projectafhankelijkheden kunnen beheren.

Waarom zou je git subtree overwegen?
Het beheer van een eenvoudige workflow is eenvoudig;
Oudere versies van Git worden ondersteund (zelfs ouder dan v1.5.2);
De code van het subproject is direct beschikbaar nadat de kloon van het superproject is voltooid;
De
git subtreevereist niet dat gebruikers van je repository iets nieuws leren. Ze kunnen negeren dat je degit subtreegebruikt om afhankelijkheden te beheren;De
git subtreevoegt geen nieuwe metagegevensbestanden toe zoals Git-submodule dat doet (d.w.z.gitmodule);De inhoud van de module kan worden gewijzigd zonder dat je ergens anders een aparte kopie van de afhankelijkheid in de repository moet hebben.
Nadelen (maar volgens ons zijn deze grotendeels aanvaardbaar):
Je moet iets leren over een nieuwe samenvoegingsstrategie (d.w.z. de
git subtree);Het is iets ingewikkelder om stroomopwaarts bij te dragen aan de code van subprojecten;
De verantwoordelijkheid om super- en subprojectcode niet te combineren in commits ligt bij jou.
De git subtree gebruiken
git subtree is sinds mei 2012 beschikbaar als stockversie van Git v1.7.11 en hoger. De versie die door homebrew op OSX wordt geïnstalleerd, heeft al een goed verbonden substructuur, maar op sommige platformen moet je misschien de installatie-instructies volgen.
Hier is een canonisch voorbeeld van het traceren van een vim-plug-in met behulp van git subtree.
De snelle manier, zonder tracering op afstand
Wil je gewoon een paar oneliners om te knippen en te plakken, lees dan deze alinea. Voeg eerst een git subtree toe aan een map met een opgegeven voorvoegsel:
git subtree add --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash(Het is gebruikelijk om niet de volledige geschiedenis van het subproject op te slaan in je hoofdrepository. Mocht je deze toch willen bewaren, laat dan de markering -squash weg.)
De bovenstaande opdracht levert deze output op:
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'Zoals je kunt zien, wordt hier een merge commit geregistreerd door de hele geschiedenis van de vim-surround-repository samen te voegen in één repository:
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]Als je na een tijdje de code van de plug-in wilt bijwerken vanuit de upstream-repository, kun je gewoon een git subtree ophalen:
git subtree pull --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squashDit werkt erg snel en moeiteloos, maar de opdrachten zijn nogal lang en moeilijk te onthouden. We kunnen de opdrachten korter maken door het subproject als extern project toe te voegen.
Het subproject toevoegen als extern project
Door de substructuur als extern project toe te voegen, kunnen we er in verkorte vorm naar verwijzen:
git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.gitWe kunnen nu de substructuur toevoegen (zoals eerder), maar in korte vorm naar de externe locatie verwijzen:
git subtree add --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squashDe opdracht om het subproject op een later tijdstip bij te werken wordt:
git fetch tpope-vim-surround main
git subtree pull --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squashStroomopwaarts weer bijdragen
We kunnen onze oplossingen nu vrij aan het subproject toevoegen in onze lokale werkmap. Wanneer het tijd is om een bijdrage aan het upstream-project te leveren, moeten we het project vertakken en het als een andere externe locatie toevoegen:
git remote add durdn-vim-surround ssh://git@bitbucket.org/durdn/vim-surround.gitNu kunnen we de opdracht subtree push gebruiken, zoals:
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 -} mainDaarna zijn we klaar en kunnen we een pull-aanvraag openen voor de onderhouder van het pakket.
Kan ik dit doen zonder de opdracht git subtree te gebruiken?
Ja! Dat kan zeker. git subtree is anders dan de strategie voor het samenvoegen van substructuren. Je kunt nog steeds de samenvoegingsstrategie gebruiken, zelfs als git subtree om de een of andere reden niet beschikbaar is. Dat moet je zo aanpakken.
Voeg de afhankelijkheid toe als een eenvoudige git remote:
git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.gitVoordat we de inhoud van de afhankelijkheid in de repository lezen, is het belangrijk om een samenvoeging vast te leggen, zodat we de volledige structuurgeschiedenis van de plug-in tot nu toe kunnen volgen:
git merge -s ours --no-commit tpope-vim-surround/mainDat levert het volgende op:
Automatic merge went well; stopped before committing as requestedVervolgens lazen we de inhoud van het nieuwste structuurobject in de repository voor plug-ins in onze werkmap, klaar om te worden vastgelegd:
git read-tree --prefix=.vim/bundle/tpope-vim-surround/ -u tpope-vim-surround/mainNu kunnen we een commit maken (deze wordt een merge die de geschiedenis bewaart van de structuur die we hebben gelezen):
git ci -m"[subtree] adding tpope-vim-surround"
[stree 779b094] [subtree] adding tpope-vim-surroundAls we het project willen bijwerken, kunnen we nu een pull uitvoeren met behulp van de git subtree-samenvoegingsstrategie:
git pull -s subtree tpope-vim-surround mainGit subtree is een geweldig alternatief
Na een tijdje Git-submodules te hebben gebruikt, zul je zien dat git subtree veel problemen met de Git-submodule oplost. Zoals gewoonlijk is er bij alles wat met Git te maken heeft, een leercurve om de functie optimaal te benutten.
Bekijk dit artikel over de kracht van git subtree.