Как git submodule add -b
работает?
После добавления подмодуля с определенной ветвью новый клонированный репозиторий (после git submodule update --init
) будет при определенной фиксации, а не сама ветвь ( git status
в подмодуле отображается «В настоящее время нет ни одной ветви»).
Я не могу найти какую - либо информацию о .gitmodules
или .git/config
о филиале подмодуль или какой - либо конкретной фиксации, так как делает Git понять это?
Кроме того, возможно ли указать тег вместо ветви?
Я использую версию 1.6.5.2.
git
git-submodules
Иван
источник
источник
Ответы:
Примечание: в Git 1.8.2 добавлена возможность отслеживать ветки. Смотрите некоторые ответы ниже.
Это немного сбивает с толку, чтобы привыкнуть к этому, но подмодули не на ветке. Они, как вы говорите, просто указатель на определенный коммит репозитория подмодуля.
Это означает, что когда кто-то проверяет ваш репозиторий или извлекает ваш код и выполняет обновление подмодуля git, подмодуль извлекается для этой конкретной фиксации.
Это отлично подходит для подмодуля, который не часто меняется, потому что тогда у каждого в проекте может быть подмодуль при одном и том же коммите.
Если вы хотите переместить субмодуль в определенный тег:
Затем другой разработчик, который хочет, чтобы submodule_directory был изменен на этот тег, делает это
git pull
изменения, которые фиксируют их каталог подмодулей, на которые указывает.git submodule update
на самом деле сливается в новом коде.источник
cd my_submodule; git checkout [ref in submodule's repository
доходностьfatal: reference is not a tree: ...
. Это как будтоgit
будет работать только в родительском хранилище.git checkout v1.0
ветка или тег?Я хотел бы добавить ответ, который на самом деле является просто конгломератом других ответов, но я думаю, что он может быть более полным.
Вы знаете, что у вас есть подмодуль Git, когда у вас есть эти две вещи.
Ваша
.gitmodules
запись имеет следующий вид:У вас есть объект подмодуля (в данном примере с именем SubmoduleTestRepo) в вашем Git-репозитории. GitHub показывает их как «субмодульные» объекты. Или сделать
git submodule status
из командной строки. Объекты подмодуля Git представляют собой особые виды объектов Git, и они содержат информацию SHA для конкретного коммита.Всякий раз, когда вы делаете
git submodule update
, он будет заполнять ваш подмодуль контентом из коммита. Он знает, где найти коммит из-за информации в.gitmodules
.Теперь все, что
-b
нужно сделать, это добавить одну строку в ваш.gitmodules
файл. Итак, следуя тому же примеру, это будет выглядеть так:Объект субмодуля по-прежнему указывает на конкретный коммит. Единственное, что
-b
покупает опция, - это возможность добавить--remote
флаг к вашему обновлению в соответствии с ответом Фогеллы:Вместо того, чтобы заполнять содержимое подмодуля коммитом, на который указывает субмодуль, он заменяет этот коммит последним коммитом в основной ветке, ПОТОМ он заполняет субмодуль этим коммитом. Это может быть сделано в два этапа с помощью ответа djacobs7. Поскольку вы обновили коммит, на который указывает объект подмодуля, вы должны зафиксировать измененный объект субмодуля в своем Git-репозитории.
git submodule add -b
это не какой-то волшебный способ держать все в курсе с веткой. Он просто добавляет информацию о ветви в.gitmodules
файл и дает вам возможность обновить объект подмодуля до самого последнего коммита указанной ветви перед его заполнением.источник
.gitmodules
и после этого$ git submodule update --init --remote TestModule
я получил сообщение об ошибкеfatal: Needed a single revision
иUnable to find current origin/TestTag revision in submodule path 'TestModule'
. Делая это с реальной веткой, это работает. Есть ли способ указать тег.gitmodules
без указания точного коммита?.gitmodules
и побежал,git submodule update
и ничего не произошло?(Git 2.22, Q2 2019, представил
git submodule set-branch --branch aBranch -- <submodule_path>
)Обратите внимание , что если у вас есть существующий подмодуль , который не отслеживание ветки еще , то ( если у вас есть GIT 1.8.2+ ):
Убедитесь, что родительское хранилище знает, что его подмодуль теперь отслеживает ветку:
Убедитесь, что ваш подмодуль на самом деле не позднее этой ветки:
(с именем origin, являющимся именем удаленного репо восходящего потока, с которого был клонирован подмодуль.
A
git remote -v
внутри этого подмодуля будет отображать его. Обычно это «origin»)Не забудьте записать новое состояние вашего подмодуля в родительском репо:
Последующее обновление для этого подмодуля должно будет использовать
--remote
опцию:Обратите внимание, что с Git 2.10+ (3 квартал 2016 года) вы можете использовать '
.
' в качестве имени ветви:Но , как заметил по LubosD
Это означает, что Git 2.23 (август 2019) или больше.
Смотрите " Confused by
git checkout
"Если вы хотите обновить все свои подмодули, следуя ветке:
Обратите внимание, что результатом для каждого обновленного подмодуля почти всегда будет отдельная ГОЛОВА , как отмечает Дэн Кэмерон в своем ответе .
( Клинт отмечает в комментариях, что, если вы запустите
git submodule update --remote
и полученный sha1 будет таким же, как ветвь, в которой в данный момент находится подмодуль, он ничего не сделает и оставит подмодуль все еще «в этой ветке», а не в отдельном состоянии головы. )Чтобы убедиться, что ветвь действительно извлечена (и это не изменит SHA1 специальной записи, представляющей подмодуль для родительского репо), он предлагает:
Каждый подмодуль будет по-прежнему ссылаться на тот же SHA1, но если вы сделаете новые коммиты, вы сможете их подтолкнуть, потому что на них будет ссылаться ветвь, которую вы хотите отследить подмодуль.
После этого продвижения в подмодуле не забудьте вернуться к родительскому репо, добавить, зафиксировать и отправить новый SHA1 для этих модифицированных подмодулей.
Обратите внимание на использование
$toplevel
, рекомендованное в комментариях по Александр Погребняк .$toplevel
был представлен в git1.7.2 в мае 2010 года: commit f030c96 .dtmland
добавляет в комментариях :Та же команда, но проще для чтения:
umläute уточняет команду dtmland с упрощенной версией в комментариях :
несколько строк:
До Git 2.26 (Q1 2020) выборка, которой велено рекурсивно извлекать обновления в подмодулях, неизбежно создает пакеты вывода, и становится трудно обнаружить сообщения об ошибках.
Команда научена перечислять подмодули, которые имели ошибки в конце операции .
См. Коммит 0222540 (16 января 2020 г.) Эмили Шаффер (
nasamuffin
) .(Слиты Junio C Hamano -
gitster
- в фиксации b5c71cc , 5 февраля 2020)источник
foreach
Сценарий не будет зависеть от зашиты<path>
, если вы заменяете<path>
с$toplevel/
.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 'git checkout $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
git submodule update --remote --merge
илиgit submodule update --remote --rebase
. Эти команды отслеживают удаленную ветвь.В Git 1.8.2 добавлена возможность отслеживать ветки.
Смотрите также Git submodules
источник
.gitmodules
файле?git submodule add -b tags/<sometag> <url>
которой вы можете увидеть , как линияbranch = tags/<sometag>
в.gitmodules
Пример того, как я использую подмодули Git.
И это выглядит примерно так:
Может быть, это помогает (хотя я использую тег, а не ветку)?
источник
git reset --hard V3.1.2
? Я просто получаю "ничего не коммитить" сgit 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 немного странные - они всегда находятся в режиме «отстраненной головы» - они не обновляются до последнего коммита на ветке, как вы могли ожидать.
Это имеет некоторый смысл, когда вы думаете об этом, хотя. Допустим, я создаю репозиторий foo с панелью субмодулей . Я отправляю свои изменения и говорю вам проверить коммит a7402be из репозитория foo .
Затем представьте, что кто-то вносит изменения в панель репозитория, прежде чем вы сможете сделать свой клон.
Когда вы проверяете коммит a7402be из репозитория foo , вы ожидаете получить тот же код, который я нажал. Вот почему подмодули не обновляются, пока вы не скажете им явно, а затем сделаете новый коммит.
Лично я думаю, что подмодули - самая запутанная часть Git. Есть много мест, которые могут объяснить подмодули лучше, чем я. Я рекомендую Pro Git от Скотта Чакона.
источник
git clone git://github.com/git/git.git
и нажмите эту функцию ...? = DЧтобы переключить ветвь для подмодуля (при условии, что у вас уже есть подмодуль как часть репозитория):
cd
в корень вашего хранилища, содержащего подмодули.gitmodules
для редактированияpath = ...
иurl = ...
это говоритbranch = your-branch
, для каждого подмодуля; сохранить файл.gitmodules
.$ git submodule update --remote
... это должно получить последние коммиты в указанной ветви для каждого измененного таким образом подмодуля.
источник
У меня есть это в моем файле .gitconfig. Это все еще черновик, но оказался полезным на данный момент. Это помогает мне всегда подключать субмодули к их ветке.
источник
Мы используем Quack для извлечения определенного модуля из другого репозитория Git. Нам нужно извлекать код без всей кодовой базы предоставленного репозитория - нам нужен очень специфический модуль / файл из этого огромного репозитория, и его следует обновлять каждый раз, когда мы запускаем update.
Итак, мы достигли этого следующим образом:
Создать конфигурацию
В приведенной выше конфигурации он создает один каталог из предоставленного репозитория GitHub, как указано в конфигурации первого модуля, а другой - извлечь и создать файл из данного репозитория.
Другие разработчики просто нужно запустить
И это тянет код из вышеуказанных конфигураций.
источник
Единственный эффект выбора ветви для подмодуля состоит в том, что всякий раз, когда вы передаете
--remote
опцию вgit submodule update
командной строке, Git будет проверять в режиме отдельного HEAD (если--checkout
выбрано поведение по умолчанию ) последний коммит этой выбранной удаленной ветви.Вы должны быть особенно осторожны при использовании этой функции удаленного отслеживания ветвей для подмодулей Git, если вы работаете с мелкими клонами подмодулей. Ветвь, которую вы выбираете для этой цели в настройках субмодуля, НЕ является той, которая будет клонирована во время
git submodule update --remote
. Если вы передадите также--depth
параметр и не будете указывать Git, какую ветку вы хотите клонировать - и на самом деле вы не можете это сделать вgit submodule update
командной строке !! -, он будет неявно вести себя, как описано вgit-clone(1)
документации,git clone --single-branch
когда явный--branch
параметр отсутствует, и поэтому он будет клонировать только первичную ветвь .Неудивительно, что после этапа клонирования, выполненного
git submodule update
командой, он, наконец, попытается проверить последний коммит для удаленной ветви, которую вы ранее настроили для подмодуля, и, если это не основной модуль, он не является частью ваш местный мелкий клон, и поэтому он потерпит неудачу систочник
подмодуль git add -b development - имя-ветви-имя- https: //branch.git
источник