Прививка истории Git на ветку SVN - PullRequest
6 голосов
/ 23 сентября 2008

Ситуация
У меня есть репозиторий Git и репозиторий SVN, которые содержат одинаковый исходный код, но разные истории коммитов. В репозитории Git есть много небольших комментариев с комментариями ... в то время как в репозитории SVN есть несколько огромных коммитов с комментариями типа «Много вещей». Обе серии коммитов следуют тем же изменениям, внесенным в код, и примерно эквивалентны.

Желаемый результат
Я хотел бы перейти на использование Git-SVN без потери подробной истории текущего репозитория Git. Это должно быть сделано путем «прививки» истории из репозитория Git на ветку SVN проекта (ветвь с того момента, когда я действительно начал использовать Git).

Зачем вы это делаете? (История)
Некоторое время назад я начал играть с Git. Я начал с настройки Git-репо в проекте, который находился под контролем SVN. С небольшой настройкой у меня были и Git, и SVN, работающие параллельно над одним и тем же исходным кодом.

Для меня это был отличный способ учиться и играть с Git, но при этом у меня была сеть безопасности SVN. Это была песочница с реальными данными в принципе. У меня не было времени, чтобы по-настоящему изучить Git, но я действительно хотел с этим повозиться. На самом деле это был довольно хороший способ выучить Git для меня.

Сначала, после внесения некоторых изменений, я обязался сделать SVN, а затем Git ... затем поиграть с Git, зная, что мои изменения были в безопасности в SVN. Вскоре я стал чаще делать коммиты в Git, чем в SVN ... Теперь коммиты в SVN выпали на надоедливую рутинную работу, которую мне приходится иногда делать.

Когда я узнал разницу между git revert и svn revert, я был ОЧЕНЬ рад, что регистрировался в репозитории SVN. Я почти потерял работу за несколько недель, предполагая, что они работали одинаково.

Теперь я знаю славу Git-SVN и с удовольствием использую его в нескольких других проектах. Когда я начал, я полностью осознал, что я могу потерять репозиторий Git и мне нужно правильно настроить новый, используя git-svn init ... но, поиграв с Git некоторое время, я уверен, что есть какой-то способ взлома История Git в SVN.

Ответы [ 6 ]

2 голосов
/ 27 сентября 2008

Похоже, это НЕ возможно. Хотя текущее репозиторий git можно присоединить к текущему репозиторию svn, представляется невозможным воспроизвести историю репозитория git в репозитории svn.

Основная проблема, с которой я столкнулся, заключалась в том, чтобы заставить git-svn «зацепить» один коммит svn. Ответ на эту проблему, кажется, git-svn set-tree. Этот пост был самым полезным:
http://www.reonsoft.com/~john/blog/2008/06/05/git-first-git-svn-later/

Это насколько я могу попытаться сохранить историю в SVN:

git branch svn-reconsile HASH_OF_SECOND_COMMIT
git checkout -f svn-reconsile

git svn init file://path/to/repos/myproject/branches/git-import
git svn fetch

git svn set-tree HASH_OF_SECOND_COMMIT

git rebase git-svn

git merge master

git svn dcommit

Проблема в том, что git svn dcommit будет делать только одну ревизию в SVN ... не одну для каждого коммита в ветви master .... поэтому история сводится в SVN.

Таким образом, более простое решение - просто запустить git-svn с помощью set-tree и убедиться, что история все еще в git, даже если она не в svn. Это можно сделать с помощью следующего:

git svn init file://path/to/repos/myproject/branches/git-import
git svn fetch

git svn set-tree HASH_OF_MOST_RECENT_COMMIT

git rebase git-svn

Если кто-нибудь знает, как обойти проблему с раздавливанием (у меня есть , пробовал --no-squash), пожалуйста, прокомментируйте! В ряду умных комментариев я просто собираюсь принять сохранение истории git и привлечение к самой последней редакции svn, используя второй фрагмент кода выше.

2 голосов
/ 23 сентября 2008

Это может быть сложно сделать то, что вы хотите. Вы можете импортировать репозиторий Git в SVN через что-то вроде этого: http://code.google.com/p/support/wiki/ImportingFromGit,, но я думаю, что у вас будут конфликты. Вы можете просто воссоздать репозиторий SVN с нуля на основе вашего репозитория git.

Для дальнейшего использования, вероятно, было бы проще использовать Git в качестве клиента SVN:

git-svn clone path/to/your/svn/repo
git-commit -a -m 'my small change'
vi some files to change.txt
git-commit -a -m 'another small change' 
git-svn dcommit # sends your little changes as individual svn commits
1 голос
/ 27 сентября 2008

Вы можете оформить заказ Портной . Я использовал его для преобразования репозитория git в svn, чтобы моя работа могла быть размещена на сервере svn нашей компании. Он достаточно гибкий, поэтому может делать то, что вы хотите.

1 голос
/ 26 сентября 2008

Я думаю, что это возможно одним из двух способов ... Сейчас я обрисую их в общих чертах и ​​позже попытаюсь раскрыть их, если смогу разобраться. Если кто-нибудь может понять, как отделить деталь, или знает, почему она не работает ... прокомментируйте!

1 - на месте с помощью git-svn
(Следующие псевдокоманды НЕ РЕАЛЬНЫ - НЕ ИСПОЛЬЗУЙТЕ ИХ)

rm .svn
(configure git-svn '/myproject/branch/git-remerge')
git svn sync_versions --svn_revision=123 --hash=ad346f221455
git svn dcommit

2 - Использование отдельного репозитория git-svn в качестве прокси
(Следующие псевдокоманды НЕ РЕАЛЬНЫ - НЕ ИСПОЛЬЗУЙТЕ ИХ)

mkdir ../svn_proxy
cd ../svn_proxy
git svn init
git checkout hash_of_svn_branch_point
git pull ../messy_repo
0 голосов
/ 16 марта 2011

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

Я создал инструмент , чтобы сгенерировать отчет, показывающий, где именно сходятся деревья, независимо от хэшей коммитов, истории git, авторов, коммиттеров и т. Д. Посмотрите на этот пример отчета что мы привыкли видеть, где сходятся два несвязанных репозитория, содержащих одинаковую информацию.

Оттуда, я просто сделал много ручных прививок и filter-branch после многих поисков в Google и списках рассылки, чтобы выяснить, кем были эти люди, внесшие изменения.

0 голосов
/ 24 августа 2010

Из репозитория git svn, в который вы пытаетесь мигрировать, выполните что-то вроде следующего:

git remote add old-repo <path-to-old-repo>
git fetch old-repo
# to browse and figure out the hashes, if that helps
gitk --all &

# for each branch you want to graft
git rebase --onto <new git svn branch base> <old-repo branch base> <old-repo branch tip>

# when done
git remote rm old-repo

Для вашего сведения, вы также должны иметь возможность делать то же самое, используя git format-patch и git am, но git rebase должен быть более дружественным.

...