Close

Moduły podrzędne: podstawowa koncepcja, przepływy pracy i porady

Zdjęcie portretowe Nicoli Paolucciego
Nicola Paolucci

Developer Advocate


Wykorzystanie modułów podrzędnych w ramach prac programistycznych w Git pozwala na włączenie innych projektów do bazy kodu w taki sposób, że ich historia jest przechowywana oddzielnie, ale zsynchronizowana z Twoją. Jest to wygodna metoda rozwiązywania problemów z bibliotekami i zależnościami dostawców. Jak zwykle w przypadku git to podejście wymaga trochę nauki, zanim będzie można je sprawnie stosować. Dostępne są już dobre i szczegółowe informacje na temat modułów podrzędnych, więc nie będę ich tutaj powtarzać. Chcę jedynie podzielić się kilkoma interesującymi faktami, które pomogą optymalnie korzystać z tej funkcji.

Bazy danych
materiały pokrewne

Jak przenieść pełne repozytorium Git

Logo Bitbucket
POZNAJ ROZWIĄZANIE

Poznaj środowisko Git z rozwiązaniem Bitbucket Cloud

Podstawowa koncepcja


Na początek pozwólcie, że objaśnię krótko podstawową koncepcję funkcjonowania modułów podrzędnych, która ułatwi pracę z nimi.

Moduły podrzędne są śledzone przez konkretny commit wskazany w projekcie nadrzędnym, a nie gałąź, referencję lub dowolne inne odniesienie symboliczne.

Nigdy nie są aktualizowane automatycznie wraz z aktualizacją repozytorium wskazanego przez moduł podrzędny, tylko wówczas, gdy aktualizowany jest sam projekt nadrzędny. Jak wskazano wyraźnie we wspomnianym wcześniej rozdziale książki Pro Git:

Gdy wprowadzasz zmiany i zatwierdzasz je w tym katalogu podrzędnym [submodule], projekt nadrzędny zauważa, że wskaźnik HEAD uległ tam zmianie i rejestruje dokładny commit, nad którym aktualnie pracujesz. Dzięki temu, gdy inni sklonują ten projekt, mogą dokładnie odtworzyć środowisko.

[...] moduły podrzędne Git [...] są statyczne. Bardzo statyczne. Śledzisz konkretne commity, korzystając z modułów podrzędnych Git, a nie gałęzi, referencji czy pojedynczego commita. Jeśli dodasz commity do modułu podrzędnego, projekt nadrzędny nie będzie o tym wiedział. Jeśli wprowadzisz wiele podziałów modułu, moduły podrzędne Git nie będą zwracać na to uwagi. Masz jedno repozytorium zdalne i wskazujesz na pojedynczy commit. Do momentu aktualizacji projektu nadrzędnego nic się nie zmienia.

Możliwe przepływy pracy


Pamiętając o tej kluczowej koncepcji i mając ją na uwadze, możesz uzmysłowić sobie, że funkcja submodule sprawdza się dobrze w niektórych przepływach pracy, a w innych jest mniej optymalny. Istnieją co najmniej trzy scenariusze, w których moduły podrzędne są dobrym wyborem:

  • Gdy komponent lub projekt podrzędny zmieniają się zbyt szybko lub nadchodzące zmiany spowodują uszkodzenie interfejsu API, możesz dla bezpieczeństwa zablokować kod na konkretnym commicie.

  • Gdy masz komponent, który nie jest aktualizowany zbyt często, a chcesz go śledzić jako zależność dostawcy. Sam robię tak na przykład ze swoimi wtyczkami vim.

  • Gdy delegujesz fragment projektu do innej osoby i chcesz zintegrować wykonaną przez nią pracę w konkretnym czasie lub wydaniu. Także tutaj ten sposób sprawdza się wówczas, gdy aktualizacje nie są zbyt częste.

Podziękowania dla fincha za dobrze wyjaśnione scenariusze.

Garść przydatnych porad


Infrastruktura modułów podrzędnych daje wiele możliwości i pozwala na przydatne rozdzielanie i integrowanie baz kodu. Istnieją jednak proste operacje, którym nie towarzyszy usprawniona procedura ani zaawansowana obsługa interfejsu użytkownika wiersza polecenia.

Jeśli korzystasz z modułów podrzędnych Git w swoim projekcie, na pewno zdarzyło lub zdarzy Ci się na nie natknąć. Wówczas trzeba będzie znaleźć rozwiązanie. A później znowu i znowu. Zaoszczędzę Ci poszukiwań: dodaj tę stronę do Instapaper, Evernote lub oznacz ją starą, dobrą zakładką (:D:D), a na chwilę będziesz mieć spokój.

Chcę tutaj omówić następujące tematy:

Jak zastąpić moduł podrzędny Git własnym podziałem?


To bardzo często używany przepływ pracy: zaczynasz korzystać z projektu innej osoby jako modułu podrzędnego, ale po jakimś czasie dostrzegasz potrzebę jego dostosowania do własnych potrzeb, chcesz więc utworzyć podział projektu i zastąpić moduł podrzędny własnym podziałem. Jak to zrobić?

Moduły podrzędne są przechowywane w pliku .gitmodules:

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

Wystarczy, że zmodyfikujesz adres URL w edytorze tekstu, a potem wykonasz następujące polecenie:

$ git submodule sync

Spowoduje to aktualizację pliku .git/config, który zawiera kopię listy tego modułu podrzędnego (możesz również edytować odpowiednią sekcję [submodule] pliku .git/config ręcznie).

Odsyłacz do Stack Overflow

Jak usunąć moduł podrzędny?


Jest to stosunkowo częsta potrzeba, jednak sama procedura jest nieco zawiła. Aby usunąć moduł podrzędny:

1. Usuń odpowiedni wiersz z pliku .gitmodules.

2. Usuń odpowiednią sekcję z pliku .git/config.

3. Uruchom polecenie git rm --cached path_to_submodule (bez ukośnika na końcu).

4. Zatwierdź i usuń nieśledzone już pliki modułów podrzędnych.

Odsyłacz do Stack Overflow

Jak ponownie zintegrować moduł podrzędny ze swoim projektem?


Lub, innymi słowy, jak sprawić, aby moduł podrzędny Git przestał być modułem podrzędnym? Jeśli chcesz jedynie umieścić kod z modułu podrzędnego w głównym repozytorium, wystarczy, że usuniesz moduł podrzędny, a następnie ponownie dodasz pliki do głównego repozytorium:

1. Usuń z indeksu referencję do modułu podrzędnego, ale zachowaj pliki:

git rm --cached submodule_path (no trailing slash)

2. Usuń plik .gitmodules lub, jeśli masz więcej niż jeden moduł podrzędny, zmodyfikuj ten plik, usuwając moduł podrzędny z listy:

git rm .gitmodules

3. Usuń folder metadanych .git (najpierw wykonaj jego kopię zapasową):

rm -rf submodule_path/.git

4. Dodaj moduł podrzędny (submodule) do indeksu głównego repozytorium:

git add submodule_path git commit -m "remove submodule"

UWAGA: Opisana powyżej procedura niszczy historię modułu podrzędnego. Jeśli chcesz zachować odpowiednią historię swoich modułów podrzędnych, musisz przejść przez wymyślną procedurę „scalania”. Więcej szczegółów znajdziesz w tym wyczerpującym opracowaniu w witrynie Stack Overflow.

Jak zignorować zmiany w modułach podrzędnych?


Czasami Twoje moduły podrzędne submodule mogą same z siebie przyjąć status dirty. Jeśli na przykład korzystasz z opcji submodule w Git do śledzenia swoich wtyczek vim, mogą one generować lub modyfikować pliki lokalne, takie jak helptags. Niestety polecenie git status zacznie Cię irytować komunikatami o tych zmianach, nawet jeśli nie będziesz się nimi wcale interesować i nie będziesz chcieć ich zatwierdzać.

Rozwiązanie jest bardzo proste. Otwórz plik .gitmodules w katalogu głównym Twojego repozytorium i dla każdego modułu podrzędnego, który chcesz zignorować, dodaj zapis ignore = dirty, jak w następującym przykładzie:

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

Podziękowania dla Nilsa za to świetne objaśnienie.

Strefa zagrożenia! Pułapki w interakcjach ze zdalnymi repozytoriami


Jak wspomniano w samouczku na temat modułów podrzędnych Git w witrynie kernel.org, przy interakcjach ze zdalnymi repozytoriami trzeba wziąć pod uwagę kilka ważnych kwestii.

Po pierwsze zmiany w module podrzędnym należy publikować zawsze przed opublikowaniem zmiany w projekcie nadrzędnym, który się do niego odnosi. Ma to krytyczne znaczenie, ponieważ może utrudniać innym klonowanie repozytorium.

Po drugie zawsze zależy pamiętać o zatwierdzeniu wszystkich zmian przed wykonaniem polecenia git submodule update, ponieważ wszelkie zmiany zostaną nadpisane.

Wnioski


Wiedząc o tym, będziesz w stanie poradzić sobie z wieloma typowymi, powtarzającymi się przepływami pracy występującymi podczas korzystania z modułów podrzędnych. W kolejnym wpisie opowiem o alternatywach dla operacji git submodule.

Obserwuj mnie (@durdn) i niesamowity zespół @Bitbucket, aby otrzymywać więcej informacji o DVCS.

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.


Udostępnij ten artykuł
Następny temat

Zalecane lektury

Dodaj te zasoby do zakładek, aby dowiedzieć się więcej na temat rodzajów zespołów DevOps lub otrzymywać aktualności na temat metodyki DevOps w Atlassian.

Ludzie współpracujący przy ścianie pełnej narzędzi

Blog Bitbucket

Ilustracja DevOps

Ścieżka szkoleniowa DevOps

Demonstracje funkcji z ekspertami Atlassian

Zobacz, jak Bitbucket Cloud współpracuje z Atlassian Open DevOps

Zapisz się do newslettera DevOps

Thank you for signing up