Как указать ветку/тег при добавлении подмодуля Git?

StackOverflow https://stackoverflow.com/questions/1777854

  •  21-09-2019
  •  | 
  •  

Вопрос

Как git submodule add -b работа?

После добавления подмодуля с определенной веткой создается новый клонированный репозиторий (после git submodule update --init) будет находиться на конкретном коммите, а не на самой ветке (git status в подмодуле отображается «В настоящее время нет ни в одной ветке»).

Я не могу найти никакой информации о .gitmodules или .git/config о ветке подмодуля или каком-либо конкретном коммите, так как же Git это выяснит?

Кроме того, можно ли вместо ветки указать тег?

Я использую версию 1.6.5.2.

Это было полезно?

Решение

Примечание. GIT 1.8.2 добавила возможность отслеживать филиалы. Смотрите некоторые из ответов ниже.


Это немного сбивает с толку привыкать к этому, но подмодули не находятся на ветке. Они, как вы говорите, просто указатель на определенную коммиту репозитория подмодуля.

Это означает, что когда кто -то еще проверяет ваш репозиторий или вытаскивает ваш код, и делает обновление подмодуля GIT, подмодуль проверяется на этот конкретный коммит.

Это здорово для подмодуля, который не часто меняется, потому что тогда каждый в проекте может иметь подмодуль с одним и тем же коммитом.

Если вы хотите переместить подмодуль в конкретный тег:

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

Затем, другой разработчик, который хочет изменить субмодуль_директорию на этот тег, делает это

git pull
git submodule update --init

git pull Изменения, которые совершают их подмодульный каталог, указывает на. git submodule update На самом деле объединяется в новом коде.

Другие советы

Я хотел бы добавить сюда ответ, который на самом деле представляет собой просто конгломерат других ответов, но я думаю, что он может быть более полным.

Вы знаете, что у вас есть подмодуль Git, когда у вас есть эти две вещи.

  1. Твой .gitmodules есть такая запись:

    [submodule "SubmoduleTestRepo"]
        path = SubmoduleTestRepo
        url = https://github.com/jzaccone/SubmoduleTestRepo.git
    
  2. У вас есть объект подмодуля (в этом примере с именем SubmoduleTestRepo) в вашем репозитории Git. GitHub показывает их как объекты «подмодуля».Или сделать git submodule status из командной строки.Объекты подмодуля Git — это особые типы объектов Git, которые содержат информацию SHA для определенного коммита.

    Всякий раз, когда вы делаете git submodule update, он заполнит ваш подмодуль содержимым из коммита.Он знает, где найти коммит, благодаря информации в .gitmodules.

    Теперь все -b нужно добавить одну строку в ваш .gitmodules файл.Если следовать тому же примеру, это будет выглядеть так:

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

    Примечание: только имя ветки поддерживается в .gitmodules файл, но SHA и TAG не поддерживаются! (вместо этого фиксацию ветки каждого модуля можно отслеживать и обновлять с помощью "git add .", например так git add ./SubmoduleTestRepo, и вам не нужно менять .gitmodules файл каждый раз)

    Объект подмодуля по-прежнему указывает на конкретный коммит.Единственное, что -b опцион покупает вас, это возможность добавить --remote отметьте свое обновление согласно ответу Фогеллы:

    git submodule update --remote
    

    Вместо заполнения содержимого субмодуля коммитом, на который указывает субмодуль, он заменяет этот коммит последним коммитом в основной ветке, ЗАТЕМ он заполняет подмодуль этим коммитом.Это можно сделать в два этапа с помощью ответа djacobs7.Поскольку теперь вы обновили фиксацию, на которую указывает объект подмодуля, вам необходимо зафиксировать измененный объект подмодуля в своем репозитории Git.

    git submodule add -b это не какой-то волшебный способ поддерживать все актуальное состояние ветки.Он просто добавляет информацию о ветке в .gitmodules файл и дает вам возможность обновить объект подмодуля до последней фиксации указанной ветки перед его заполнением.

(GIT 2.22, Q2 2019, представил git submodule set-branch --branch aBranch -- <submodule_path>)

Обратите внимание, что Если у вас есть существующий подмодуль, который не Отслеживание филиала еще, тогда (Если у вас есть git 1.8.2+):

  • Убедитесь, что родительский репо знает, что его подмодуль теперь отслеживает ветку:

    cd /path/to/your/parent/repo
    git config -f .gitmodules submodule.<path>.branch <branch>
    
  • Убедитесь, что ваш подмодуль на самом деле находится в последней части этой ветви:

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

(с «происхождением» - название Вверх по течению удаленного репо Подмодуль был клонирован от.
А git remote -v Внутри этот подмодуль будет отображать его. Обычно это «происхождение»)

  • Не забудьте записать новое состояние вашего подмодуля в вашем родительском репо:

    cd /path/to/your/parent/repo
    git add path/to/your/submodule
    git commit -m "Make submodule tracking a branch"
    
  • Последующее обновление для этого подмодуля придется использовать --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 
    

Обратите внимание, что с Git 2.10+ (Q3 2016), вы можете использовать '.'Как название ветви:

Имя филиала записано как submodule.<name>.branch в .gitmodules за update --remote.
Специальная ценность . используется, чтобы указать, что имя ветви в подмодуле должно быть тем же именем, что и текущая ветвь в текущем репозитории.


Если вы хотите обновить все свои подмодули после филиала:

    git submodule update --recursive --remote

Обратите внимание, что результат для каждого обновленного подмодуля будет почти всегда быть Отличная голова, в качестве Дэн Кэмерон примечание в его ответ.

(Клинтм заметки В комментариях что, если вы бежите git submodule update --remote и полученный SHA1 такой же, как филиал, в которой в настоящее время находится подмодуль, он ничего не сделает и не оставит подмодуля все еще «на этой ветви», а не в отделении головы.)

Для обеспечения фактической проверки ветви (и это не изменит SHA1 Специальная запись Представляя подмодуль для родительского репо), он предлагает:

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

Каждый подмодуль все равно будет ссылаться на один и тот же SHA1, но если вы сделаете новые коммиты, вы сможете подтолкнуть их, потому что на них будет ссылаться филиал, на который вы хотите отслеживать подмодуль.
После этого толчка в подмодуле не забудьте вернуться к родительскому репо, добавить, совершить и подтолкнуть новый SHA1 для этих модифицированных подмодулей.

Обратите внимание на использование $toplevel, рекомендуемые В комментариях по Александр Погребняк.
$toplevel был введен в GIT1.7.2 в мае 2010 года: Commit F030C96.

Он содержит абсолютный путь каталога верхнего уровня (где .gitmodules является).

dtmland добавляет В комментариях:

Сценарий Foreach не сможет зарегистрировать подмодулы, которые не следуют за веткой.
Однако эта команда дает вам обоих:

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

Та же команда, но легче читать:

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

Умлаут уточняет DtmlandКоманда с упрощенной версией В комментариях:

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

Несколько строк:

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

GIT 1.8.2 добавил возможность отслеживать филиалы.

# add submodule to track master branch
git submodule add -b branch_name URL_to_Git_repo optional_directory_rename

# update your submodule
git submodule update --remote 

Смотрите также GIT -подмодули

Пример того, как я использую подмодули GIT.

  1. Создать новый репозиторий
  2. Затем клонировать другой репозиторий как подмодуль
  3. Тогда у нас есть этот подмодуль использовать тег под названием v3.1.2
  4. А потом мы совершаем.

И это выглядит немного похоже на это:

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 

Может быть, это помогает (хотя я использую тег, а не ветвь)?

По моему опыту переключения ветвей в суперпроекте или будущих зачетах по -прежнему вызовет отдельные головы подмодулей независимо от того, правильно ли добавлен и отслеживается подмодуль (т.е. @djacobs7 и @johnny z отвечает).

И вместо вручную проверять правильную ветвь вручную или через сценарий GIT Submodule Foreach может быть использован.

Это проверит файл конфигурации подмодуля для свойства ветви и оформить набор ветви.

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

GIT -подмодули немного странные - они всегда в режиме «отстраненная голова» - они не обновляются до последнего коммита в филиале, как вы можете ожидать.

Это имеет смысл, когда вы думаете об этом. Допустим, я создаю репозиторий Фу с подмодулем бар. Анкет Я толкаю свои изменения и говорю вам проверить Commit a7402be из репозитория Фу.

Тогда представьте, что кто -то совершает изменение в хранилище бар Прежде чем вы сможете сделать свой клон.

Когда вы проверяете Commit A7402BE из репозитория Фу, Вы ожидаете получить тот же код, который я нажал. Вот почему подмоудулы не обновляются, пока вы не скажете им явно, а затем не сделаете новый коммит.

Лично я думаю, что подмодули - самая запутанная часть GIT. Есть много мест, которые могут объяснить подмодули лучше, чем я. Я рекомендую Pro Git Скотт Чакон.

Чтобы переключить ветвь для подмодуля (при условии, что у вас уже есть подмодуль как часть репозитория):

  • cd Корень вашего хранилища, содержащего подмодули
  • Открытым .gitmodules для редактирования
  • Добавьте строку ниже path = ... а также url = ... это говорит branch = your-branch, для каждого подмодуля; сохранить файл .gitmodules.
  • Затем без изменения каталога сделайте $ git submodule update --remote

... Это должно привлечь последние коммиты по указанной ветви, для каждого подмодуля, измененного таким образом.

У меня есть это в моем файле .gitConfig. Это все еще проект, но на данный момент оказался полезным. Это помогает мне всегда переехать подмодули в их ветвь.

[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 = git@wherever.you.like/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-"

Мы используем Шарлатан Чтобы вытащить определенный модуль из другого репозитория GIT. Нам нужно вытащить код без всей базы кода предоставленного репозитория - нам нужен очень конкретный модуль / файл из этого огромного репозитория, и мы должны обновляться каждый раз, когда мы запускаем обновление.

Итак, мы достигли этого таким образом:

Создать конфигурацию

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']

При вышеуказанной конфигурации он создает один каталог из предоставленного репозитория GitHub, как указано в конфигурации первого модуля, а другой - вытянуть и создать файл из данного репозитория.

Другим разработчикам просто нужно бежать

$ quack

И он вытаскивает код из вышеуказанных конфигураций.

Единственный эффект выбора ветви для подмодуля - это то, что всякий раз, когда вы передаете --remote вариант в git submodule update Командная строка, GIT проверит в Отличная голова режим (если по умолчанию --checkout Поведение отбирается) последняя коммита этого выбранного удаленный ответвляться.

Вы должны быть особенно осторожны при использовании этой удаленной функции отслеживания филиалов для подмодулей GIT, если вы работаете с неглубокими клонами подмодулей. Ветвь, которую вы выбираете для этой цели в настройках подмодулей НЕ ЯВЛЯЕТСЯ тот, который будет клонирован во время git submodule update --remoteАнкет Если вы пройдете также --depth параметр и Вы не обучаете GIT о том, какую филиал вы хотите клонировать -- И на самом деле вы не можете в git submodule update командная строка!! - это неявно вести себя как объясненное в git-clone(1) Документация для git clone --single-branch Когда явное --branch Параметр отсутствует, и поэтому он будет клонировать только основную ветвь.

Без удивления, после того, как стадия клона выполнялась git submodule update команда, наконец, попытается проверить последний коммит для удаленный ветвь, которую вы ранее настроили для подмодуля, и, если это не первичное, он не является частью вашего локального мелкого клона, и поэтому он потерпит неудачу с

Фатальный: нужен один ревизион

Не в состоянии найти тока происхождения/NotThePrimaryBranch Пересмотр в подмодульном пути 'mysubmodule'

GIT Submodule ADD -B Разработка -имени филиала -имени - https: //branch.git

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top