клонирование репо с вложенными подмодулями не работает - PullRequest
1 голос
/ 29 июня 2019

У меня есть несколько отдельных репозиториев git, в которых нет подмодулей. Задача состоит в том, чтобы собрать иерархическое дерево этих репозиториев и использовать его для обмена между пользователями. Это тривиально со схемами «поддерево» или «субрепорация», но, похоже, не работает с «подмодулями». Причиной использования субмодулей является низкая производительность git в системах nfs. В моем случае оформление заказа занимает более 2 часов

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

 mkdir m1 ; cd m1 ; git init ; date > a.txt ; git add --all ; git commit -m added ; cd -
 mkdir m2 ; cd m2 ; git init ; date > b.txt ; git add --all ; git commit -m added ; cd -
 mkdir m3 ; cd m3 ; git init ; date > c.txt ; git add --all ; git commit -m added ; cd -
 mkdir msub; cd msub; git init; date > d.txt; git add --all; git commit -m added;
 git submodule add `realpath ../m1` m1
 cd m1
 git submodule add `realpath ../../m2` m2
 git submodule add `realpath ../../m3` m3
 git commit -m 'added submodules'
 cd ..
 git commit -m 'added a submodule'
 cd ..
 git clone --recursive msub msub1

В результате он создает msub1 с одним подмодулем верхнего уровня (m1).

В других случаях я получал фатальную ошибку, похожую на эту, после клона первого подмодуля.

fatal: git upload-pack: not our ref 89434ad65c1e697bfa311cd0260dfe1997985e65
fatal: remote error: upload-pack: not our ref 89434ad65c1e697bfa311cd0260dfe1997985e65
Fetched in submodule path 'soc', but it did not contain 89434ad65c1e697bfa311cd0260dfe1997985e65. Direct fetching of that commit failed.

Я пытался добавить субмодули напрямую в 'm1', и это, казалось, улучшило ситуацию, но я не могу сделать это с реальными репозиториями.

Итак, требуемая схема, похоже, не работает. Есть ли способ это исправить?

Ответы [ 2 ]

1 голос
/ 29 июня 2019
git submodule add `realpath ../m1` m1
cd m1
git submodule add `realpath ../../m2` m2
git submodule add `realpath ../../m3` m3

Здесь вы изменили свою локально клонированную копию m1, но не вернули изменение обратно к исходному m1.

git commit -m 'added submodules'
cd ..
git commit -m 'added a submodule'

Вы забыли добавить изменения в подмодуль.

cd ..
git clone --recursive msub msub1

Когда git клонирует msub в msub1, он пытается клонировать m1 из своего исходного каталога, а не из msub/m1. Просто потому, что на верхнем уровне .gitmodules есть путь к исходному m1. А оригинальный m1 не имеет подмодулей.

Чтобы исправить весь рабочий процесс, вам нужно:

  • git add изменено m1 до его совершения;
  • cd m1 && git push origin master (ну, push для непроигранного репо не сработает, поэтому cd для оригинала и pull вместо).

Итак, весь исправленный скрипт:

#! /bin/sh
set -e

mkdir m1 ; cd m1 ; git init ; date > a.txt ; git add --all ; git commit -m added ; cd -
mkdir m2 ; cd m2 ; git init ; date > b.txt ; git add --all ; git commit -m added ; cd -
mkdir m3 ; cd m3 ; git init ; date > c.txt ; git add --all ; git commit -m added ; cd -
mkdir msub; cd msub; git init; date > d.txt; git add --all; git commit -m added;
git submodule add `realpath ../m1` m1
cd m1
git submodule add `realpath ../../m2` m2
git submodule add `realpath ../../m3` m3
git commit -m 'added submodules'
cd ../../m1
git pull ../msub/m1 master
cd ../msub
git add m1
git commit -m 'added a submodule'
cd ..
git clone --recursive msub msub1
1 голос
/ 29 июня 2019

Ответ "not our ref" обычно означает, что ваш сервер настроен на ограничение прямой выборки объектов по идентификатору, и нет подходящей ссылки, позволяющей извлечь этот объект.

Git предоставляет три вариантакоторый контролирует, можете ли вы получить произвольный идентификатор объекта: один, который позволяет выбрать любой произвольный объект, к которому Git имеет доступ, другой, который позволяет получить любой объект, достижимый из ссылки, и другой, который дополнительно позволяет получить объекты, достижимые из скрытых ссылок.Большинство провайдеров серверов предпочитают отключить один или несколько из них, что часто означает, что вы можете запросить идентификатор объекта только в том случае, если на него указывает не скрытая ссылка (т. Е. Ветвь или тег).

"Не нашref "сообщение" означает, что вы пытаетесь получить объект по идентификатору объекта, который используется для подмодулей, но сервер не позволяет его по вышеуказанной причине.Если вы используете кэширование ссылок Bitbucket Server, это также может означать, что сервер кэширует устаревшие данные;в таком случае вы должны отключить кэширование ссылок, если вам нужно, чтобы все работало.

Есть пара вещей, которые вы можете сделать.Если вам нужна возможность проверить произвольную ревизию, вы можете создать ветку, которая на нее указывает.Или, если вашему подмодулю не нужна конкретная ревизия, а только самая последняя ветка, вы можете установить опцию submodule.<name>.branch (см. man gitmodules), и тогда вы всегда будете проверять последнюю ветку.Если вы используете собственный сервер, вы можете установить для uploadpack.allowAnySHA1InWant значение true.Наконец, вы можете вручную извлечь подмодуль (возможно, с помощью git submodule foreach), который обычно будет иметь нужную вам ревизию.

...