uiteindelijk zal elk interessant softwareproject afhangen van een ander project, bibliotheek of framework. Git biedt submodules om hiermee te helpen. Met Submodules kunt u een of meer repositories opnemen of insluiten als een submap in een andere repository.
voor veel projecten zijn submodules niet het beste antwoord (meer hierover hieronder), en zelfs op hun best kan het werken met submodules lastig zijn, maar laten we beginnen met een rechttoe rechtaan voorbeeld.,
het toevoegen van een Submodule
stel dat je werkt aan een project genaamd Slingshot. Je hebt code voor y-shaped stick
en een rubber-band
.
flickr foto gedeeld door young@art onder een Creative Commons ( BY ) licentie
tegelijkertijd heb je in een andere repository een ander project genaamd Rock—het is gewoon een generieke rock
bibliotheek, maar je denkt dat het perfect is voor Slingshot.
u kunt rock
toevoegen als een submodule van slingshot
., In deslingshot
repository:
Op dit punt, heb je eenrock
map binnenslingshot
, maar als je in die map zou kijken, afhankelijk van je versie van Git, zie je misschien … niets.,
nieuwere versies van Git zullen dit automatisch doen, maar oudere versies vereisen dat je Git expliciet vertelt de inhoud van rock
:
als alles er goed uitziet, kun je deze wijziging committen en heb je een rock
map in de slingshot
repository met alle inhoud van de rock
repository.,
op GitHub zal het rock
folderpictogram een kleine indicator hebben die aangeeft dat het een submodule is:
en door te klikken op de rock
folder neemt u over naar de rock
repository.
dat is het! U hebt de rock
repository ingesloten in de slingshot
repository. U kunt interageren met alle inhoud van rock
alsof het een map in slingshot
(want het is).,
Op de commando-regel, Git commando ‘ s uitgegeven van slingshot
(of een van de andere mappen, rubber-band
en y-shaped-stick
) zal werken op de “bovenliggende map”, slingshot
, maar de opdrachten die u het probleem van de rock
map zal werken op alleen de rock
archief:
lid worden van een project met behulp van submodules
Nu, zeggen dat je een nieuwe medewerker voor de toetreding tot het Project Katapult., Je zou beginnen met het uitvoeren van git clone
om de inhoud van de slingshot
repository te downloaden. Op dit punt, als je zou kijken in de rock
map, zou je zien … niets.
nogmaals, Git verwacht dat we het expliciet vragen om de inhoud van de submodule te downloaden., U kunt git submodule update --init --recursive
ook hier gebruiken, maar als u slingshot
voor de eerste keer klonen, kunt u een gewijzigd clone
commando gebruiken om ervoor te zorgen dat u alles downloadt, inclusief alle submodules:
overschakelen naar submodules
Het kan een beetje lastig zijn om een bestaande submap om te zetten in een externe afhankelijkheid. Laten we naar een voorbeeld kijken.
u staat op het punt een nieuw project te starten—een magische roll-back kan–dat ook een rubber-band
nodig heeft., Laten we de rubber-band
nemen die je hebt gebouwd voor slingshot
, splitsen in een stand-alone repository, en dan insluiten in beide projecten via submodules.
je kunt alles uit de Project Slingshot ’s rubber-band
map halen en het uitpakken in een nieuwe repository en zelfs de commit historie behouden.
laten we beginnen met het extraheren van de inhoud van de rubber-band
map uit slingshot
., Je kunt git filter-branch
gebruiken om dit te doen, waardoor je alleen de commits hebt die gerelateerd zijn aan rubber-band
. Het commando git filter-branch
zal de geschiedenis van onze repository herschrijven, waardoor het lijkt alsof de map rubber-band
zijn eigen repository was. Voor meer informatie over git filter-branch
, zie dit artikel.
de eerste stap is om een kopie te maken van slingshot
om aan te werken—het einddoel is dat rubber-band
Als eigen repository staat, dus laat slingshot
zoals het is., U kunt cp
met -r
gebruiken om de gehele slingshot
map recursief te kopiëren naar een nieuwe map rubber-band
.,
Het lijkt erop rubber-band
is gewoon een slingshot
, maar nu, van de rubber-band
archief, uitvoeren git filter-branch
:
Op dit punt, heb je een map rubber-band
, dat is een opslagplaats van dat soort strekking Project Katapult, maar hij heeft alleen de bestanden en commit geschiedenis van de rubber-band
map.,
omdat je dit hebt gekopieerd van slingshot
, zal de nieuwe repository nog steeds alle remote tracking branches hebben die je hebt ingesteld toen het slingshot
was. U wilt rubber-band
niet terugpushen naar slingshot
. Je wilt dit naar een nieuwe repository pushen.
Maak een nieuwe repository aan voor rubber-band
op GitHub, werk dan de remote bij voor rubber-band
., Ervan uitgaande dat u de remote origin
aanroept, kunt u:
dan kunt u de nieuwe “generic rubber-band module” publiceren met git push
.,
Nu dat je hebt gescheiden rubber-band
in de eigen repository, moet u verwijderen van de oude rubber-band
map van de slingshot
archief:
update slingshot
om te gebruiken rubber-band
als een submodule:
Zoals we zagen toen we werden toevoegen rock
, we hebben nu een repository-in-een-gegevensopslagruimte., Drie repositories, in feite: de “parent” repository slingshot
, plus de twee” sub”repositories, rock
en rubber-band
.
bovendien, als we terugduiken in slingshot
’s geschiedenis, zullen we de commits zien die we oorspronkelijk maakten in rubber-band
toen het een map was—het verwijderen van de map heeft geen van de geschiedenis gewist., Dit kan soms een beetje verwarrend zijn—aangezien derubber-band
“child” repository een gekopieerde en gewijzigde versie heeft van die oudeslingshot
commits, kan het soms aanvoelen alsof je een déja vu hebt.
helaas zal elke medewerker die slingshot
Pult op dit moment een lege rubber-band
map hebben., U kunt uw medewerkers eraan herinneren om dit commando uit te voeren om er zeker van te zijn dat ze alle inhoud van de submodule hebben:
u wilt ook de rubber-band
submodule toevoegen aan magic roll-back can
. Gelukkig hoeft u alleen maar dezelfde procedure te volgen die u eerder gebruikte toen u rock
aan slingshot
toevoegde, in “een submodule toevoegen.”
advies over het gebruik van submodules (of niet)
- voordat u een repository als een submodule toevoegt, controleer eerst of u een beter alternatief beschikbaar hebt., Git submodules werken goed genoeg voor eenvoudige gevallen, maar tegenwoordig zijn er vaak betere tools beschikbaar voor het beheren van afhankelijkheden dan wat Git submodules kunnen bieden. Moderne talen als Go hebben vanaf het begin vriendelijke, Git-bewuste afhankelijkheidsbeheersystemen ingebouwd. Anderen, zoals Ruby ‘ s rubygems, Node.js ‘npm, of Cocoa’ s CocoaPods en Carthago, zijn toegevoegd door de programmeergemeenschap. Zelfs front-end ontwikkelaars hebben tools zoals Bower om bibliotheken en frameworks voor client-side JavaScript en CSS te beheren.
- onthoud dat Git standaard geen submodule inhoud download., Als je een submodule toevoegt aan een bestaand project, zorg er dan voor dat iedereen die aan het project werkt weet dat ze commando ‘ s moeten uitvoeren zoals
git submodule update
engit clone --recursive
om ervoor te zorgen dat ze alles krijgen—Dit geldt ook voor elke geautomatiseerde implementatie-of testservice die mogelijk betrokken is bij het project! We raden je aan iets als onze “Scripts om ze allemaal te regeren” te gebruiken om ervoor te zorgen dat alle medewerkers en services overal toegang hebben tot dezelfde inhoud van de repository. - Submodules vereisen dat u consistentie en gemak zorgvuldig balanceert., De hier gebruikte opstelling geeft sterk de voorkeur aan consistentie, ten koste van een beetje gemak. Het is over het algemeen het beste om de submodules van een project te vergrendelen op een specifieke SHA, zodat alle medewerkers dezelfde inhoud ontvangen. Maar deze setup maakt het ook moeilijk voor ontwikkelaars in de “parent” repository om wijzigingen terug te brengen naar de submodule repository.
- onthoud dat medewerkers niet automatisch updates zullen zien voor submodules-als u een submodule bijwerkt, moet u uw collega ‘ s er mogelijk aan herinneren om
git submodule update
uit te voeren of ze zullen waarschijnlijk vreemd gedrag zien., - het beheren van dynamische, snel evoluerende of sterk co-afhankelijke repositories met submodules kan snel frustrerend worden. Dit bericht was gericht op eenvoudige, relatief statische ouder-kind repository relaties. Een toekomstige follow-up post zal een aantal strategieën beschrijven om complexere submodule workflows te helpen beheren.