Ответ 3
Этот метод по существу совпадает с принятым ответом от @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, сделанные с последнего успешного git svn dcommit
, в одно коммит. Таким образом, новый сингл будет содержать только текущую головку, а не неприятные версии "подмодуля".
Чтобы найти последнее успешное использование svn commit:
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 id (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
означает, что это commit, squash
означает включение этих изменений в следующую фиксацию. Замените все "pick" на "squash", кроме первой строки.
pick 16b5fcc Changed submodules to ordinary directories
squash c964dea Some changes
squash 06cf8ee Added some things
squash 094ed52 Some other changes
Сохраните и выйдите из этого файла, и вы должны получить новый сингл commit.
git svn dcommit
Теперь работает!