Обновите подмодуль до последнего коммита

269

У меня есть проект A, который является библиотекой, и он используется в проекте B.

Оба проекта A и B имеют отдельный репозиторий на github, НО внутри B у нас есть подмодуль A.

Я отредактировал некоторые классы в библиотеке, которая находится в хранилище A, я нажал на удаленное хранилище, поэтому библиотека (хранилище A) обновляется.

Эти обновления не отражают «ссылку» (подмодуль), который подмодуль ссылается на предыдущий коммит .... что я должен сделать, чтобы обновить подмодуль в git?

жир
источник

Ответы:

358

Введите каталог подмодулей:

cd projB/projA

Вытащите репо из вашего проекта A ( не будет обновлять статус git вашего родителя, проект B):

git pull origin master

Вернитесь в корневой каталог и проверьте обновление:

cd ..
git status

Если субмодуль обновился раньше, он покажет что-то вроде ниже:

# Not currently on any branch.
# Changed but not updated:
#   (use "git add ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#       modified:   projB/projA (new commits)
#

Затем подтвердите обновление:

git add projB/projA
git commit -m "projA submodule updated"

ОБНОВИТЬ

Как заметил @paul, начиная с git 1.8, мы можем использовать

git submodule update --remote --merge

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

Kjuly
источник
35
Кстати, если вы не являетесь владельцем подмодуля, вы можете просто сделать это, git submodule updateкогда кто-то еще обновит projA (вы получите новый идентификатор фиксации).
Кюли,
У меня есть главный репо субмодуля (proj A), но я являюсь коммиттером в proj B.
Жир
@Kjuly После коммита, как его перенести на пульт? Это просто git push?
KR29
1
@ KR29 верно, и полный cmd git push <remote> <branch>, например git push origin dev.
Кюли,
2
git submodule updateработает без флагов, только когда была извлечена фиксация (в proj B), которая обновляет ссылки на рассматриваемый подмодуль (ы) (proj A). Чтобы обновить proj B для ссылки на HEADветку удаленного отслеживания proj A, вы должны сделать это, git submodule update --remote --mergeкак показано в ответе Пола Хэтчера ниже.
Бен Бернс
109

С git 1.8 можно делать

git submodule update --remote --merge

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

git commit

Затем нажмите на изменения, так как без этого идентификатор SHA-1, указывающий на подмодуль, не будет обновлен, и поэтому изменение не будет видно никому другому.

Пол Хэтчер
источник
Несмотря на то, что я делаю это, git commitвсе остальные до сих пор этого не видят. On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: modified: SubmoduleA (new commits) modified: SubmoduleB (new commits)
Макс.
1
Сделали ли вы «git push» после своего коммита, имейте в виду, что коммит просто меняет ваш локальный репозиторий, вы должны вытолкнуть его на удаленный компьютер, чтобы его увидели все остальные
Пол Хэтчер
Отсутствует в этом ответе (но отмечено в других ответах ниже): обновленные подмодули должны быть подготовлены git addперед фиксацией.
Joshng
1
@joshng Я чувствую, что каждый, кто находится в точке, где они работают над подмодулями, поймет это. Это единственный пост, который мне помог, большое спасибо.
Husk Rekoms
38

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

git status

покажет что-то вроде:

modified:
   some/path/to/your/submodule

Тот факт, что субмодуль не синхронизирован, также можно увидеть с

git submodule

вывод покажет:

+afafaffa232452362634243523 some/path/to/your/submodule

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

просто добавьте это изменение:

git add some/path/to/your/submodule

и совершить это:

git commit -m "referenced newer version of my submodule"

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

git submodule update

Более подробную информацию о подмодулях можно найти здесь http://progit.org/book/ch6-6.html .

Адам Димитрук
источник
Если вы не видите +при запуске git submodule, убедитесь, что вы инициализировали и импортировали подмодули. Команды для этого git submodule initи git submodule update, соответственно.
Fureigh
19

Однолинейная версия

git submodule foreach "(git checkout master; git pull; cd ..; git add '$path'; git commit -m 'Submodule Sync')"
Энди Вебов
источник
2

Несколько других ответов рекомендуют объединять / фиксировать в каталоге подмодуля, что IMO может стать немного грязным.

Предполагая, что удаленный сервер назван, originи мы хотим masterветвь подмодуля (ов), я склонен использовать:

git submodule foreach "git fetch && git reset --hard origin/master"

Примечание: Это выполнит полный сброс для каждого подмодуля - если вы не хотите этого, вы можете изменить --hardна --soft.

XtraSimplicity
источник
1

Мой проект должен использовать «последний» для подмодуля. На Mac OSX 10.11, git версии 2.7.1, мне не нужно было заходить в мою папку субмодуля, чтобы собрать его коммиты. Я просто сделал обычный

git pull --rebase 

на верхнем уровне, и он правильно обновил мой подмодуль.

AnneTheAgile
источник
0

Ответ Энди сработал для меня, избежав $ path:

git submodule foreach "(git checkout master; git pull; cd ..; git add \$path; git commit -m 'Submodule Sync')"
Мигель Фернандес Малди
источник
Вероятно, причина того, почему ответ @Andy Webov не требовал экранирования, заключалась в том, что они использовали одинарные кавычки вокруг пути, например. '$path'
S0AndS0