Этот метод по сути аналогичен принятому ответу @VonC, но он расширен, чтобы его было легче понять.
Ситуация
Это ошибка, которую я получал при выдаче git svn dcommit
#object# doesn't exist in the repository at /usr/lib/git-core/git-svn line 5305
Failed to read object #object# at /usr/lib/git-core/git-svn line 922
У меня было несколько коммитов в git, которые я пытался выдвинуть вверх по течению, и #object#
был хеш-идентификатором SHA1 одного из этих коммитов 2d061be916dc4c2d54eed7b169f1dd80ecf04bc4
в моем случае.
Я включил несколько других репозиториев git из других источников в дерево моего проекта. Хотя я явно не добавил их как подмодули git, я сделал git add <existing_repo_path>
. git замечает файл .git и добавляет existing_repo_path
в качестве специального каталога (то есть в качестве подмодуля). Эти каталоги являются костями сельди, которые заставляют git-svn
задыхаться.
исправить
find . -name .git
Это найдет любой каталог, который был добавлен как подмодуль.
./.git # Expect this one
./path/to/submodule1/.git
./path/to/other/submodule/.git
Удалите специальные каталоги из git, оставив файлы в файловой системе:
git rm --cached ./path/to/submodule1
git rm --cached ./path/to/other/submodule
Переименуйте или удалите файлы .git
из каталогов субмодуля. Переименование файлов .git
обеспечивает небольшую защиту, поскольку вы можете вернуться обратно.
mv path/to/submodule1/.git path/to/submodule1/dot.git
mv path/to/other/submodule/.git path/to/other/submodule/dot.git
Если вы явно добавили субмодули, вам может потребоваться удалить файл .gitmodules
в корне репо. Вам, вероятно, следует сначала отредактировать этот файл, чтобы проверить, есть ли в нем что-либо, что вы хотите, прежде чем удалять его.
git rm .gitmodules
Каталоги подмодулей теперь могут быть добавлены обратно в git и будут обрабатываться как обычные поддеревья (то есть больше не подмодули или каталоги особых случаев).
git add ./path/to/submodule1 ./path/to/other/submodule
Зафиксируйте эти новые файлы.
git commit -a -m "Changed submodules to ordinary directories"
Глава git-репо теперь в порядке. Но git-svn все равно захлебнется, потому что попытается создать версии из истории git. Это означает, что история мерзавцев должна быть изменена. Мой подход состоит в том, чтобы объединить все коммиты git, сделанные с момента последнего успешного git svn dcommit
, в один коммит. Таким образом, новый сингл будет содержать только текущий заголовок, а не проблемные версии «подмодулей».
Чтобы найти последний успешный коммит svn, используйте:
git svn log -n 1 --show-commit
Я получаю что-то вроде:
r2917 | 094ed52 | rue | 2015-12-04 15:39:58 +0000 (Fri, 04 Dec 2015) | 2 lines
<commit message>
Выходные данные показывают номер SVN (r2917
), за которым следует эквивалентный идентификатор git commit (094ed52
)
Затем запустите интерактивный перебаз всех версий с момента этой фиксации:
git rebase -i 094ed52
Откроется редактор с чем-то вроде этого:
pick 16b5fcc Changed submodules to ordinary directories
pick c964dea Some changes
pick 06cf8ee Added some things
pick 094ed52 Some other changes
pick
означает сохранить этот коммит, squash
означает включить эти изменения в следующий коммит. Замените все «кирки» на «сквош», кроме первой строки.
pick 16b5fcc Changed submodules to ordinary directories
squash c964dea Some changes
squash 06cf8ee Added some things
squash 094ed52 Some other changes
Сохраните и выйдите из этого файла, и вы получите новый одиночный коммит.
git svn dcommit
Теперь работает!