Почему `git checkout` автоматически не выполняет` git submodule update --recursive`?

Кто-нибудь, пожалуйста, помогите мне понять подмодули в git. Я знаю, что они получают много криков в Интернете, но, поскольку я предполагаю, что разработчики git - умные люди, должна быть причина для текущего поведения - и, возможно, способ обойти мою проблему.

Итак, у меня есть проект и несколько подмодулей. У проекта есть разные ветки, например:

  • MyApp_version2
  • MyApp_version3
  • MyApp_version4
  • MyApp_liteversion
  • MyApp_development

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

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

Зачем мне это нужно?

Я ожидал, что git будет работать как svn. Когда я фиксирую свою работу в основном репо, я ожидаю, что git подумает примерно так: «Хорошо, он хочет зафиксировать свою работу сейчас. Я вижу, что подмодули в настоящее время находятся на ревизии abc, поэтому, когда он в какой-то момент в будущем вернуться к этому коммиту, он, вероятно, снова хочет, чтобы подмодули той же ревизии. "

Я не вижу ни одного случая, когда вы бы хотели, чтобы подмодули оставались в текущей ревизии, пока вы вернетесь на 3 года назад в свой основной репозиторий. Однако для такой реализации должна быть причина, не так ли?

Мне бы очень хотелось услышать, знает ли кто-нибудь из вас, что за этим стоит, но в любом случае мне бы очень хотелось решения. Есть ли способ сказать git: «Я хочу выполнить эту работу с этими подмодулями. Если я в какой-то момент вернусь в это состояние, я хочу, чтобы подмодули также были проверены в правильной версии».

Пример для пояснения

Мой основной репозиторий - это приложение, которое должно использовать SSL, и я нахожу библиотеку SSL (libSSL), которую добавляю в качестве подмодуля.

31 октября 2010 г. я создаю фиксацию в своем основном репозитории (2fd4e1), а подмодуль указывает на libSSL версии 3 (c67a2d).

Проходит время, libSSl обновляется до версии 34, я адаптирую свой код, жизнь идет хорошо.

14 мая 2013 года я создаю новую фиксацию (28fced), и подмодуль указывает на самую последнюю версию libSSL (849ee1).

Однако, если я проверю 2fd4e1, мой подмодуль останется на 849ee1, даже если исходный коммит был создан с помощью c67a2d. Git знает, что я сделал исходную фиксацию с помощью c67a2d, и я не понимаю, как вам может понадобиться другой подмодуль, кроме того, с которым была создана исходная фиксация.


person Markus    schedule 11.03.2014    source источник
comment
Возможно, вы проверяете разные коммиты только для того, чтобы посмотреть, как определенные вещи выглядят в разных точках - вы действительно хотите подождать, пока все подмодули обновятся каждый раз? Хотя, я согласен, было бы неплохо иметь возможность git checkout, чтобы он также выполнял соответствующие действия подмодуля, я бы не хотел, чтобы он был включен по умолчанию ...   -  person twalberg    schedule 11.03.2014
comment
Вы можете создать псевдоним для Git, который будет автоматически обновлять подмодули. См. stackoverflow.com/a/4611550/994153   -  person Colin D Bennett    schedule 10.10.2014
comment
Мне было сложно понять, как выполнить инклюзивный расчет по подмодулю. Название этого вопроса решило мою проблему. Интересно, почему это так непонятно.   -  person Brent Bradburn    schedule 25.02.2015
comment
Я считаю, что все команды подмодуля * должны быть заменены другими существующими командами, например: git submodule init foo, вероятно, должен быть аналогичен git clone foo, если foo не является URL-адресом. И если пользователь хочет сделать что-то более сложное, чем клонирование или оформление заказа, он может просто cd foo и вызвать git в обычном режиме. Это, вероятно, сделало бы все эти непонятные команды интуитивно понятными и простыми в использовании.   -  person VinGarcia    schedule 11.02.2017


Ответы (3)


Похоже, что то, что вы хотите сделать, может быть достигнуто с помощью git v2.13 с новой --recurse-submodules опцией git checkout. На странице руководства git-checkout:

- [no-] рекурсивные подмодули

Использование --recurse-submodules обновит содержимое всех инициализированных подмодулей в соответствии с фиксацией, записанной в суперпроекте. Если локальные изменения в подмодуле будут перезаписаны, проверка завершится неудачно, если не используется -f. Если ничего (или --no-recurse-submodules) не используется, рабочие деревья подмодулей обновляться не будут.

См. Также это соответствующее сообщение списка рассылки git об этой новой опции.

person Cyril Cressent    schedule 13.06.2017
comment
Вы можете установить это поведение по умолчанию начиная с версии 2.14.0 с помощью git config --global submodule.recurse true - person codehearts; 20.03.2018

Упростите свой ярлык / псевдонимы, используя:

alias checkitout='git checkout $1; git submodule update --recursive'
person thomas bogard    schedule 21.02.2019

По сути, вы хотите, чтобы git выполнял все операции рекурсивно и автоматически для всех подмодулей. Что, вероятно, тривиально для централизованной модели клиент-сервер, такой как svn.

Но git распространяется. Ваш подмодуль может поступать с совершенно другого URL-адреса с совершенно другим протоколом. Скорее всего, у вас нет push доступа к origin репо подмодуля, в то время как у вас есть доступ к основному репо.

Так что не может быть рекурсивного толчка.

Поэтому разработчики, вероятно, решили везде избегать автоматической рекурсии для подмодулей. Что стабильно, но очень больно.

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

person SzG    schedule 11.03.2014
comment
Нисколько! Я добавил пример. Это не имеет ничего общего с отправкой в ​​удаленный репозиторий. Проблема в следующем: допустим, я разрабатываю Firefox. В firefox версии 3 я использую libSSL версии 1 (как подмодуль). Позже, в firefox 24 я использую libSSL версии 4. Если я снова проверю Firefox версии 3, почему libSSL останется в версии 4, когда git знает, что это должна быть версия 1. FIrefox версии 3 ничего не знает о libSSL версии 4, поскольку она была выпущен спустя годы после создания исходного коммита - person Markus; 11.03.2014
comment
Снова. Нет автоматической рекурсии в подмодули. Всегда. Для единообразия. Наверное. Может быть. Кто знает. - person SzG; 11.03.2014
comment
вопрос касается оформления заказа, нет причин, по которым вы не можете выполнить рекурсивный заказ. Конечно, толкнуть будет невозможно. Вопрос в том, почему вам нужно выполнить git checkout someoldrev && git submodule update, потому что почти никогда не бывает причин для выхода из предыдущего подмодуля. - person Karl P; 16.07.2016