så småningom kommer alla intressanta mjukvaruprojekt att bero på ett annat projekt, bibliotek eller ramverk. Git ger submoduler för att hjälpa till med detta. Undermoduler gör att du kan inkludera eller bädda in ett eller flera förråd som en undermapp i ett annat förråd.
För många projekt är undermoduler inte det bästa svaret (mer om detta nedan), och även i bästa fall kan det vara svårt att arbeta med undermoduler, men låt oss börja med att titta på ett rakt framåt exempel.,
lägga till en undermodul
låt oss säga att du arbetar med ett projekt som heter Slingshot. Du har kod för y-shaped stick
och en rubber-band
.
flickr foto delas av young@art under en Creative Commons ( BY ) licens
samtidigt, i ett annat förråd, du har ett annat projekt som heter Rock—Det är bara en generiskrock
bibliotek, men du tror att det skulle vara perfekt för slangbella.
Du kan lägga till rock
som underkod för slingshot
., I slingshot
– förvaret:
vid denna tidpunkt har du en rock
– mapp inuti slingshot
, men om du skulle kika inuti den mappen, beroende på din version av Git, kanske du ser … ingenting.,
nyare versioner av Git kommer att göra detta automatiskt, men äldre versioner kommer att kräva att du uttryckligen säger åt Git att ladda ner innehållet irock
:
om allt ser bra ut kan du begå denna ändring och du har enrock
mapp islingshot
arkiv med allt innehåll frånrock
– arkivet.,
på GitHub kommer mappikonenrock
att ha en liten indikator som visar att det är en undermodul:
och att klicka på mappen rock
tar dig över till rock
– arkivet.
det är det! Du har inbäddat rock
– arkivet i slingshot
– arkivet. Du kan interagera med allt innehåll från rock
som om det vore en mapp inuti slingshot
(eftersom det är).,
på kommandoraden, Git-kommandon som utfärdats frånslingshot
(eller någon av de andra mapparna,rubber-band
ochy-shaped-stick
) kommer att fungera på ”överordnade förvaret”,slingshot
, men kommandon du utfärdar frånrock
mappen kommer att fungera på bararock
repository:
gå med i ett projekt med hjälp av undermoduler
säg nu att du är en ny samarbetspartner som går med i Project Slingshot., Du skulle börja med att köragit clone
för att ladda ner innehållet islingshot
– arkivet. Vid denna tidpunkt, om du skulle kika inuti mappen rock
, skulle du se … ingenting.
återigen förväntar sig Git att vi uttryckligen ber den ladda ner undermodulens innehåll., Du kan också använda git submodule update --init --recursive
här, men om du klonar slingshot
för första gången kan du använda ett modifierat kommandot clone
för att se till att du laddar ner allt, inklusive eventuella undermoduler:
byter till undermoduler
det kan vara lite knepigt att ta en befintlig undermapp och göra den till ett externt beroende. Låt oss titta på ett exempel.
du håller på att starta ett nytt projekt—en magisk rullbackburk-som också behöver en rubber-band
., Låt oss ta rubber-band
du byggde för slingshot
, dela upp det i ett fristående förråd och bädda in det i båda projekten via undermoduler.
Du kan ta allt från Project Slingshot ’ s rubber-band
mapp och extrahera den till ett nytt förråd och även behålla begå historia.
låt oss börja med att extrahera innehållet i mappenrubber-band
urslingshot
., Du kan använda git filter-branch
för att göra detta, vilket ger dig bara de åtaganden som är relaterade till rubber-band
. Kommandotgit filter-branch
kommer att skriva om vårt förvars historia, vilket gör att det ser ut som om mappen rubber-band
hade varit det egna förvaret hela tiden. Mer information om git filter-branch
finns i den här artikeln.
det första steget är att göra en kopia av slingshot
för att arbeta vidare-slutmålet är att rubber-band
ska stå som sitt eget förråd, så lämna slingshot
som det är., Du kan användacp
med-r
för att rekursivt kopiera hela mappenslingshot
till en ny mapprubber-band
.,
det ser ut somrubber-band
är bara en annanslingshot
, men nu, frånrubber-band
Arkiv, Körgit filter-branch
:
vid denna tidpunkt har du en mapprubber-band
, vilket är ett förråd som liknar Project Slingshot, men det har bara filerna och begår historia från mappenrubber-band
.,
eftersom du kopierade detta från slingshot
kommer det nya arkivet fortfarande att ha några fjärr-spårningsgrenar du konfigurerade när det var slingshot
. Du vill inte trycka rubber-band
tillbaka tillslingshot
. Du vill driva detta till ett nytt förråd.
skapa ett nytt förråd förrubber-band
på GitHub, uppdatera sedan fjärrkontrollen förrubber-band
., Förutsatt att du anropade fjärrkontrollen origin
kan du:
då kan du publicera den nya” generiska gummibandsmodul”med git push
.,
nu när du har separerat rubber-band
I sitt eget förråd måste du ta bort den gamla rubber-band
-mappen från slingshot
-förvaret:
uppdatera sedan slingshot
för att använda rubber-band
som undermodul:
som vi såg tidigare när vi lade till rock
har vi nu ett förråd-i-A-förråd., Tre repositories, i själva verket: ”parent” repository slingshot
, plus de två ”sub” repositories, rock
och rubber-band
.
dessutom, om vi dyker tillbaka till slingshot
’s historia, kommer vi att se de åtaganden vi ursprungligen gjort till rubber-band
tillbaka när det var en mapp—ta bort mappen raderade inte någon av historiken., Detta kan ibland vara lite förvirrande – eftersomrubber-band
”child”-arkivet har en kopierad och modifierad version av de gamlaslingshot
förbinder sig, kan det ibland kännas som om du har déja vu.
tyvärr kommer alla medarbetare som drarslingshot
vid denna tidpunkt att ha en tomrubber-band
mapp., Du kanske vill påminna dina medarbetare om att köra det här kommandot för att säkerställa att de har allt undermodulens innehåll:
du vill också lägga till undermodulenrubber-band
tillmagic roll-back can
. Lyckligtvis är allt du behöver göra det för att följa samma procedur som du använde tidigare när du lade till rock
till slingshot
, I ” lägga till en undermodul.”
råd om användning av undermoduler (eller inte)
- innan du lägger till ett förråd som en undermodul, kontrollera först om du har ett bättre alternativ tillgängligt., Git-undermoduler fungerar tillräckligt bra för enkla fall, men idag finns det ofta bättre verktyg för att hantera beroenden än vad Git-undermoduler kan erbjuda. Moderna språk som Go har vänliga, Git-medvetna beroendehanteringssystem inbyggda från början. Andra, som rubygems rubygems, Node.JS ’npm, eller Cocoa’ s CocoaPods och Carthage, har lagts till av programplaneringsgruppen. Även front-end utvecklare har verktyg som Bower att hantera bibliotek och ramar för klientsidan JavaScript och CSS.
- kom ihåg att Git inte hämtar undermodulinnehåll som standard., Om du lägger till en undermodul till ett befintligt projekt, se till att alla som arbetar på projektet vet att de behöver köra kommandon som
git submodule update
ochgit clone --recursive
för att säkerställa att de får allt—detta inkluderar alla automatiserade driftsättnings-eller testtjänster som kan vara inblandade i projektet! Vi rekommenderar att du använder något som våra ”skript för att styra dem alla” för att säkerställa att alla medarbetare och tjänster har tillgång till samma arkivinnehåll överallt. - undermoduler kräver att du noggrant balanserar konsistens och bekvämlighet., Installationen som används här föredrar starkt konsistens, på bekostnad av lite bekvämlighet. Det är i allmänhet bäst att ha ett projekts undermoduler låsta till en specifik SHA, så alla medarbetare får samma innehåll. Men denna inställning gör det också svårt för utvecklare i ”överordnade” förvaret att bidra med ändringar tillbaka till undermodulförvaret.
- kom ihåg att samarbetspartners inte automatiskt ser uppdateringar av undermoduler—om du uppdaterar en undermodul kan du behöva påminna dina kollegor att köra
git submodule update
eller de kommer sannolikt att se udda beteende., - hantering av dynamiska, snabbt utvecklande eller kraftigt medberoende repositories med undermoduler kan snabbt bli frustrerande. Det här inlägget var inriktat på enkla, relativt statiska föräldra-barnförvarsrelationer. En framtida uppföljningspost kommer att specificera några strategier för att hantera mer komplexa undermodulära arbetsflöden.