Перемещение существующего репозитория git в SVN

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

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

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

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

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

17 ответов


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

импорт 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" и возобновление перебазироваться. В конце концов, вы закончите; затем синхронизируйте обратно в 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

и удалить раздел .

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


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

клонировать 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

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

ура !


использование 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

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

получить начальный материал из svn:

git svn fetch

теперь найдите хэш вашей корневой фиксации (должен показывать одну фиксацию):

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

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

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

создайте новый каталог в репозитории subversion для вашего проекта.

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

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

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

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


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) извлеките информацию из главной ветви из РЕПО old-git в текущее РЕПО:

git fetch old-git master

5) проверка главной ветви старого-git удаленный в новую ветку под названием old в текущем РЕПО:

git checkout -b old old-git/master

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

git rebase master

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

git checkout master

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

8) нажмите свою работу в svn:

git svn dcommit

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


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



Мне нужно было зафиксировать мое существующее 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 (мой источник использует аутентификацию закрытого/открытого ключа), я должен был использовать свойство --username.


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

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


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

подробнее здесь https://github.com/blog/1178-collaborating-on-github-with-subversion


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

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

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


вы можете сделать новое РЕПО svn. Экспортируйте свой проект git (fleshing out .git files). Добавьте его в репо svn (инициализация РЕПО с тем, что у вас было до сих пор в git). Затем используйте инструкции для импорта репозиториев svn в свежий проект git.

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


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

git svn dcommit

$ Git и внесение изменений через dcommit СВН

использование неинициализированного значения $u в замене (s///) на /usr/lib/perl5/vendor_perl/5.22/Git/SVN.линия 101.

использование неинициализированного значения $u в конкатенации (.) или строка в /usr/lib/perl5/vendor_perl/5.22/Git / SVN.линия 101. refs / пульты дистанционного управления / 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";
}

это исправило мою проблему


в моем случае, мне пришлось инициировать чистый проект из 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

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

  1. необходимые пакеты:

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

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

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

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

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

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

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

    #!/bin/bash
    exit 0;
    

    этот скрипт должен быть исполняемым:

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

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

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

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

    $ svn log -r 1:HEAD
    

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

    $ cd ..
    
  11. дамп репозитория:

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

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


еще одна последовательность, которая работала (с некоторыми комментариями по каждому шагу):

  1. установить git-svn и subversion инструменты:

sudo apt-get install git-svn subversion

  1. внутри PROJECT_FOLDER

cd PROJECT_FOLDER

  1. создать путь к проекту на сервере Subversion (к сожалению тока git-svn плагин имеет дефект по сравнению с TortoiseSVN) он не может хранить исходный код непосредственно в PROJECT_FOLDER вместо этого по умолчанию он будет загружать весь код в PROJECT_FOLDER/trunk

svn mkdir --parents protocol:///path/to/repo/PROJECT_FOLDER/trunk -m "creating git repo placeholder" это то место, где trunk в конце пути обязательное

  1. инициализации git-svn контекст плагина внутри .git папку

git svn init -s protocol:///path/to/repo/PROJECT_FOLDER это то место, где trunk в конце пути лишних

  1. принести пустой Subversion хранилище информация

git svn fetch этот шаг помогает синхронизировать Subversion сервер git-svn плагин. это момент, когда git-svn плагин remotes/origin путь и связывает его с trunk папку на стороне сервера

  1. rebase старый git коммиты произошли до git-svn плагин стал участвовать в процессе (этот шаг дополнительно)

git rebase origin/trunk

  1. добавить новые / измененные файлы для фиксации (этот шаг является обычным для git и дополнительно)

git add .

  1. зафиксировать недавно добавленные файлы в локальный git хранилище (этот шаг дополнительно и применяется только в том случае, если был использован Шаг 7)

git commit -m "Importing git repo"

  1. нажатие на все изменения истории проекта в Subversion сервер

git svn dcommit


Что делать, если вы не хотите фиксировать каждую фиксацию, которую вы делаете в Git, в репозиторий SVN? Что делать, если вы просто хотите выборочно отправлять коммиты вверх по трубе? Что ж. У меня есть решение получше.

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

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

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

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