Как отредактировать внешний подмодуль и отправить его в свой репозиторий?

Я работаю над своей диссертацией, где я расширяю еще одну статью. В этой статье весь их код опубликован в репозитории X, а также используется сам подмодуль: назовем его Y.

Для моего собственного проекта я сделал собственный репозиторий Z, в который я включил X как подмодуль и, таким образом, Y как вложенный подмодуль. Однако я хотел бы внести изменения в код в X и Y, а также иметь возможность отправить это в свое собственное репо, чтобы я мог использовать его в нескольких местах. У меня нет разрешения на отправку X и Y, так как это чужое репо. Каков наилучший способ сделать это? Заранее спасибо, я запутался :D

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

git push --set-upstream origin new_branch
ERROR: Permission to \[repo X\] denied to \[myusername\].
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Теперь я разветвил репозиторий X и изменил URL-адрес в своих .gitmodules. Что теперь происходит с подмодулем Y?

С подмодулем никогда ничего не происходит. Это другой репозиторий Git. В своей вилке вы можете изменить содержимое файла .gitmodules, чтобы указать другой URL-адрес для еще одной вилки, если хотите, или вы можете оставить существующий URL-адрес в покое, чтобы продолжить использовать тот же другой Git-репозиторий.

torek 22.03.2022 08:30

Теперь я также изменил вилку в моем .gitmodule во вложенном репо. Но вы говорите, что если я хочу изменить содержимое двух репозиториев на бумаге, мне нужно найти другое решение? Не могли бы вы указать мне правильное направление там?

EBDIJK 22.03.2022 10:59
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
26
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Начнем с предыстории подмодулей.

Подмодули просты, но со сложными результатами. «Подмодуль» состоит из двух частей: файла .gitmodules и двух репозиториев Git. Один репозиторий называется суперпроект, а другой — подмодуль. Суперпроект содержит в одном или нескольких коммитах необработанный хэш-идентификатор коммита для проверки в подмодуля. Вот и вся картина — во всяком случае, до тех пор, пока мы не начнем работать.

Предположим, вы начинаете с клонирования суперпроекта

Допустим, вы бежите:

git clone --no-recurse-submodules <url> super
cd super

Теперь у вас есть фиксация извлечения в из репозитория суперпроекта с указанием, что Git, запустив в этого суперпроекта, должен проверить фиксацию в подмодуле. Но нет никакого подмодуля. Вы клонировали только репозиторий один, а не два.

Параметр --no-recurse-submodules гарантирует, что Git еще не клонирует подмодуль. В любом случае это значение по умолчанию, но мы сделали это здесь специально, чтобы сделать его очевидным и на случай, если вы изменили свои личные настройки, чтобы включить рекурсию.

Теперь вам нужно указать Git на полный проверку, если вы хотите, чтобы подмодуль был клонирован, а фиксация проверена. (Если вы предпочитаете вообще не возиться с подмодулем, вы можете оставить все в этом состоянии: у вас просто не будет подмодуля, даже если суперпроект требует его. Фактический шаг клонирования и проверки не является обязательным, при условии, что все, что вы делаете, не является необходимость подмодулем.Репозиторий Git для Git, например, включает в себя ссылку на подмодуль программы, которая проверяет коллизии SHA-1, но это конкретно необязательный, и вам не нужно беспокоиться об этом .)

Чтобы завершить проверку, вы теперь запускаете:

git submodule update --init

(если вы используете --recurse-submodules в своем клоне, команда git clone запускает эту команду для вас после шага git checkout, шага 61).

Здесь есть проблема: это git submodule update --init должно работать git clone. Команде git clone требуется URL-адрес. Откуда берется URL? Решением этой проблемы является файл .gitmodules, который должен существовать в подтвержденном коммите в шаг 6; в этом файле должны быть перечислены URL-адреса всех подмодулей, которые должны быть клонированы в этот момент.

После того, как эти подмодули клонированы, команда git submodule update, которую вы теперь можете использовать без флага --init, выбирает коммит по хэш-идентификатору, который должен git checkoutв для каждого подмодуля, указанного суперпроектом. Идентификатор хэша, который команда суперпроекта Git git submodule update извлекает в, репозиторий подмодуля — это тот, который хранится в извлеченном коммите (снова на шаге 6) — или, точнее, идентификатор хэша, который сейчас находится в Git показатель (но он попал в Git’s показатель). index через кассу на шаге 6).

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


1Команда git clone в основном является сокращением для запуска шести или семи команд, все, кроме одной, являются командами Git:

  1. mkdir или любая другая команда вашей системы для создания новой папки/каталога. Остальные команды выполняются в в новой папке.
  2. git init: это создает новый, абсолютно пустой репозиторий.
  3. git remote add: это добавляет пульт, имя которого вы можете выбрать, но все используют значение по умолчанию origin с URL-адресом, который вы указали для git clone.
  4. Любые указанные вами команды git config (по умолчанию нет).
  5. git fetch origin: это копирует все коммиты из программного обеспечения Git, которое отвечает на указанный вами URL-адрес. Он копирует нет ответвлений:, вместо этого их ветки становятся вашими именами для удаленного отслеживания.
  6. git checkout: это создает одну ветку в вашем новом репозитории и проверяет коммит. Этот шаг является необязательным, так как он скрыт --no-checkout.
  7. git submodule update --init, если вы призвали к этому, и если есть подмодули, перечисленные в фиксации, проверенной на шаге 6. Этот шаг является необязательным и не используется по умолчанию.

Предположим, вы не начинаете таким образом

Представьте, что вместо только что клонируется суперпроект:

git clone --no-recurse-submodules <url> super
cd super

вы лично сначала клонируете сам суперпроект, но затем вы также лично клонируете подмодуль:

git clone --no-recurse-submodules <url1> super
cd super
mkdir -p super/sub
git clone --no-recurse-submodules <url2> super/sub

Теперь вы можете запустить git checkout или git switch в super (где вы сейчас находитесь), а затем git submodule update в super и Git не нужно клонировать новый репозиторий. Git просто использует клон подмодуля существующий, который вы создали в суперпроекте.

При использовании этого метода содержимое файла .gitmodules игнорируется. Таким образом, используя этот метод, вам не нужно исправлять какие-либо файлы .gitmodules в любом суперпроекте, чтобы использовать другой URL-адрес подмодуля.


2Вы также можете запустить git submodule absorbgitdirs после двух команд git clone, чтобы переключиться со старой модели хранилища подмодулей Git 1.x на новую модель Git 2.x. Это не обязательный, это просто хорошая идея для несколько запутанных причин "подмодули могут приходить и уходить, а затем возвращаться снова". Когда подмодули делать удаляются — например, путем извлечения исторической фиксации — результат в настоящее время довольно уродлив: у подмодулей есть много проблем с пользовательским интерфейсом, что приводит к тому, что многие Все еще называют их модулями рыдать, несмотря на значительные улучшения в них с самого начала. дни Гита.


Последствия

Что все это значит? Ну, скажем, есть какой-то существующий суперпроект, который вам не нужно трогать, но у вас есть подмодуль, или подмодуль из подмодуль, который вам делать нужно трогать, и в результате вы хотите, чтобы люди клонировали ваш подмодуль, или ваш под-под-модуль, когда они клонируют суперпроект.

Все, что вам нужно сделать, В самом делеимеют, — это сделать доступным собственный репозиторий Git. Те, кто «осведомлен», могут аккуратно клонировать подмодуль ваш и поместить его в надстройку(и), предоставленную(ые) существующим(и) суперпроектом(ами). Но если вы хотите, чтобы другие клонировали суперпроект (только удобный) и имели подмодуль git submodule update --init клона ваш этого суперпроекта, вы должны обновить файл .gitmodules в любом репозитории Git, который действует как суперпроект для вашего подмодуля.

Допустим, у вас изначально есть такая структура:

super                <-- their superproject
super/sub1           <-- their submodule
super/sub1/sub2      <-- their sub-submodule

Есть два файла .gitmodules: один в super/sub1/.gitmodules, в котором указан URL-адрес, с которого можно клонировать sub2, и один в super/.gitmodules, в котором указан URL-адрес, с которого можно клонировать sub1.

Поскольку вы создали новый репозиторий заменяетsub2, теперь вы должны создать новый репозиторий заменяетsub1, в котором .gitmodules файл вsub1 содержит новый URL-адрес для вашей замены sub2. Но чтобы суперпроект super перечислил новый URL-адрес для вашей замены sub1, теперь вы должны создать новый репозиторий заменяетsuper, в котором .gitmodules файл вsuper перечисляет новый URL-адрес для вашей sub1 замены.

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

Но это если. Подмодули уже ужасны; какой еще уровень ужаса здесь? Вы можете вместо того, чтобы дублировать другие репозитории только для обновления одного файла .gitmodules в каждом из них, предоставить инструкцию, что после выполнения рекурсивного клонирования или update --init те, кто хочет использовать ваш суб-суб-модуль, должны удалить один клон и заменить его. с твоим.

Это ваш выбор: сделать его удобным для других, сделав его неудобным для вас, или сделать его более удобным для вас, сделав его неудобным для других.

Большое спасибо за ваш супер развернутый ответ! Это дало мне лучшее понимание работы подмодулей.

EBDIJK 28.03.2022 15:52

Другие вопросы по теме