Нажатие существующего репозитория git на SVN

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

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

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

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

Любые инструкции о том, как это сделать, будут очень благодарны!

Ответы

Ответ 1

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

Импорт git → svn

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" и возобновив rebase. В конце концов, вы сделаете это; Затем выполните синхронизацию с svn-repo, используя dcommit. Это все.

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

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

git svn fetch
git rebase trunk

И для синхронизации из git → svn используйте:

git svn dcommit

Заключительная записка

Возможно, вы захотите попробовать это в локальной копии, прежде чем подать заявку на реальный репо. Вы можете сделать копию своего git -repo во временное место, просто используя 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 заново.

Ответ 2

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

Скопируйте репозиторий git на ваш компьютер. Откройте .git/config и добавьте следующее (из http://www.kerrybuckley.org/2009/10/06/maintaining-a-read-only-svn-mirror-of-a-git-repository/):

[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

Теперь, если он по какой-то причине ломается, введите эти 3 строки:

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

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

git svn dcommit

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

приветствия!

Ответ 3

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

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

Я буду расшифровать решение здесь, но кредиты для Björn.

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

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

. --prefix дает вам удаленные ветки отслеживания, такие как "svn/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

gitk должен показать svn/trunk в родословной мастера

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

git svn rebase

И теперь "git svn dcommit -n" должен сказать вам, что он собирается совершить к стволу.

git svn dcommit

Ответ 4

Создайте новый каталог в репозитории 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, и вы должны сделать это. Тем не менее, это серьезно испортит ваши даты фиксации.

Ответ 5

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 (в этом примере Im с помощью 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) проверьте мастер-ветку старого git удаленного в новую ветку, называемую старой в текущем репо:

git checkout -b old old-git/master

6) Положите HEAD поверх старого git/master. Это будет поддерживать все ваши коммиты. Это в основном заключается в том, чтобы выполнить всю вашу работу в git и поместить ее поверх работы, к которой вы обращаетесь, из svn.

git rebase master

7) Теперь вернитесь к своей основной ветке:

git checkout master

и вы увидите, что у вас есть чистая история фиксации. Это то, что вы хотите нажать на svn.

8) Направьте свою работу на svn:

git svn dcommit

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

Ответ 6

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

Ответ 8

Мне нужно было передать существующий репозиторий 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 repo (мое начало использует private/public key auth), мне пришлось использовать свойство -username.

Ответ 9

Если вы хотите продолжать работать с git в качестве основного репозитория и просто нужно время от времени "экспортировать" ревизии в svn, вы можете использовать tailor, чтобы сохранить репозиторий svn в синхронизации. Он может копировать ревизии между различными системами управления версиями и обновлять svn с изменениями, внесенными вами в git.

Я не пробовал преобразование git → svn, но для примера svn → svn см. этот ответ.

Ответ 11

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

http://evansolomon.me/notes/git-wordpress-plugins-and-a-bit-of-sanity-scatter/

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

Ответ 12

Вы можете создать новый репозиторий svn. Экспортируйте проект git (создавая файлы .git). Добавьте его в svn repo (инициализируя репо с тем, что у вас было до сих пор в git). Затем используйте инструкции по импорту svn-репозиториев в новый проект git.

Но это потеряет вашу предыдущую историю git.

Ответ 13

В моем случае мне пришлось инициировать чистый проект из SVN

$ Project> git svn init protocol://path/to/repo -s
$ Project> git svn fetch

добавить все источники проекта...

$ Project> git add .
$ Project> git commit -m "Importing project sources"
$ Project> git svn dcommit

Ответ 14

Я знаю, что это очень старый вопрос, но мне недавно пришлось перенести несколько репозиций Git на SVN, и после того, как я попытался найти все решения, что, наконец, сработало для меня, было Mercurial (да, используя третий VCS). Используя это руководство, я придумал следующий процесс (в Linux, но основная идея должна работать и на Windows).

  • Необходимые пакеты:

    $ sudo apt-get install git subversion mercurial python-subversion
    
  • Mercurial необходимо настроить, добавив следующее к ~/.hgrc:

    [extensions]
    hgext.convert=
    
  • Создайте несколько временных рабочих каталогов (у меня было несколько репозиториев для миграции, поэтому я создал каталоги для версий SVN и Git, чтобы они не разделялись):

    $ mkdir svn
    $ mkdir git
    
  • Создайте пустой локальный репозиторий SVN:

    $ svnadmin create svn/project
    
  • Клонировать существующий репозиторий Git:

    $ git clone server/path/project.git git/project
    
  • Пусть Mercurial сделает свое дело:

    $ hg convert --dest-type svn git/project svn/project
    
  • Теперь SVN-репо должно содержать полную историю фиксации, но не с исходными временными метками. Если это не проблема, пропустите следующую часть до шага 11.

  • С небольшой работой можно изменить дату и время каждой фиксации. Поскольку мои репозиции довольно малы, для меня было возможно сделать это вручную. Во-первых, создайте крюк pre-revprop-change в репо SVN со следующим содержимым, чтобы разрешить изменение необходимого свойства:

    #!/bin/bash
    exit 0;
    

    Этот script должен быть выполнен:

    $ chmod +x svn/project/hooks/pre-revprop-change
    
  • Mercurial создал рабочую копию репозитория SVN с именем project-wc, поэтому переключитесь на него и отредактируйте время фиксации:

    $ cd project-wc
    $ svn propedit svn:date --revprop -r 1
    

    Введите правильную дату и время (обратите внимание на часовые пояса!) и сохраните, вы должны получить сообщение "Установить новое значение для свойства svn: date on revision 1".
    Теперь полоскание и повторение для каждой другой ревизии.

  • Дополнительно проверяйте историю фиксации, чтобы убедиться, что все выглядит нормально:

    $ svn log -r 1:HEAD
    

    Затем вернитесь на один уровень:

    $ cd ..
    
  • Дамп репозитория:

    $ svnadmin dump svn/project > project.dump
    
  • Загрузите дамп на сервере Subversion. Готово!

Этот процесс, вероятно, также будет работать напрямую между удаленными репозиториями, но мне было легче работать с локальными. Фиксация времени фиксации была большой работой, но в целом процесс был гораздо более простым, чем любой другой метод, который я нашел.

Ответ 15

Просто хочу поделиться своим опытом с принятым ответом. Я сделал все шаги, и все было хорошо, прежде чем я запустил последний шаг.

git svn dcommit

$git svn dcommit

Использование неинициализированного значения $u в подстановке (s///) в /usr/lib/perl 5/vendor_perl/5.22/ Git/SVN.pm строке 101.

Использование неинициализированного значения $u в конкатенации (.) или строки в /usr/lib/perl 5/vendor_perl/5.22/ Git/SVN.pm строке 101. refs/remotes/origin/HEAD: 'https://192.168.2.101/svn/PROJECT_NAME' не найден в ''

Я нашел эту нить https://github.com/nirvdrum/svn2git/issues/50

и, наконец, решение, которое я применил в следующем файле в строке 101 /usr/lib/perl5/vendor_perl/5.22/Git/SVN.pm

Я заменил

$u =~ s!^\Q$url\E(/|$)!! or die

Я заменяю

if(!$u) {
    $u = $pathname;
}else {
    $u =~ s!^\Q$url\E(/|$)!! or die
    "$refname: '$url' not found in '$u'\n";
}

Это зафиксировало мою проблему

Ответ 16

Что делать, если вы не хотите совершать КОЛИЧЕСТВО, которое вы делаете в Git, в репозиторий SVN? Что делать, если вы просто хотите, чтобы выборочная передача фиксировала трубку? Что ж. У меня есть лучшее решение.

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

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

Когда я готов передать свое локальное состояние репозиции git в SVN, я просто скопирую весь беспорядок файлов в локальную рабочую копию SVN и передаю его оттуда с помощью SVN, а не git.

Таким образом, мне не нужно делать никаких перезарядов, потому что перезагрузка похожа на freebasing.