Close

Git-submodules

Met Git-submodules kun je een git-repository bewaren als submap van een andere git-repository. Git-submodules zijn gewoon een verwijzing naar een andere repository op een bepaald moment. Git-submodules stellen een Git-repository in staat om de versiegeschiedenis van externe code op te nemen en bij te houden.


Wat is een git-submodule?


Vaak is een coderepository afhankelijk van externe code. Deze externe code kan op verschillende manieren worden opgenomen. De externe code kan rechtstreeks worden gekopieerd en in de hoofd-repository worden geplakt. Deze methode heeft als nadeel dat alle stroomopwaartse wijzigingen in de externe repository verloren gaan. Een andere methode om externe code toe te voegen is via het gebruik van een pakketbeheersysteem van een taal, zoals Ruby Gems of NPM. Deze methode heeft als nadeel dat installatie- en versiebeheer vereist is op alle plaatsen waar de broncode wordt geïmplementeerd. Beide voorgestelde opnamemethoden maken het niet mogelijk om bewerkingen en wijzigingen in de externe repository bij te houden.

Een git-submodule is een record binnen een host-git-hostrepository die verwijst naar een specifieke commit in een andere externe repository. Submodules zijn erg statisch en houden alleen specifieke commits bij. Submodules houden geen git-referenties of branches bij en worden niet automatisch bijgewerkt wanneer de host-repository wordt bijgewerkt. Wanneer je een submodule aan een repository toevoegt, wordt een nieuw bestand .git-modules aangemaakt. Het bestand .gitmodules bevat metagegevens over de toewijzing tussen de URL van het submoduleproject en de lokale map. Als de host-repository meerdere submodules heeft, bevat het bestand .gitmodules een vermelding voor elke submodule.

Wanneer moet je een git-submodule gebruiken?


Als je een strikt versiebeheer moet handhaven voor je externe afhankelijkheden, kan het zinvol zijn om git-submodules te gebruiken. Hieronder volgen enkele voorbeelden die het beste kunnen worden gebruikt voor git-submodules.

  • Als een externe 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.
  • 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.
Databases
gerelateerd materiaal

Een volledige Git-repository verplaatsen

Logo Bitbucket
Oplossing bekijken

Git leren met Bitbucket Cloud

Veelgebruikte opdrachten voor git-submodules


Git-submodule toevoegen

De opdracht git submodule add wordt gebruikt om een nieuwe submodule toe te voegen aan een bestaande repository. Het volgende is een voorbeeld waarin een lege repo wordt gecreëerd en de git-submodules worden verkend.

$ mkdir git-submodule-demo
$ cd git-submodule-demo/
$ git init
Initialized empty Git repository in /Users/atlassian/git-submodule-demo/.git/

Deze reeks opdrachten maakt een nieuwe map git-submodule-demo aan, voert die map in en initialiseert deze als een nieuwe repository. Vervolgens voegen we een submodule toe aan deze nieuwe repo.

$ git submodule add https://bitbucket.org/jaredw/awesomelibrary
Cloning into '/Users/atlassian/git-submodule-demo/awesomelibrary'...
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 8 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.

Voor de opdracht git submodule add is een URL-parameter nodig die wijst naar een git-opslagplaats. Hier hebben we awesomelibrary toegevoegd als submodule. Git kloont de submodule onmiddellijk. We kunnen nu de huidige status van de repository bekijken aan de hand van de git-status...

$ git status
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

new file:   .gitmodules
new file:   awesomelibrary

Er zijn nu twee nieuwe bestanden in de repository .gitmodules en de map awesomelibrary. Wanneer je kijkt naar de inhoud van .gitmodules, dan zie je de nieuwe submoduletoewijzing

[submodule "awesomelibrary"]
path = awesomelibrary
url = https://bitbucket.org/jaredw/awesomelibrary
$ git add .gitmodules awesomelibrary/
$ git commit -m "added submodule"
[main (root-commit) d5002d0] added submodule
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 awesomelibrary

Git-submodules klonen

git clone /url/to/repo/with/submodules
git submodule init
git submodule update

Git-submodule Init

Het standaardgedrag van git submodule init is om de toewijzing te kopiëren uit het bestand .gitmodules in het lokale beatand ./.git/config. Dit lijkt misschien overbodig en trekt de bruikbaarheid van de git submodule init twijfel. git submodule init heeft een uitgebreider gedrag waarbij een lijst met expliciete modulenamen wordt geaccepteerd. Dit maakt een workflow mogelijk waarbij alleen specifieke submodules worden geactiveerd die nodig zijn om aan de repository te werken. Dit kan handig zijn als er veel submodules in een repo zijn, maar ze niet allemaal opgehaald hoeven te worden voor het werk dat je doet.

Workflows voor submodules

Zodra submodules op de juiste manier zijn geïnitialiseerd en bijgewerkt in een bovenliggende repository, kunnen ze op dezelfde manier worden gebruikt als zelfstandige repository's. Dit betekent dat submodules hun eigen branches en geschiedenis hebben. Bij het aanbrengen van wijzigingen in een submodule is het belangrijk om wijzigingen in de submodule te publiceren en vervolgens de verwijzing naar de submodule in de bovenliggende repository's bij te werken. Laten we doorgaan met het voorbeeld awesomelibrary en enkele wijzigingen aanbrengen:

$ cd awesomelibrary/
$ git checkout -b new_awesome
Switched to a new branch 'new_awesome'
$ echo "new awesome file" > new_awesome.txt
$ git status
On branch new_awesome
Untracked files:
  (use "git add <file>..." to include in what will be committed)

new_awesome.txt

nothing added to commit but untracked files present (use "git add" to track)
$ git add new_awesome.txt
$ git commit -m "added new awesome textfile"
[new_awesome 0567ce8] added new awesome textfile
 1 file changed, 1 insertion(+)
 create mode 100644 new_awesome.txt
$ git branch
  main
* new_awesome

Hier hebben we de map veranderd naar de submodule awesomeLibrary. We hebben een nieuw tekstbestand new_awesome.txt gemaakt met wat inhoud en we hebben dit nieuwe bestand toegevoegd aan en gecommit bij de submodule. Laten we nu de mappen terugzetten naar de bovenliggende repository en de huidige status van de bovenliggende repo bekijken.

$ cd ..
$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

modified:   awesomelibrary (new commits)

no changes added to commit (use "git add" and/or "git commit -a")

Wanneer we git status uitvoeren, zien we dat de bovenliggende repository bekend is met de nieuwe commits voor de submodule awesomelibrary. Hierbij wordt niet gedetailleerd ingegaan op de specifieke updates, want dat valt onder de verantwoordelijkheid van de repository's van de submodule. De bovenliggende repository houdt zich alleen bezig met het vastzetten van de submodule aan een commit. Nu kunnen we de bovenliggende repository opnieuw updaten door een git add en git commit uit te voeren op de submodule. Dit brengt alles in een goede staat met lokale inhoud. Als je in een teamomgeving werkt, is het van cruciaal belang dat je vervolgens met git push de updates van de submodule en de updates van de bovenliggende repository pusht.

Wanneer je met submodules werkt, leidt het vergeten om updates te pushen voor externe gebruikers vaak tot verwarring en fouten. Als we het zojuiste verrichte werk met awesomelibrary opnieuw bekijken, hebben we alleen de updates naar de bovenliggende repository gepusht. Een andere ontwikkelaar zou de laatste bovenliggende repository pullen en die zou verwijzen naar een commit van awesomelibrary die de ontwikkelaar niet kon pullen omdat we waren vergeten de submodule te pushen. Dit zou de lokale repo van externe ontwikkelaars defect maken. Om dit foutscenario te voorkomen, moet je ervoor zorgen dat je altijd de submodule en de bovenliggende repository commit en pusht.

Conclusie


Git-submodules zijn een krachtige manier om git te gebruiken als tool voor extern afhankelijkheidsbeheer. Weeg de voor- en nadelen van git-submodules af voordat je ze gebruikt, aangezien het een geavanceerde functie is die voor teamleden een leerproces kan vereisen om deze methode toe te passen.


Deel dit artikel

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