git submodule

Zarządza podrepozytoriami osadzonymi wewnątrz głównego repo.

git submodule pozwala osadzić jedno repozytorium Git wewnątrz drugiego — jako podkatalog, który dalej jest osobnym, niezależnym repo z własną historią i własnym commitem. Repo nadrzędne nie kopiuje plików submodułu, tylko zapisuje wskaźnik na konkretny commit. Dzięki temu wciągasz cudzą bibliotekę albo wspólny komponent do projektu, masz go u siebie, ale aktualizujesz osobno i kontrolujesz dokładnie, na której wersji siedzisz. To rozwiązanie dla zależności, których nie chcesz wrzucać przez menedżer pakietów.

Składnia i najważniejsze opcje

Podstawowa forma: git submodule [opcje], np. git submodule add <ścieżka>.

  • add <ścieżka> — dodaje nowy submoduł i tworzy/aktualizuje plik .gitmodules.
  • init — kopiuje konfigurację submodułów z .gitmodules do lokalnego .git/config.
  • update — pobiera i ustawia submoduły na commicie zapisanym w repo nadrzędnym.
  • update --init — skrót: robi init i update za jednym razem.
  • update --recursive — schodzi też do submodułów w submodułach (zagnieżdżonych).
  • update --remote — ściąga najnowszy commit ze zdalnej gałęzi submodułu, zamiast tego zapisanego w repo.
  • status — pokazuje aktualny commit każdego submodułu i czy się zgadza.
  • deinit <ścieżka> — „odpina” submoduł, czyści jego katalog roboczy i wpis w configu.
  • foreach — wykonuje to samo polecenie w każdym submodule.

Przykłady użycia

  • git submodule add https://github.com/user/lib.git libs/lib — dodaje bibliotekę jako submoduł w libs/lib i tworzy wpis w .gitmodules.
  • git clone --recurse-submodules — klonuje repo i od razu pobiera wszystkie submoduły (zero ręcznego inicjowania).
  • git submodule update --init --recursive — klasyk po świeżym git clone bez flagi: inicjuje i ściąga wszystko, łącznie z zagnieżdżonymi.
  • git submodule update --remote libs/lib — podbija ten jeden submoduł do najnowszego commita jego zdalnej gałęzi.
  • git submodule foreach git pull origin main — wciąga zmiany w każdym submodule po kolei.

Częste błędy i pułapki

Najpopularniejszy klasyk: sklonowałeś repo i katalogi submodułów są puste. To nie błąd — po prostu zapomniałeś o git submodule update --init --recursive albo o --recurse-submodules przy klonowaniu.

Druga mina: git submodule update przestawia submoduł na zapisany commit i ląduje w stanie detached HEAD. Jeśli tam coś commitujesz bez przejścia na gałąź, łatwo zgubić zmiany. Pamiętaj też, że zmiana wersji submodułu to osobny commit w repo nadrzędnym — sam git pull w środku submodułu nie wystarczy, musisz dodać i zacommitować nowy wskaźnik. Submoduły działają tak samo na Linuksie, macOS i Windowsie, więc tu różnic między systemami nie uświadczysz — problemy są zwykle ludzkie, nie systemowe.

Powiązane komendy: git clone --recurse-submodules, git config, git subtree (alternatywa bez wskaźników), git rm (do trwałego usunięcia submodułu).