Close

Submodules: kernconcept, workflows en tips

Headshot van Nicola Paolucci
Nicola Paolucci

Developer Advocate


Door submodules op te nemen als onderdeel van je Git-ontwikkeling, kun je andere projecten in je codebase opnemen, waarbij hun geschiedenis gescheiden blijft maar gesynchroniseerd met die van jou. Het is een handige manier om problemen met de leveranciersbibliotheek en afhankelijkheden op te lossen. Zoals gewoonlijk bij alles wat git doet, is de aanpak eigenwijs en moedigt deze aan om eerst wat onderzoek te doen voordat die vakkundig kan worden toegepast. Er is al goede en gedetailleerde informatie over submodules, dus ik herhaal het niet nog eens. Wat ik hier ga doen, is een aantal interessante dingen met je delen die je zullen helpen om deze functie optimaal te benutten.

Databases
gerelateerd materiaal

Een volledige Git-repository verplaatsen

Logo Bitbucket
Oplossing bekijken

Git leren met Bitbucket Cloud

Kernconcept


Laat me eerst een korte uitleg geven over een kernconcept van submodules, wat ze makkelijker bruikbaar maakt.

Submodules worden bijgehouden op basis van de exacte commit die is gespecificeerd in het bovenliggende project, niet in een branch, referentie of andere symbolische referentie.

Ze worden nooit automatisch bijgewerkt wanneer de door de submodule gespecificeerde repository wordt bijgewerkt, alleen wanneer het bovenliggende project zelf wordt bijgewerkt. Zoals heel duidelijk verwoord in het eerder genoemde hoofdstuk over Pro Git:

Wanneer je wijzigingen aanbrengt en vastlegt in die subdirectory [submodule], merkt het superproject dat de HEAD daar is gewijzigd en registreert het de exacte commit waar je op dit moment mee bezig bent. Op die manier kunnen anderen, wanneer ze dit project klonen, de omgeving exact opnieuw creëren.

Of met andere woorden:

[...] git-submodules [...] zijn statisch. Heel statisch. Je houdt specifieke commits bij met git-submodules, niet met branches, niet met referenties, één commit. Als je commits toevoegt aan een submodule, weet het bovenliggende project dat niet. Als je een aantal vertakkingen van een module hebt, maakt dat voor de git-submodules niets uit. Je hebt één externe repository en je wijst naar één commit. Totdat je het bovenliggende project bijwerkt, verandert er niets.

Mogelijke workflows


Door dit kernconcept te onthouden en erover na te denken, kun je begrijpen dat die submodule sommige workflows goed ondersteunt en andere minder optimaal. Er zijn minstens drie scenario's waarin submodules een redelijke keuze zijn:

  • Als een component of subproject te snel verandert of als er komende wijzigingen de API defect maken, kun je voor je eigen veiligheid de code aan een specifieke commit vastkoppelen.

  • Als je een component hebt die niet vaak wordt bijgewerkt en je dit wilt bijhouden als leveranciersafhankelijkheid. Ik doe dit bijvoorbeeld voor mijn vim-plug-ins.

  • Wanneer je een deel van het project delegeert aan een externe partij en je hun werk op een bepaald moment of in een specifieke release wilt integreren. Nogmaals, dit werkt als er niet te vaak updates zijn.

Met dank aan Finch voor de goed toegelichte scenario's.

Handige binnenkomende tips


De infrastructuur van de submodule is krachtig en maakt een nuttige scheiding en integratie van codebases mogelijk. Er zijn echter eenvoudige handelingen waarvoor geen gestroomlijnde procedure of krachtige ondersteuning van de gebruikersinterface voor opdrachtregels vereist is.

Als je in je project git-submodules gebruikt, heb je hiermee te maken gehad of gaat dat gebeuren. Als het gebeurt, zul je de oplossing moeten opzoeken. Keer op keer. Laat me je onderzoekstijd besparen: gebruik Instapaper, Evernote of ouderwets een bladwijzer voor deze pagina (:D:D) en je bent voorlopig onder de pannen.

Dit is wat ik voor je heb:

Hoe wissel je een git-submodule met je eigen vertakking


Dit is een veel voorkomende workflow: je begint het project van iemand anders als submodule te gebruiken, maar na een tijdje merk je dat het nodig is om het aan te passen en het zelf bij te werken. Daarom wil je het project vertakken en de submodule vervangen door je eigen vertakking. Hoe doe je dat?

De submodules worden opgeslagen in .gitmodules:

$ cat .gitmodules [submodule "ext/google-maps"] path = ext/google-maps url = git://git.naquadah.org/google-maps.git

Je kunt de URL gewoon bewerken met een teksteditor en dan het volgende uitvoeren:

$ git submodule sync

Hiermee wordt .git/config bijgewerkt. die een kopie bevat van deze lijst met submodules (je kunt ook gewoon het relevante [submodule]-gedeelte van .git/config handmatig bewerken).

Referentie voor Stack Overflow

Hoe verwijder ik een submodule?


Het is een vrij algemene behoefte, maar de procedure is nogal ingewikkeld. Om een submodule te verwijderen, moet je het volgende doen:

1. Verwijder de relevante regel uit het bestand .gitmodules.

2. Verwijder het relevante gedeelte uit .git/config.

3. Voer git rm --cached path_to_submodule uit (geen schuine streep erachter).

4. Commit en verwijder de submodule-bestanden die nu niet meer worden gevolgd.

Referentie voor Stack Overflow

Hoe integreer ik een submodule weer in mijn project?


Of met andere woorden, hoe maak ik een git-submodule ongedaan? Als je alleen de code van je submodule in de hoofdrepository wilt plaatsen, hoef je alleen maar de submodule te verwijderen en de bestanden opnieuw toe te voegen aan de hoofdrepo:

1. Verwijder de referentie naar de submodule uit de index, maar bewaar de bestanden:

git rm --cached submodule_path (no trailing slash)

2. Verwijder het .git-modules-bestand of als je meer dan één submodule hebt, bewerk dan dit bestand door de submodule uit de lijst te verwijderen:

git rm .gitmodules

3. Verwijder de .git map met metagegevens (zorg dat je er een back-up van hebt):

rm -rf submodule_path/.git

4. Voeg de submodule toe aan de hoofdindex van de repository:

git add submodule_path git commit -m "remove submodule"

OPMERKING: De hierboven beschreven procedure is destructief voor de geschiedenis van de submodule. In gevallen waarin je een congruente geschiedenis van je submodules wilt behouden, moet je een slimme 'merge' doorlopen. Voor meer informatie verwijs ik je naar deze zeer volledige referentie voor Stack Overflow.

Hoe kun je veranderingen in submodules negeren?


Soms raken je submodules vanzelf vervuild. Als je bijvoorbeeld git-submodulesgebruikt om je vim-plug-ins te volgen, kunnen ze lokale bestanden zoals helptags genereren of wijzigen. Helaas gaat git-status je dan steeds wijzen op die veranderingen, ook al ben je er helemaal niet in geïnteresseerd en ben je niet van plan ze te committen.

De oplossing is heel eenvoudig. Open het bestand .gitmodules in de hoofdmap van je repository en voeg vervolgens voor elke submodule die je wilt negeren ignore = dirty toe, zoals in dit voorbeeld:

[submodule ".vim/bundle/msanders-snipmate"] path = .vim/bundle/msanders-snipmate url = git://github.com/msanders/snipmate.vim.git ignore = dirty

Gevaarzone! Valkuilen bij interactie met remotes


Zoals wordt aangegeven in de Git Submodule Tutorial op kernel.org, zijn er een paar belangrijke dingen waar je op moet letten bij interactie met je externe repository's.

Ten eerste moet je de wijziging in de submodule altijd publiceren voordat je de wijziging publiceert in het superproject dat ernaar verwijst. Dit is van cruciaal belang omdat het anderen kan verhinderen de repository te klonen.

Ten tweede moet je altijd onthouden dat je al je wijzigingen moet committen voordat je git submodule update uitvoert, omdat wijzigingen worden overschreven als deze er zijn!

Conclusies


Gewapend met deze notities zou je in staat moeten zijn om veelvoorkomende terugkerende workflows aan te pakken die zich voordoen bij het gebruik van submodules. In een volgende post zal ik schrijven over alternatieven voor git submodule.

Volg mij @durdn en het geweldige @Bitbucket-team voor meer DVCS-details.

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


Deel dit artikel
Volgend onderwerp

Aanbevolen artikelen

Bookmark deze resources voor meer informatie over soorten DevOps-teams of voor voortdurende updates over DevOps bij Atlassian.

Mensen die samenwerken met een muur vol tools

Bitbucket-blog

Toelichting DevOps

DevOps-leertraject

Demo Den Feature-demo's met Atlassian-experts

Hoe Bitbucket Cloud werkt met Atlassian Open DevOps

Meld je aan voor onze DevOps-nieuwsbrief

Thank you for signing up