Jak dodać submoduł do podkatalogu?

309

Mam repozytorium git ~/.janus/z kilkoma podmodułami. Chcę dodać podmoduł ~/.janus/snipmate-snippets/snippets/, ale po uruchomieniu git submodule add <[email protected]:...>w snipmate-snippetskatalogu pojawia się następujący komunikat o błędzie:

You need to run this command from the toplevel of the working tree.

Pytanie brzmi: jak dodać submoduł do snipmate-snippetskatalogu?

Robert Audi
źródło
Przejście do katalogu głównego repozytorium git dla poleceń submodułu nie będzie już wymagane (wkrótce). Zobacz moją odpowiedź poniżej
VonC
3
git submodule add -b <branch> <url> <relative_path_4m_root>
parasrish

Odpowiedzi:

437

Wchodzisz ~/.janusi biegasz:

git submodule add <git@github ...> snipmate-snippets/snippets/

Jeśli potrzebujesz więcej informacji o submodułach (lub ogólnie git), ProGit jest bardzo przydatny.

BergmannF
źródło
dobrym pomysłem wydaje się dodanie gałęzi podczas dodawania, w przeciwnym razie HEAD łatwo się odłącza: git submodule add -b <branch> <repository> [<submodule-path>]
deann
1
To było dla mnie przyczyną 'subprojects' already exists in the index (użyłem podprojektów jako nazwy katalogu) . Zamiast tego pomogła odpowiedź VonC poniżej, tj. Zrobienie cd subprojects, a następnie git submodule add <get@github …>bez ścieżki.
Cześć Anioł
83

Zauważ, że zaczynając od git1.8.4 (lipiec 2013), nie musisz już wracać do katalogu głównego.

 cd ~/.janus/snipmate-snippets
 git submodule add <git@github ...> snippets

( Bouke Versteegh komentuje , że nie musisz używać /., ponieważ w snippets/.: snippetswystarczy)

Zobacz zatwierdzenie 091a6eb0feed820a43663ca63dc2bc0bb247bbae :

submoduł: upuść wymagania najwyższego poziomu

Użyj nowej rev-parse --prefixopcji do przetworzenia wszystkich ścieżek podanych w poleceniu submodule, porzucając wymóg uruchamiania go z najwyższego poziomu repozytorium.

Ponieważ interpretacja względnego adresu URL modułu podrzędnego zależy od tego, czy „ remote.origin.url” jest skonfigurowany, jawnie blokuj względne adresy URL w „ git submodule add”, gdy nie jest on na najwyższym poziomie działającego drzewa.

Podpisano: John Keeping

Zależy od zatwierdzenia 12b9d32790b40bf3ea49134095619700191abf1f

To sprawia, że ​​„ git rev-parse” zachowuje się tak, jakby został wywołany z określonego podkatalogu repozytorium, z tą różnicą, że wszystkie ścieżki plików, które drukuje, są poprzedzone pełną ścieżką od góry działającego drzewa .

Jest to przydatne w skryptach powłoki, w których możemy chcieć wejść cdna szczyt działającego drzewa, ale musimy obsługiwać ścieżki względne podane przez użytkownika w wierszu poleceń.

VonC
źródło
Wielkie dzięki! Zauważyłem, że końcowe /.nie jest konieczne, git bez niego utworzy fragmenty katalogu.
Bouke Versteegh,
@BoukeVersteegh Ciekawe. W odpowiedzi umieściłem twój komentarz dla większej widoczności.
VonC
Korzystam z gita w wersji 2.7.4, ale wciąż pojawia się ten komunikat o błędzie Relative path can only be used from the toplevel of the working tree. Robięgit submodule add ../../../functest
FlyingAura,
@ user3426358 tak, jest to oczekiwane: powyższa odpowiedź na temat możliwości dodania podmodułu git z dowolnego podfolderu głównego repozytorium, a nie tylko z jego folderu głównego. To nie o odwołanie do submodule zdalnego repo o względnej ścieżki. Jeśli to zrobisz, pojawi się komunikat o błędzie, który zobaczysz.
VonC
@ user3426358 A przy okazji, ten komunikat o błędzie (który widzisz: „ Relative path can only be used from the toplevel of the working tree”) nie jest tym z pierwotnego pytania („ You need to run this command from the toplevel of the working tree”)
VonC
17

Miałem podobny problem, ale zamalowałem się w kącie za pomocą narzędzi GUI.

Miałem podprojekt z kilkoma plikami, które do tej pory kopiowałem, zamiast sprawdzać własne repozytorium git. Utworzyłem repozytorium w podfolderze, byłem w stanie zatwierdzić, wypchnąć itp. W porządku. Ale w repozytorium nadrzędnym podfolder nie był traktowany jako podmoduł, a jego pliki były nadal śledzone przez repozytorium nadrzędne - to nic dobrego.

Aby wyjść z tego bałaganu, musiałem powiedzieć Gitowi, aby przestał śledzić podfolder (bez usuwania plików):

proj> git rm -r --cached ./ui/jslib

Potem musiałem powiedzieć, że jest tam submoduł (którego nie możesz zrobić, jeśli cokolwiek jest obecnie śledzone przez git):

proj> git submodule add ./ui/jslib

Aktualizacja

Idealny sposób poradzenia sobie z tym wymaga jeszcze kilku kroków. Najlepiej byłoby, gdyby istniejące repo zostało przeniesione do własnego katalogu, wolnego od nadrzędnych modułów git, zatwierdzone i wypchnięte, a następnie dodane jako podmoduł:

proj> git submodule add [email protected]:user/jslib.git ui/jslib

Spowoduje to sklonowanie repozytorium git jako submodułu - co obejmuje standardowe kroki klonowania, ale także kilka innych, bardziej niejasnych kroków konfiguracji, które git podejmuje w twoim imieniu, aby uruchomić ten podmoduł. Najważniejszą różnicą jest to, że umieszcza tam prosty plik .git zamiast katalogu .git, który zawiera ścieżkę do miejsca, w którym mieszka prawdziwy katalog git - zazwyczaj w katalogu głównym projektu nadrzędnego .git / modules / jslib.

Jeśli nie zrobisz tego w ten sposób, zadziałają dla ciebie dobrze, ale gdy tylko zaangażujesz i popchniesz rodzica, a inny deweloper pójdzie pociągnąć tego rodzica, po prostu utrudniłeś im życie. Bardzo trudno będzie im powielić strukturę, którą masz na swoim komputerze, o ile masz pełny katalog .git w podfolderze katalogu zawierającego własny katalog .git.

Podmoduł move, push, git add jest najczystszą opcją.

Chris Moschini
źródło
16

Dla tych z was, którzy podzielają moją dziwną zamiłowanie do ręcznej edycji plików konfiguracyjnych, dodanie (lub zmodyfikowanie) również załatwi sprawę.

.git / config (konfiguracja osobista)

[submodule "cookbooks/apt"]
    url = https://github.com/opscode-cookbooks/apt

.gitmodules ( zatwierdzona wspólna konfiguracja)

[submodule "cookbooks/apt"]
    path = cookbooks/apt
    url = https://github.com/opscode-cookbooks/apt

Zobacz to również - różnica między .gitmodules a określaniem submodułów w .git / config?

yoniLavi
źródło
2

jednoskładnikowy skrypt bashowy, aby ułatwić odpowiedź Chrisa powyżej, ponieważ malowałem się również w kącie, używając aktualizacji Vundle do moich skryptów .vim. DESTjest ścieżką do katalogu zawierającego twoje submoduły. Zrób to po zrobieniugit rm -r $DEST

DEST='path'; for file in `ls ${DEST}`; do git submodule add `grep url ${DEST}/${file}/.git/config|awk -F= '{print $2}'` ${DEST}/${file}; done

Twoje zdrowie

Rick R.
źródło