Podmoduły Git: Określ gałąź / tag

Jak działa git submodule add -b?

Po dodaniu podmodułu z określoną gałęzią, nowy sklonowany repo (po git submodule update --init) będzie znajdował się w określonym commicie, a nie w samej gałęzi (git status na podmodule pokazuje "obecnie nie na żadnej gałęzi").

Nie mogę znaleźć żadnych informacji na temat .gitmodules lub .git/config o gałęzi submodule lub o jakimkolwiek konkretnym commicie, więc jak git to rozgryzł?

Czy jest możliwe podanie znacznika zamiast gałęzi?

PS: używam 1.6.5.2.

Author: demonplus, 2009-11-22

11 answers

Uwaga: Git 1.8.2 dodał możliwość śledzenia gałęzi. Zobacz niektóre z Odpowiedzi poniżej.


Jest to trochę mylące, aby się do tego przyzwyczaić, ale podmoduły nie są na gałęzi. Są one, jak mówisz, tylko wskaźnikiem do konkretnego commita w repozytorium podmodułu.

Oznacza to, że gdy ktoś inny sprawdza twoje repozytorium lub pobiera Twój kod i aktualizuje podmodule git, podmodule jest sprawdzany do danego commita.

To jest Świetne dla submodule, który nie zmienia się często, ponieważ wtedy każdy w projekcie może mieć submodule w tym samym commicie.

Jeśli chcesz przenieść podmoduł do określonego tagu:

cd submodule_directory
git checkout v1.0
cd ..
git add submodule_directory
git commit -m "moved submodule to v1.0"
git push

Następnie inny programista, który chce zmienić submodule_directory na ten tag, robi to

git pull
git submodule update

git pull zmiany, które zatwierdzają ich katalog podmodułów wskazują na. git submodule update faktycznie łączy się w nowym kodzie.

 586
Author: djacobs7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-02 14:59:20

Chciałbym dodać tutaj odpowiedź, która jest tak naprawdę konglomeratem innych odpowiedzi, ale myślę, że może być bardziej kompletna.

Wiesz, że masz podmoduł git, gdy masz te dwie rzeczy.

1) Twój .gitmodules ma taki wpis:

[submodule "SubmoduleTestRepo"]
    path = SubmoduleTestRepo
    url = https://github.com/jzaccone/SubmoduleTestRepo.git

2) masz obiekt submodule (o nazwie SubmoduleTestRepo w tym przykładzie) w repozytorium git. Github pokazuje je jako obiekty "submodule". Lub wykonaj git submodule status z linii poleceń. Obiekty submodule Git są specjalne rodzaj obiektu git i trzymają informację SHA dla konkretnego commita.

Za każdym razem, gdy wykonasz git submodule update, wypełni ona Twój podmoduł zawartością z commita. Wie, gdzie znaleźć commit z powodu informacji w .gitmodules.

Teraz wystarczy dodać jedną linię do pliku .gitmodules. Tak więc podążając za tym samym przykładem wyglądałoby to tak:

[submodule "SubmoduleTestRepo"]
    path = SubmoduleTestRepo
    url = https://github.com/jzaccone/SubmoduleTestRepo.git
    branch = master

EDIT: powyżej obsługiwana jest tylko nazwa gałęzi, a nie SHA lub TAG.

Obiekt submodule jest wciąż wskazując na konkretny commit. Jedyną rzeczą, którą kupuje ci opcja -b, jest możliwość dodania flagi --remote do aktualizacji zgodnie z odpowiedzią Vogelli:

git submodule update --remote

Zamiast wypełniać zawartość podmodułu commitem wskazywanym przez podmoduł, zastępuje on ten commit najnowszym commitem w gałęzi master, a następnie wypełnia podmoduł tym commitem. Można to zrobić w dwóch krokach przez odpowiedź djacobs7. Ponieważ teraz zaktualizowałeś commit submodule obiekt wskazuje na, musisz zatwierdzić zmieniony obiekt submodule do repozytorium git.

git submodule add -b to nie jest jakiś magiczny sposób, aby utrzymać wszystko na bieżąco z gałęzią. Po prostu dodaje informacje o gałęzi w pliku .gitmodules i daje możliwość zaktualizowania obiektu submodule do najnowszego zatwierdzenia określonej gałęzi przed jej wypełnieniem.

 412
Author: Johnny Z,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-25 19:19:09

Zauważ, że Jeśli masz istniejący submodule, który nie jest śledzący gałąź jeszcze , then ( jeśli masz git 1.8.2+):

  • Upewnij się, że repo rodzica wie, że jego podmoduł śledzi teraz gałąź:]}
    cd /path/to/your/parent/repo
    git config -f .gitmodules submodule.<path>.branch <branch>
    
  • Upewnij się, że Twój podmoduł jest w rzeczywistości najpóźniej z tej gałęzi:

    cd path/to/your/submodule
    git checkout -b branch --track origin/branch
      # if the master branch already exist:
      git branch -u origin/master master
    

         (z "pochodzeniem" jest nazwa upstream remote repo na podmoduł został sklonowany z.
         git remote -v wewnątrz tego podmodułu wyświetli go. Zazwyczaj jest to 'pochodzenie')

  • Nie zapomnij zapisać nowego stanu submodule w repo rodzica:]}
    cd /path/to/your/parent/repo
    git add path/to/your/submodule
    git commit -m "Make submodule tracking a branch"
    
  • Kolejna aktualizacja dla tego podmodułu będzie musiała użyć opcji --remote:

    # update your submodule
    # --remote will also fetch and ensure that
    # the latest commit from the branch is used
    git submodule update --remote
    
    # to avoid fetching use
    git submodule update --remote --no-fetch 
    

Zauważ, że z Git 2.10+ (Q3 2016), możesz użyć' . ' jako nazwy gałęzi:

Nazwa branch zapisywany jest jako submodule.<name>.branch w .gitmodules dla update --remote.
specjalna wartość . jest używana do wskazania, że nazwa gałęzi w podmodule powinna być taka sama jak bieżąca gałąź w bieżącym repozytorium .


Jeśli chcesz zaktualizować wszystkie swoje podmoduły po gałęzi:

    git submodule update --recursive --remote

Zauważ, że wynik, dla każdego zaktualizowanego podmodułu, będzie prawie zawsze będzie odłączoną głową, jako Dan Cameron uwaga w jego odpowiedź .

(Clintm zauważa w komentarzach , że jeśli uruchomisz git submodule update --remote i uzyskany sha1 będzie taki sam jak gałąź, na której aktualnie znajduje się podmoduł, to nic nie zrobi i pozostawi podmoduł nadal "na tej gałęzi", a nie w stanie odłączonej głowy.)

Aby upewnić się, że gałąź jest rzeczywiście sprawdzona (a to nie zmieni SHA1 wpis specjalny reprezentując submodule dla repo rodzica), on sugeruje:

git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; git checkout $branch'

Każdy podmoduł nadal będzie odwoływał się do tego samego SHA1, ale jeśli zrobisz nowe commity, będziesz mógł je wypchnąć, ponieważ będą one odwoływane przez gałąź, którą chcesz śledzić.
Po tym wciśnięciu w podmodule, nie zapomnij wrócić do macierzystego repo, dodać, zatwierdzić i wcisnąć nowy SHA1 dla tych zmodyfikowanych podmodułów.

Zwróć uwagę na użycie $toplevel, zalecane w komentarzach przez Alexander Pogrebnyak .
$toplevel został wprowadzony w git1. 7. 2 w maju 2010: commit f030c96 .

Zawiera absolutną ścieżkę katalogu najwyższego poziomu (gdzie .gitmodules jest).

dtmland dodaje w komentarzach :

Skrypt foreach nie wyświetli podmoduł, które nie podążają za gałęzią.
Jednak ta komenda daje Ci oba:

 git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; [ "$branch" = "" ] && git checkout master || git checkout $branch' –

To samo polecenie, ale łatwiejsze do powinno być:

git submodule foreach -q --recursive \
    'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; \
     [ "$branch" = "" ] && \
     git checkout master || git checkout $branch' –

Umläute uzupełnia polecenie dtmland o uproszczoną wersję w komentarzach :

git submodule foreach -q --recursive 'git checkout $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'

Wiele linii:

git submodule foreach -q --recursive \
  'git checkout \
  $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
 251
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-25 19:51:55

Git 1.8.2 dodał możliwość śledzenia gałęzi.

# add submodule to track master branch
git submodule add -b master [URL to Git repo];

# update your submodule
git submodule update --remote 

Zobacz także podmoduły Gita

 152
Author: vogella,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-03 08:44:33

Przykład jak używam podmodułów git.

  1. tworzy nowy repo
  2. Następnie klonuje kolejny repo jako submodule
  3. Następnie mamy, że podmodule używać znacznika o nazwie V3. 1. 2
  4. and then we commit

A to wygląda trochę tak:

git init 
vi README
git add README
git commit 
git submodule add git://github.com/XXXXX/xxx.yyyy.git stm32_std_lib
git status

git submodule init
git submodule update

cd stm32_std_lib/
git reset --hard V3.1.2 
cd ..
git commit -a

git submodule status 
Może to pomoże? (nawet ty używam znacznika, a nie gałęzi)
 48
Author: Johan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-22 09:53:15

Z mojego doświadczenia wynika, że przełączanie oddziałów w superprojekcie lub przyszłych kasach nadal spowoduje odłączenie głowic podmodułów niezależnie od tego, czy podmoduł jest poprawnie dodany i śledzony(tj.

I zamiast ręcznie sprawdzać poprawną gałąź ręcznie lub za pomocą skryptu git submodule foreach może być użyty.

Spowoduje to sprawdzenie pliku konfiguracyjnego podmodułu dla właściwości branch i sprawdzenie gałęzi set.

git submodule foreach -q --recursive 'branch="$(git config -f <path>.gitmodules submodule.$name.branch)"; git checkout $branch'

 32
Author: Dan Cameron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-09 04:54:45

Moduły podrzędne Git są trochę dziwne - są zawsze w trybie "odłączonej głowy" - nie aktualizują się do najnowszego commita na gałęzi, jak można się spodziewać.

To ma jakiś sens, gdy się nad tym zastanowić. Załóżmy, że tworzę repozytorium foo za pomocą paska podmodułów. Wciskam moje zmiany i każę ci sprawdzić commit a7402be z repozytorium foo.

Potem wyobraź sobie, że ktoś popełnia zmianę na pasku repo, zanim będziesz mógł zrobić swój klon.

Kiedy się wymeldujesz commit a7402be z repo foo, oczekujesz tego samego kodu, który pchnąłem. Dlatego moduły podrzędne nie aktualizują się, dopóki nie powiesz im wyraźnie, aby wprowadziły nowy commit.

Osobiście uważam, że submodule są najbardziej mylącą częścią Gita. Jest wiele miejsc, które mogą wyjaśnić podmoduły lepiej niż ja. Polecam Pro Git Scotta Chacona.

 26
Author: Neall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-02 14:44:28

Mam to w swoim .plik gitconfig. Nadal jest to projekt, ale okazał się przydatny od teraz. Pomaga mi to zawsze przyczepiać podmoduły do ich gałęzi.

[alias]

######################
#
#Submodules aliases
#
######################


#git sm-trackbranch : places all submodules on their respective branch specified in .gitmodules
#This works if submodules are configured to track a branch, i.e if .gitmodules looks like :
#[submodule "my-submodule"]
#   path = my-submodule
#   url = [email protected]/my-submodule.git
#   branch = my-branch
sm-trackbranch = "! git submodule foreach -q --recursive 'branch=\"$(git config -f $toplevel/.gitmodules submodule.$name.branch)\"; git checkout $branch'"

#sm-pullrebase :
# - pull --rebase on the master repo
# - sm-trackbranch on every submodule
# - pull --rebase on each submodule
#
# Important note :
#- have a clean master repo and subrepos before doing this !
#- this is *not* equivalent to getting the last committed 
#  master repo + its submodules: if some submodules are tracking branches 
#  that have evolved since the last commit in the master repo,
#  they will be using those more recent commits !
#
#  (Note : On the contrary, git submodule update will stick 
#to the last committed SHA1 in the master repo)
#
sm-pullrebase = "! git pull --rebase; git submodule update; git sm-trackbranch ; git submodule foreach 'git pull --rebase' "

# git sm-diff will diff the master repo *and* its submodules
sm-diff = "! git diff && git submodule foreach 'git diff' "

#git sm-push will ask to push also submodules
sm-push = push --recurse-submodules=on-demand

#git alias : list all aliases
#useful in order to learn git syntax
alias = "!git config -l | grep alias | cut -c 7-"
 7
Author: Pascal T.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-01 16:41:42

Aby zmienić gałąź dla podmodułu (zakładając, że masz już podmoduł jako część repo):

  • cd do korzenia twojego repo zawierającego podmoduły
  • Otwórz .gitmodules do edycji
  • Dodaj wiersz poniżej path = ... i url = ..., który mówi branch = your-branch, dla każdego podmodułu; zapisz plik .gitmodules.
  • następnie bez zmiany katalogu do $ git submodule update --remote

...powinno to ściągnąć najnowsze commity z podanej gałęzi, dla każdej podmodule tak zmodyfikowanej.

 7
Author: Arcane Engineer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-12 13:34:53

Używamy Quack do pobrania określonego modułu z innego repozytorium git. Musimy pobrać kod bez całej bazy kodu podanego repozytorium - potrzebujemy bardzo konkretnego modułu / pliku z tego ogromnego repozytorium i powinien być aktualizowany za każdym razem, gdy uruchamiamy update.

Więc osiągnęliśmy w ten sposób,

Utwórz konfigurację

name: Project Name

modules:
  local/path:
    repository: https://github.com/<username>/<repo>.git
    path: repo/path
    branch: dev
  other/local/path/filename.txt:
    repository: https://github.com/<username>/<repo>.git
    hexsha: 9e3e9642cfea36f4ae216d27df100134920143b9
    path: repo/path/filename.txt

profiles:
  init:
    tasks: ['modules']

Z powyższą konfiguracją, tworzy 1 katalog z udostępnionego repozytorium github, jak określono w pierwszym Module config, a drugim jest aby pobrać i utworzyć plik z podanego repo.

Inni programiści po prostu muszą uruchomić

$ quack

I ściąga kod z góry.

 3
Author: Love Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-22 14:35:13

Wybranie gałęzi dla podmodułu ma jedyny efekt pozwalający git checkout w odłączonym stanie głowy (jeśli jest zaznaczone domyślne zachowanie --checkout) najnowszy commit wybranej gałęzi, gdy podasz opcję --remote w linii poleceń git submodule update.

Zauważ, że gałąź, którą wybierzesz do tego celu w Ustawieniach podmodułu , nie jest tą, która będzie klonowana podczas submodule update --remote. Jako subtelną konsekwencję jeśli przekażesz również parametr --depth i nie pouczysz Gita, o którym branch you want to clone --!! i tak naprawdę nie możesz w wierszu poleceń Git submodule update !! -- , będzie zachowywał się jak w git-clone(1) docu dla git clone --single-branch z brakującym jawnym parametrem --branch i dlatego będzie klonował tylko podstawową gałąź. Nie dziwi mnie to, że na etapie klonowania i, kiedy w końcu spróbuje znaleźć najnowszy commit dla gałęzi, którą wybrałeś dla podmodułu, jeśli nie jest to podstawowa gałąź, zakończy się niepowodzeniem z

Fatal: Needed a single revision

Nie można znaleźć bieżącego pochodzenia/nonPrimaryBranch revision in submodule path 'mySubmodule'

 -1
Author: LuKePicci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-29 15:52:16