Перемещение существующего репозитория 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).
-
необходимые пакеты:
$ 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
hook в репо SVN со следующим содержимым, чтобы разрешить изменение необходимого свойства:#!/bin/bash exit 0;
этот скрипт должен быть исполняемым:
$ chmod +x svn/project/hooks/pre-revprop-change
-
Mercurial создал рабочую копию РЕПО SVN с именем проект-wc, поэтому переключитесь на него и отредактируйте время фиксации:
$ cd project-wc $ svn propedit svn:date --revprop -r 1
введите правильную дату и время (обратите внимание на часовые пояса!) и сохранить, вы должны получить сообщение о том "Установить новое значение для свойства svn: дата в редакции 1".
Теперь промойте и повторите для каждой другой ревизии. -
дополнительно проверьте историю фиксации, чтобы убедиться, что все выглядит нормально:
$ svn log -r 1:HEAD
затем вернитесь на один уровень вверх:
$ cd ..
-
дамп репозитория:
$ svnadmin dump svn/project > project.dump
и загрузите дамп на сервер Subversion. Готово!
этот процесс будет вероятно, также работают непосредственно между удаленными репозиториями, но мне было легче работать с локальными. Фиксация времени фиксации была большой работой, но в целом процесс был намного более простым, чем любой другой метод, который я нашел.
еще одна последовательность, которая работала (с некоторыми комментариями по каждому шагу):
- установить
git-svn
иsubversion
инструменты:
sudo apt-get install git-svn subversion
- внутри
PROJECT_FOLDER
cd PROJECT_FOLDER
- создать путь к проекту на сервере 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
в конце пути обязательное
- инициализации
git-svn
контекст плагина внутри.git
папку
git svn init -s protocol:///path/to/repo/PROJECT_FOLDER
это то место, где trunk
в конце пути лишних
- принести пустой
Subversion
хранилище информация
git svn fetch
этот шаг помогает синхронизировать Subversion
сервер git-svn
плагин. это момент, когда git-svn
плагин remotes/origin
путь и связывает его с trunk
папку на стороне сервера
- rebase старый
git
коммиты произошли доgit-svn
плагин стал участвовать в процессе (этот шаг дополнительно)
git rebase origin/trunk
- добавить новые / измененные файлы для фиксации (этот шаг является обычным для
git
и дополнительно)
git add .
- зафиксировать недавно добавленные файлы в локальный
git
хранилище (этот шаг дополнительно и применяется только в том случае, если был использован Шаг 7)
git commit -m "Importing git repo"
- нажатие на все изменения истории проекта в
Subversion
сервер
git svn dcommit
Что делать, если вы не хотите фиксировать каждую фиксацию, которую вы делаете в Git, в репозиторий SVN? Что делать, если вы просто хотите выборочно отправлять коммиты вверх по трубе? Что ж. У меня есть решение получше.
Я храню одно локальное git-РЕПО, где все, что я когда-либо делаю, это выборка и слияние из SVN. Таким образом, я могу убедиться, что включаю все те же изменения, что и SVN, но я держу свою историю фиксации отдельно от SVN полностью.
затем я сохраняю отдельную локальную рабочую копию SVN, которая находится в отдельная папка. Это тот, из которого я делаю коммиты обратно в SVN, и я просто использую утилиту командной строки SVN для этого.
когда я готов зафиксировать состояние моего локального репозитория git в SVN, я просто копирую весь беспорядок файлов в локальную рабочую копию SVN и фиксирую ее оттуда, используя SVN, а не git.
таким образом, мне никогда не нужно делать перестановку, потому что перестановка похожа на халяву.