Подмодуль фиксированной ветки больше не доступен - PullRequest
0 голосов
/ 15 октября 2018

В репо у ветви есть субмодуль (назовите его суб-репо), установленный для определенного коммита.Однако этот коммит больше не существует (объединен в другой коммит).Теперь, когда я пытаюсь вытащить ветку репо, я получаю эту ошибку:

git submodule update --init sub-repo
fatal: reference is not a tree: xxxxx
Unable to checkout 'xxxxx' in submodule path 'sub-repo'

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

git checkout --branch valid-branch sub-repo
git add sub-repo
git commit

Но яЯ не уверен, что это систематический способ сделать это.Есть идеи?

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

TL; DR: то, что вы сделали, хорошо, хотя, возможно, и неполно.


Это что-то общего с подмодулями: они полагаются на точные хэши фиксацииидентификатор хешаСуперпроект записывает хэш-идентификатор коммита подмодуля как часть коммита суперпроекта.

Обычно люди не удаляют коммиты из репозиториев Git, так что это работает.Давайте назовем репозиторий суперпроекта R , а репозиторий субмодулей S («суперпроект» и «субмодуль» оба начинаются с S, ноони не могут быть оба S).Некоторые коммиты в R сообщают Git: В пределах S , проверьте коммит C по этому сохраненному хеш-идентификатору. Каккак только C перестает существовать в S , все , эти R коммиты становятся недействительными.Следовательно, если вы используете repo S в качестве подмодуля, и вы зависите от commit C в S , и кто-то удаляет C из S , вы получите эту проблему.Внутри одного репозитория невозможно удалить коммит, в котором нуждается остальная часть репозитория.Но в отдельных репозиториях , где зависимость - это просто необработанный хэш-идентификатор, который S даже не знает, что R использует, это легко сделать, в том числе и по ошибке.

Помимо «не делай этого», решения должны входить в суперпроект - хранилище R - и делать новые коммиты, которые либо ссылаются на какой-либо другой коммит в S , либо которые больше не используют S ввсе.Если вы управляете обоими репозиториями или у вас есть основания полагать, что S (или некоторые коммиты в S ) должны быть стабильными и всегда существовать, сохраняя S в качестве подмодуля является разумным.Если у вас нет контроля над S и он оказался нестабильным, вероятно, неразумно зависеть от него следующим образом.

Поскольку подмодуль равен Git-репозиторий, способ, которым вы выбираете коммит внутри него, заключается в cd включении в него и работе с ним как в Git-репозитории (что вы и сделали).Затем, когда подмодуль находится на каком-то новом коммите C2, который, как вы уверены, на этот раз стабилен, вы делаете новый коммит в R точно так же, как вы это сделали.Если единственное отличие между старым коммитом R и новым заключается в том, что новый коммит имеет другой хеш подмодуля, вы можете вызвать этот новый коммит в R новая улучшенная версия старого коммита.

Возможно, вы захотите выбросить (и / или заменить новыми или улучшенными версиями) все ваши старые коммиты, которые ссылаются надо C в S , 1 , хотя, если это возможно, поскольку удаление C сломало их всех.Делать это чисто сложно, поэтому для него нет инструментов (если, возможно, BFG не вырастил инструмент для замены подмодуля).Вероятно, должен быть фильтр git filter-branch специально для замены подмодулей.Но даже найти эти коммиты довольно сложно: вы должны просмотреть и, возможно, скопировать в новый и улучшенный коммит замены, каждый коммит в R ,Это то, для чего созданы оба инструмента (BFG и git submodule).(Как правило, они хотят внести некоторые изменения в некоторые файлы, а не в некоторые подмодули, но это означает, что у них есть вся логика и все на месте, им просто нужен какой-то способ для идентификации и замены хеш-идентификаторов подмодулей.)


1 Как отмечено в комментариях ниже, это ссылка от R до (C -in- * 1134)* S ), т. Е. Для коммита, которого больше не существует.

0 голосов
/ 15 октября 2018
cd sub-repo
git reset --hard HEAD
git pull origin 'your branch name'
cd ../
...