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.
gerelateerd materiaal
Een volledige Git-repository verplaatsen
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
Volgend onderwerp
Aanbevolen artikelen
Bookmark deze resources voor meer informatie over soorten DevOps-teams of voor voortdurende updates over DevOps bij Atlassian.