Перенос существующего Git-репозитория в SVN - PullRequest
381 голосов
/ 19 марта 2009

Я делал всю свою работу в Git и отправлял на GitHub. Я был очень доволен как программным обеспечением, так и сайтом, и я не хочу менять свои рабочие методы на этом этапе.

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

Затем я хочу просто запустить пару команд для отправки коммитов в этот SVN-репозиторий, когда я выберу. Я хочу продолжать использовать Git и просто иметь зеркало репозитория SVN, что есть в Git.

Я буду единственным человеком, который когда-либо принимал участие в SVN, если это что-то изменит.

Ответы [ 17 ]

399 голосов
/ 21 апреля 2009

Мне это тоже нужно было, и с помощью ответа Бомбе + немного повозиться, я заставил его работать. Вот рецепт:

Импорт Git -> Subversion

1. cd /path/to/git/localrepo
2. svn mkdir --parents protocol:///path/to/repo/PROJECT/trunk -m "Importing git repo"
3. git svn init protocol:///path/to/repo/PROJECT -s
4. git svn fetch
5. git rebase origin/trunk
5.1.  git status
5.2.  git add (conflicted-files)
5.3.  git rebase --continue
5.4.  (repeat 5.1.)
6. git svn dcommit

После # 3 вы получите загадочное сообщение, подобное этому:

Использование более высокого уровня URL: protocol:///path/to/repo/PROJECT => protocol:///path/to/repo

Просто игнорируйте это.

Когда вы запускаете # 5, вы можете получать конфликты. Решите их, добавив файлы с состоянием «unmerged» и возобновив их перебазирование. В конце концов, вы закончите; затем выполните синхронизацию с репозиторием SVN, используя dcommit. Вот и все.

Синхронизация репозиториев

Теперь вы можете синхронизироваться из SVN в Git, используя следующие команды:

git svn fetch
git rebase trunk

А для синхронизации из Git в SVN используйте:

git svn dcommit

Конечная нота

Возможно, вы захотите попробовать это на локальной копии, прежде чем применять к живому репозиторию. Вы можете сделать копию своего репозитория Git во временное место; просто используйте cp -r, так как все данные находятся в самом хранилище. Затем вы можете настроить файловый репозиторий тестирования, используя:

svnadmin create /home/name/tmp/test-repo

И проверьте рабочую копию, используя:

svn co file:///home/name/tmp/test-repo svn-working-copy

Это позволит вам поиграться с вещами, прежде чем вносить какие-либо длительные изменения.

Приложение: Если вы запутались git svn init

Если вы случайно запустили git svn init с неправильным URL-адресом, и вы не были достаточно умны, чтобы сделать резервную копию своей работы (не спрашивайте ...), вы не можете просто запустить эту же команду снова. Однако вы можете отменить изменения, введя:

rm -rf .git/svn
edit .git/config

И удалить раздел [svn-remote "svn"] раздел.

Затем вы можете запустить git svn init заново.

29 голосов
/ 19 января 2012

Вот как мы это сделали:

Клонируйте свой репозиторий Git где-нибудь на вашем компьютере.

Откройте .git / config и добавьте следующее (из Поддержание SVN-зеркала только для чтения репозитория Git ):

[svn-remote "svn"]
    url = https://your.svn.repo
    fetch = :refs/remotes/git-svn

Теперь из окна консоли введите:

git svn fetch svn
git checkout -b svn git-svn
git merge master

Теперь, если по какой-либо причине здесь произойдет сбой, введите следующие три строки:

git checkout --theirs .
git add .
git commit -m "some message"

И, наконец, вы можете зафиксировать в SVN:

git svn dcommit

Примечание. После этого я всегда удаляю эту папку.

27 голосов
/ 05 мая 2009

Использование git rebase напрямую потеряет первый коммит. Git относится к этому по-другому и не может перебазировать его.

Существует процедура, которая сохранит полную историю: http://kerneltrap.org/mailarchive/git/2008/10/26/3815034

Я расшифрую решение здесь, но кредиты для Бьёрна.

Инициализировать git-svn:

git svn init -s --prefix=svn/ https://svn/svn/SANDBOX/warren/test2

--prefix дает вам ветки удаленного отслеживания, такие как "svn / trunk", что хорошо, потому что вы не получаете двусмысленных имен, если вы называете свою локальную ветку просто "trunk". И -s является ярлыком для стандартного макета ствола / тегов / ветвей.

Получить исходный материал из SVN:

git svn fetch

Теперь посмотрите хэш вашего корневого коммита (должен отображаться один коммит):

git rev-list --parents master | grep '^.\{40\}$'

Затем получите хэш пустого коммита транка:

git rev-parse svn/trunk

Создание трансплантата:

echo <root-commit-hash> <svn-trunk-commit-hash> >> .git/info/grafts

Теперь "gitk" должен показывать svn/trunk как первый коммит, на котором основана ваша основная ветвь.

Сделать трансплантат постоянным:

git filter-branch -- ^svn/trunk --all

Бросай трансплантат:

rm .git/info/grafts

Гитк должен по-прежнему показывать svn/trunk в происхождении мастера.

Линеаризуйте свою историю поверх ствола:

git svn rebase

А теперь "git svn dcommit -n" должен сообщить вам, что он собирается фиксировать транк.

git svn dcommit
8 голосов
/ 19 марта 2009

Создайте новый каталог в хранилище Subversion для вашего проекта.

# svn mkdir --parents svn://ip/path/project/trunk

Перейдите в управляемый Git проект и инициализируйте git-svn.

# git svn init svn://ip/path/project -s
# git svn fetch

Это создаст один коммит, потому что ваш каталог проекта SVN по-прежнему пуст. Теперь перебазируйте все на этом коммите, git svn dcommit, и все готово. Это серьезно испортит ваши даты коммитов.

7 голосов
/ 03 марта 2016

Git -> SVN с полной историей коммитов

У меня был проект Git, и мне пришлось перенести его в SVN. Вот как я это сделал, сохранив всю историю коммитов. Единственное, что теряется, это исходное время коммита, так как libSVN установит местное время, когда мы сделаем git svn dcommit.

Howto:

  1. Есть SVN-репозиторий, куда мы хотим импортировать наш материал и клонировать его с помощью git-svn:

    git svn clone https://path.to/svn/repository repo.git-svn`
    
  2. Идите туда:

    cd repo.git-svn
    
  3. Добавьте удаленное хранилище Git (в этом примере я использую C: /Projects/repo.git). Вы хотите нажать на SVN и дать ему имя old-git:

    git remote add old-git file:///C/Projects/repo.git/
    
  4. Извлечение информации из главной ветки из старого Git-репозитория в текущий репозиторий:

    git fetch old-git master
    
  5. Извлеките основную ветку пульта old-git в новую ветвь с именем old в текущем хранилище:

    git checkout -b old old-git/master`
    
  6. Перебазировать, чтобы положить ГОЛОВУ поверх старого git / master. Это сохранит все ваши коммиты. В основном это сводится к тому, чтобы взять всю вашу работу, выполненную в Git, и поставить ее поверх работы, к которой вы обращаетесь из SVN.

    git rebase master
    
  7. Теперь вернитесь к своей основной ветке:

    git checkout master
    

    И вы можете видеть, что у вас есть чистая история коммитов. Это то, что вы хотите подтолкнуть к SVN.

  8. Отправьте свою работу в SVN:

    git svn dcommit
    

Вот и все. Это очень чисто, без взлома, и все отлично работает из коробки. Наслаждайтесь.

4 голосов
/ 13 мая 2012

Я бы предложил очень короткую инструкцию из 4 команд, используя SubGit . См. сообщение для деталей.

3 голосов
/ 09 мая 2014

Мне нужно было зафиксировать свой существующий Git-репозиторий в пустом SVN-репозитории.

Вот как мне удалось это сделать:

$ git checkout master
$ git branch svn
$ git svn init -s --prefix=svn/ --username <user> https://path.to.repo.com/svn/project/
$ git checkout svn
$ git svn fetch
$ git reset --hard remotes/svn/trunk
$ git merge master
$ git svn dcommit

Работало без проблем. Надеюсь, это кому-нибудь поможет.

Поскольку мне приходилось авторизоваться под именем пользователя, отличным от SVN-репозитория (мой origin использует аутентификацию с использованием открытого / открытого ключа), мне пришлось использовать свойство --username.

2 голосов
/ 19 марта 2009

Если вы хотите продолжать работать с Git в качестве основного репозитория и вам просто нужно время от времени «экспортировать» ревизии в SVN, вы можете использовать Tailor для синхронизации репозитория SVN. Он может копировать ревизии между различными системами контроля версий и обновлять SVN с изменениями, внесенными в Git.

Я не пробовал преобразование Git в SVN, но для примера SVN -> SVN см. этот ответ .

1 голос
/ 20 февраля 2013

Если вам не нужно использовать какой-либо конкретный SVN, и вы используете GitHub, вы можете использовать их разъем SVN.

Больше информации здесь: Сотрудничество на GitHub с Subversion

1 голос
/ 28 марта 2013

Я хотел бы поделиться замечательным инструментом, используемым в сообществе WordPress, под названием Scatter

Плагины Git для WordPress и немного рассудка

Это позволяет пользователям автоматически отправлять свои репозитории Git на wordpress.org SVN. Теоретически этот код может быть применен к любому репозиторию SVN.

...