Git не будет инициализировать / синхронизировать / обновлять новые подмодули


113

Вот часть содержимого моего .gitmodulesфайла:

[submodule "src/static_management"]
        path = src/static_management
        url = git://github.com/eykd/django-static-management.git
[submodule "external/pyfacebook"]
        path = external/pyfacebook
        url = http://github.com/sciyoshi/pyfacebook.git

Однако .git/configсодержит только первое:

[submodule "src/static_management"]
        url = git://github.com/eykd/django-static-management.git

Второй подмодуль ( external/pyfacebook) был добавлен другим разработчиком в ветке функций. Я унаследовал разработку сейчас и проверил ветку функций. Однако Git не потянет за меня подмодуль. Я пробовал:

  • git submodule init
  • git submodule update
  • git submodule update --init
  • git submodule sync
  • Удаление всех определений подмодулей из .git/configи запуск git submodule init. Он копирует только существующий ранее подмодуль и игнорирует новый.
  • Ввод новых определений подмодулей .git/configвручную и выполняется git submodule update. Только существующие субмодули требуют обновления.

в различных комбинациях, но git просто не будет обновляться .git/configна основе нового содержимого .gitmodules, а также не будет создавать external/pyfacebookпапку и извлекать содержимое подмодуля.

Что мне не хватает? Действительно ли .git/configтребуется ручное вмешательство (добавление записи подмодуля вручную ) и почему?

Изменить: ручное вмешательство не работает. Добавление новой записи подмодуля вручную .git/configничего не дает. Новый подмодуль игнорируется.


1
работает 1.7.7.1 и имеет ту же проблему: "git submodule sync" не обновляет .git / config после изменения на .gitmodules.
Джеймс Приттс

Ответы:


92

У меня была такая же проблема - оказалось, что файл .gitmodules был зафиксирован, но фактическая фиксация подмодуля (то есть запись идентификатора фиксации подмодуля) не была.

Добавление его вручную, похоже, помогло - например:

git submodule add http://github.com/sciyoshi/pyfacebook.git external/pyfacebook

(Даже не удаляя ничего из .git / config или .gitmodules.)

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

Добавление некоторых дополнительных комментариев к этому рабочему ответу: Если git submodule init или git submodule update не работает, то, как описано выше, git submodule add url должен помочь. Это можно проверить с помощью

 git config --list

и вы должны получить запись о подмодуле, который вы хотите извлечь, в результате команды git config --list. Если в результате конфигурации есть запись вашего подмодуля, то теперь обычное обновление подмодуля git --init должно вытащить ваш подмодуль. Чтобы протестировать этот шаг, вы можете вручную переименовать подмодуль, а затем обновить подмодуль.

 mv yourmodulename yourmodulename-temp
 git submodule update --init

Чтобы узнать, есть ли у вас локальные изменения в подмодуле, это можно увидеть с помощью git status -u (если вы хотите увидеть изменения в подмодуле) или git status --ignore-submodules (если вы не хотите видеть изменения в подмодуль).


Для чего external/pyfacebook?
Игорь Ганапольский

2
@IgorGanapolsky Это путь назначения для вашего подмодуля.
yuhua

Это мне помогло, спасибо большое! Я мог бы просто добавить, что если целевой путь уже существует (что он сделал для меня в результате попытки других команд), вы получите следующее сообщение, которое только усугубляет путаницу:'your/local/path' already exists and is not a valid git repo
Майкл Амбрус

1
один лайнер для чтения записей в «git config --list»:git config --list | grep submodule | sed -e "s/submodule\.//" -e "s/\(.*\)\.url=\(.*\)/git submodule add --force \2 \1/" | bash
Puggan Se

64

git версии 2.7.4. Эта команда обновляет локальный код git submodule update --init --force --remote


21
Ничего не делает для меня.
Карло Вуд

1
Что касается git- submodule [документация) ( git-scm.com/docs/git-submodule#git-submodule---remote ), вышеупомянутая команда должна обновлять локальную ветвь подмодулей.
Палик

1
@palik ты молодец!
Денис Трофимов

1
Вы можете обновить отдельный модуль с помощью git submodule update --init --force --remote <module-name>.
Адам Фарина

15

Была такая же проблема, когда git игнорировал initи updateкоманды и ничего не делал.

КАК ИСПРАВИТЬ

  1. Папка вашего подмодуля должна быть зафиксирована в репозитории git
  2. Его не должно быть в .gitignore

Если эти требования соблюдены, он будет работать. В противном случае все команды будут выполняться без каких-либо сообщений и результата.

Если вы все это сделали, но все равно не работает:

  1. Добавить подмодуль вручную, например git submodule add git@... path/to
  2. git submodule init
  3. git submodule update
  4. зафиксировать и нажать все файлы - .gitmodulesи папку вашего модуля (обратите внимание, что содержимое папки не будет фиксироваться)
  5. оставьте свой локальный репозиторий git
  6. клонировать новый
  7. убедитесь, что у .git/configвас еще нет подмодулей
  8. Теперь git submodule init- и вы увидите сообщение, что модуль зарегистрирован
  9. git submodule update - получит модуль
  10. Теперь посмотрите, .git/configи вы найдете зарегистрированный подмодуль

1
Я считаю, что путь к подмодулям МОЖЕТ быть в .gitignore. По крайней мере, я заставил его работать, следуя ответу @DaveJamesMiller. Больше у меня ничего не работало.
gebbissimo

7

Кажется, здесь (тоже) много путаницы в ответах.

git submodule initэто не предназначено , чтобы волшебным образом генерировать вещи в .git / конфигурации (от .gitmodules). Он предназначен для настройки чего-либо в полностью пустом подкаталоге после клонирования родительского проекта или выполнения фиксации, которая добавляет ранее несуществующий подмодуль.

Другими словами, вы следуете a git cloneпроекта, в котором есть подмодули (о чем вы узнаете по тому факту, что клон извлек файл .gitmodules) на git submodule update --init --recursive.

Вы не следуете git submodule add ...за git submodule init(или git submodule update --init), это не должно работать. Фактически, добавление уже обновит соответствующий .git / config, если все работает.

РЕДАКТИРОВАТЬ

Если ранее несуществующий подмодуль git был добавлен кем-то другим, и вы выполняете git pullэту фиксацию, тогда каталог этого подмодуля будет полностью пуст (когда вы выполняете git submodule statusхеш нового подмодуля, он должен быть виден, но -перед . это) в этом случае вы должны следовать вашему git pullтакже с git submodule update --init(плюс , --recursiveесли это подмодуль внутри субмодуля), чтобы получить новый, ранее не существовавшее, подмодуль проверил; так же, как после первоначального клона проекта с подмодулями (где, очевидно, у вас и раньше не было этих подмодулей).


1
Это интересно, потому git help submoduleчто об init говорится следующее: «init: инициализировать подмодули, записанные в индексе (которые были добавлены и зафиксированы где-то еще), путем копирования имен и URL-адресов подмодулей из .gitmodules в .git / config». Так он уверен , звучит , как он должен делать именно то , что вы говорите , это не делает ...? Пришло время обновить документацию по git?
Брэд

@brad Не думаю, что я это сказал, но я добавил пояснение для этого конкретного случая. Спасибо.
Карло Вуд

@CarloWood есть идея, почему авторы подмодулей git решили, что --initэто необходимо для получения новых подмодулей (вместо их автоматического включения update)? Похоже, что обновление вашего репозитория должно захватить все необходимое, если оно не уничтожит данные. С --initзаставляет вас знать , что новые Подмодули могли быть созданы, или просто всегда выдают --initкаждый раз , когда в этом случае, опять же , казалось бы , что она должна быть включена по умолчанию.
Catskul 01

@Catskul Очевидно, я понятия не имею, почему авторы подмодулей git что-то решили, но я предполагаю, что «update» зарезервирован для обновления того, что уже существует, а «init» используется для создания чего-то (локально) нового. Под капотом они, вероятно, достаточно сильно отличаются, чтобы требовать другой команды.
Карло Вуд

6

У меня была та же проблема, но ни одно из вышеперечисленных решений не помогло. Записи в .gitmodules и .git / config были правильными, но команда git submodules update --init --recursiveничего не делала. Я также удалил каталог подмодулей, запустил git submodules update --init --recursiveи вернул каталог подмодулей, но с точно такой же фиксацией, как и раньше.

Я нашел ответ на этой странице . Команда такая:git submodule update --remote


2
Для меня это тоже было правильным решением. Я бежал git submodule updateвместо git submodule update --remote.
Эндрю Медлин

5

Вроде как по волшебству, но сегодня я побежал git submodule initза git submodule syncним, git submodule updateи он начал тянуть мои подмодули ... Магия? Возможно! Это действительно один из самых неприятных моментов с Git ...

Сотрите это. Я действительно заставил это работать git submodule update --init --recursive. Надеюсь это поможет.

PS: Убедитесь, что вы находитесь в корневом каталоге git, а не в подмодуле.


7
Нет, это абсолютно ничего для меня не делает.
Игорь Ганапольский

@IgorGanapolsky Я отредактировал ответ выше тем, что сработало для меня. Сообщите мне, если это сработает!
Леви Фигейра

Я пробовал ваши новые команды, но они тоже ничего не сделали.
Игорь Ганапольский 01

5

Думая , что вручную настройки .gitmodulesдостаточно является НЕПРАВИЛЬНО

Мой местный git version 2.22.0на момент написания этой статьи.

Итак, я пришел в эту ветку, задаваясь вопросом, почему не git submodule initработает; Я настроил .gitmodulesфайл и приступил к выполнению git submodule init...

ВАЖНЫЙ

  1. git submodule add company/project.git includes/projectэто требуется (при добавлении модуля в первый раз), это будет:

    • добавить конфигурацию в .git/config
    • обновить .gitmodulesфайл
    • отслеживать расположение подмодуля ( includes/projectв этом примере).
  2. Вы должны затем git commitпосле добавления подмодуля, это будет совершать .gitmodulesи гусеничное место подмодуля.

Когда проект будет снова клонирован, он будет иметь .gitmodulesи пустой каталог подмодулей (например, includes/projectв этом примере). На данный момент .git/configеще нет конфигурации подмодуля, пока он не git submodule initбудет запущен, и помните, что это работает только потому, что .gitmodulesИ includes/projectотслеживаются в основном репозитории git.

Также для справки см .:


4

По ответу Дэйва Джеймса Миллера я могу подтвердить, что у меня это сработало. Здесь важно было зафиксировать идентификатор фиксации подпроекта. Просто иметь запись в .gitmodules было недостаточно.

Вот подходящий коммит:

https://github.com/dirkaholic/vagrant-php-dev-box/commit/d5f4c40bdbd80eefbb5ac6029823733f591435ae


3

У меня такая же проблема.

.gitmodulesбыл подмодуль, но после git submodule initкоманды его не было .git/config.

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


2

Как и вы, я обнаружил, что git submodule sync не делает того, что вы ожидаете. git submodule addURL-адрес подмодуля изменяется только после повторного явного выполнения.

Итак, я вставил этот скрипт ~/bin/git-submodule-sync.rb:

https://gist.github.com/frimik/5125436

И я также использую ту же логику в нескольких сценариях развертывания git после получения.

Все, что мне нужно сделать сейчас, это отредактировать .gitmodules, затем запустить этот скрипт, и он, наконец, заработает так, как я думал git submodule sync.


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

2

Сегодня у меня была такая же проблема, и я понял, что, поскольку я набрал git submodule initтогда, у меня была эта строка в моем .git/config:

[submodule]
   active = .

Я удалил это и набрал:

git submodule update --init --remote

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


2

Проблема для меня в том, что предыдущий разработчик репо зафиксировал эту submodules/thingпапку как обычную папку, что означает, что когда я пытался запустить git submodule add ..., она не выполнялась с:, 'submodules/thing' already exists in the indexно попытка обновить подмодуль также не удалась, потому что он увидел, что путь не содержат подмодуль.

Чтобы исправить это, мне пришлось удалить submodules/thingпапку, зафиксировать удаление, а затем запустить git submodule addкоманду, чтобы правильно добавить ее обратно:

git submodule add --force --name thing https://github.com/person/thing.git submodules/thing

1

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

Снова добавление подмодулей и сравнение уровней фиксации подмодуля с найденными в git show $breaking_commit_sha(поиск строк, соответствующих регулярному выражению ^-Subproject) для корректировки необходимых исправлений.


1

Удаление каталога подмодуля и его содержимого (папка "external / pyfacebook"), если он существует раньше, git submodule add ...может решить проблемы.


1
Это было проблемой для меня. Кто-то зафиксировал папку "submodule" как обычную папку, что означает, что когда я пытался запустить "git submodule add ...", это не помогло: "'vendor / mobx-state-tree' уже существует в индексе" , но попытка обновить подмодуль также не удалась, потому что было обнаружено, что путь не содержит подмодуля). Чтобы исправить это, мне пришлось удалить папку, зафиксировать удаление, а затем запустить команду git add, чтобы правильно добавить ее.
Venryx

1

У меня была аналогичная проблема с подмодулем. Он просто не хотел, чтобы его клонировали / вытаскивали / обновляли / что-то еще.

При попытке повторно добавить подмодуль с помощью git submodule add git@my-repo.git destinationя получил следующий результат:

A git directory for 'destination' is found locally with remote(s):
  origin        git@my-repo.git
If you want to reuse this local git directory instead of cloning again from
  git@my-repo.git
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.

Итак, я попытался применить команду добавления :
git submodule add --force git@my-repo.git destination

В моем случае это сработало.


0

Для записи:
я создал ту же проблему, добавив пустой репозиторий в качестве подмодуля. В этом случае для подмодуля не было доступного ссылочного хэша, что привело к ошибке, описанной исходным плакатом.

Принудительное добавление репозитория после его фиксации решило проблему (как в сообщении Arvids)
git submodule add --force git@my-repo.git destination


0
  • Удалите подмодуль из своего .git/config
  • Выполнить git submodule initкоманду
  • Перейдите в каталог вашего подмодуля и запустите git pull origin master

Он должен работать сейчас


0

Просто поделился тем, что сработало для меня:

git clone --recurse-submodules <repository path>

Это клонирует удаленный репозиторий, уже включающий подмодули. Это означает, что вам не нужно запускать git submodule update или init после клонирования.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.