Git commit для общего подмодуля (основная ветвь)

У меня есть два или более проекта (пусть я называю их ProjectFoo и ProjectBar ) с некоторым общим кодом , который я вставил в подмодуль .

Я понимаю, что если Я фиксирую изменения в подмодуле из ProjectFoo , это будет в отдельной голове, что только все клоны ProjectFoo могут видеть:

(master) $ cd ProjectFooBarCommoneSubmodule/
(master) $ git commit -am "Common code fix."
(56f21fb0...) $ git push
Everything up-to-date

Это, вероятно, потому что мастер ] ветка не изменилась. Возможно, я мог бы сделать что-то вроде git checkout master && git merge Все актуально , но это кажется довольно уродливым. Может быть, git reset --hard master сделал бы то же самое, но это кажется еще более уродливым.

Как сделать общий код общим для проекта, обновив из этих проектов, используя Это? Другими словами, фиксация в этом подмодуле должна обновлять все различные репозитории (не только клоны , но и клоны ), которые используют этот же подмодуль.

---- EDIT ----

Видимо, мой извлеченный репозиторий был испорчен и сломан. Он должен был с самого начала работать так (на ProjectFoo в этом примере):

(master) $ cd ProjectFooBarCommoneSubmodule/
(master) $ git commit -am "Common code fix."
(master) $ git push
....
   fbfdd71..0acce63  master -> master
(master) $ cd ..
(master) $ git add ProjectFooBarCommoneSubmodule
(master) $ git commit -m "Submodule update."

Затем, чтобы получить это изменение от других проектов, например ProjectBar :

(master) $ cd ProjectFooBarCommoneSubmodule/
(master) $ git pull

обновить до последнего общего кода. мастер git checkout может потребоваться, если он находится на отдельной головке.

56
задан AstroCB 17 February 2015 в 04:46
поделиться

1 ответ

Короткий ответ:

cd ProjectFooBarCommoneSubmodule
git checkout master
<Do your editing>
git commit --all -m "Lots of fixes"
git push submodule_origin master
cd ..

git add ProjectFooBarCommoneSubmodule
git commit -m "Bumped up the revision of ProjectFooBarCommoneSubmodule"
git push origin master

Более длинный:

Подмодули Git — это механизм зависимостей, где основной проект (скажем, A) определяет указанную ревизию в подпроекте (скажем, B), который будет использоваться при построении проекта А. Чтобы инструмент был полезным, его поведение должно быть предсказуемым с точки зрения А. Зависимости не могут измениться, если только кто-то не решит внести изменения в проект A. Могут произойти всевозможные неприятные вещи, если изменения проекта B будут автоматически импортированы, из которых ошибки компиляции, вероятно, самые лучшие, поскольку A сразу же заметит сбои. Вот почему голова B: держится в отсоединенном состоянии.

Состояние B хранится в A (проверьте git submodule status ), и изменение ревизии должно быть сделано и зафиксировано в A, чтобы оно имело какой-либо эффект.Это то, что происходит в приведенном выше примере: A изменяет номер версии, хранящийся в репозитории, и устанавливает последнюю версию. Этот процесс необходимо будет повторить и в другом основном репо, поэтому нет автоматического переключателя «использовать мастер», AFAIK.

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


РЕДАКТИРОВАТЬ: я попытаюсь объяснить это лучше

Я позволил себе создать примеры проектов в моей учетной записи github. Коммиты бессмысленны и содержат мусор, но установка должна быть в порядке. Пожалуйста, проверьте это, чтобы следовать.

И ProjectFoo, и ProjectBar совместно используют код в общем подмодуле.

ProjectFooBarCommoneSubmodule: мастер 6850e4e4c1fac49de398

В ProjectFoo:

git submodule status

-6850e4e4c1fac49de39890703f21486ca04b87a0 общих

В ProjectBar:

git submodule status

-6850e4e4c1fac49de39890703f21486ca04b87a0 общих

Так как точки на ту же ревизию, правильно? Хитрость заключается в том, чтобы увидеть, что ProjectFoo и ProjectBar указывают на ревизию (6850e4e4c1fac49de39890703f21486ca04b87a0) , а не на ветку (мастер), хотя это одно и то же. Первый - это отдельная голова, а другой - именованная ветвь.

Если вы хотите внести некоторые исправления в ProjectFooBarCommoneSubmodule, вы можете перейти в подкаталог, например, в ProjectFoo и выберите ветку вместо ревизии:

git checkout master 
<Do your coding and pushing here>

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

git submodule status

+e24bd2bf45d52171a63b67ac05cd4be0ac965f60 common (heads/master-1-ge24bd2b)

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

Теперь вам также нужно обновить ссылку в ProjectBar. Перейдите в ProjectBar/common и выполните git fetch origin (это быстрое слияние), выполните

git checkout master 
cd ..
git add common
git commit -m "Bumped up the revision"
git push origin master # to publish the revision bump to everybody else

. Таким образом, как и в случае с любым репозиторием git, вам не нужно работать с отдельной головкой. Вы можете либо работать с мастером, либо создать именованную ветку. В любом случае убедитесь, что исходный код содержит изменения ProjectFooBarCommoneSubmodule, иначе вы сломаете и ProjectFoo, и ProjectBar, если они ссылаются на что-то несуществующее. Надеюсь, это объяснило это лучше

68
ответ дан 26 November 2019 в 17:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: