Як перенести сховище SVN з історією до нового сховища Git?


1509

Я читав посібник з Git, FAQ, курс збою Git - SVN і т. Д., І всі вони пояснюють це та інше, але ніде не можна знайти просту інструкцію типу:

SVN сховище у: svn://myserver/path/to/svn/repos

Репозиторій Git у: git://myserver/path/to/git/repos

git-do-the-magic-svn-import-with-history \
svn://myserver/path/to/svn/repos \
git://myserver/path/to/git/repos

Я не очікую, що це буде так просто, і я не очікую, що це буде одна команда. Але я сподіваюсь, що не намагатись пояснити що-небудь, а лише сказати, які кроки потрібно зробити з цього прикладу.


6
Це стає простіше, я просто завершив це сам і задокументував свої висновки за допомогою SO jmoses.co/2014/03/21/moving-from-svn-to-git.html
Джон Мойсей

Використовуйте відповідь Кейсі нижче, але перш ніж запустити команду "svn clone ...", див. Як додати додатковий рядок "Visual SVN Server" у файл user.txt ... тут: stackoverflow.com/questions/8971208/ …
MacGyver

1
Крім того, якщо у вашому профілі GitHub встановлено параметр "зробити приватну електронну пошту", використовуйте це як свою адресу електронної пошти в users.txt, щоб відповідати. Yourgituser@users.noreply.github.com, щоб ваша справжня адреса електронної пошти не відображалася на коміти
MacGyver

Відповіді:


529

Магія:

$ git svn clone http://svn/repo/here/trunk

Git і SVN діють дуже по-різному. Вам потрібно вивчити Git, і якщо ви хочете відслідковувати зміни від SVN вище за течією, вам потрібно навчитися git-svn. На git-svn головній сторінці є хороший розділ прикладів :

$ git svn --help

139
Відповідь від @Casey набагато краще відповідає на оригінальне запитання.
Дуг Вілсон

3
Чи збереже це гілки і все? чи просто клонувати багажник?
Eildosa

7
@Eildosa: Це просто клонує багажник. Дивіться відповідь Кейсі за альтернативу.
sleske

3
@DougWilson, але я не бачу тут жодної відповіді Кейсі. Чи наведена нижче відповідь із 13 авторів, що починається із "Створити файл користувача"?
Андрій Регентов

67
Для всіх, кому цікаво, що це "відповідь Кейсі", на яку посилається багато коментарів, саме цей (Кейсі змінив прізвисько на cmcginty).
Стефан Монов

1559

Створіть файл користувача (тобто users.txt) для відображення SVN-користувачів у Git:

user1 = First Last Name <email@address.com>
user2 = First Last Name <email@address.com>
...

Ви можете скористатися цим одноклассником для створення шаблону з наявного сховища SVN:

svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt

SVN зупиняється, якщо знайде відсутнього користувача SVN, який не знаходиться у файлі. Але після цього ви можете оновити файл і забрати там, де ви зупинилися.

Тепер витягніть дані SVN із сховища:

git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp

Ця команда створить нове сховище Git dest_dir-tmpі почне витягувати сховище SVN. Зауважте, що прапор "--stdlayout" означає, що у вас є загальний макет "trunk /, гілки /, теги /" SVN. Якщо ваш макет відрізняється, ознайомляться з --tags, --branches, --trunkваріанти (в цілому git svn help).

Всі загальні протоколи допускаються: svn://, http://, https://. URL-адреса має бути націленою на базовий сховище, на зразок http://svn.mycompany.com/myrepo/repository . Рядок URL-адреси не повинен містити /trunk, /tagабо /branches.

Зауважте, що після виконання цієї команди дуже часто схоже, що операція "висить / заморожена", і цілком нормально, що вона може затримуватися надовго після ініціалізації нового сховища. Згодом ви побачите повідомлення журналу, що вказує на те, що воно мігрує.

Також зауважте, що якщо ви не виставите --no-metadataпрапор, Git додасть інформацію про відповідну редакцію SVN до повідомлення про виконання (тобто git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>)

Якщо ім’я користувача не знайдено, оновіть users.txtфайл, тоді:

cd dest_dir-tmp
git svn fetch

Вам, можливо, доведеться повторити цю останню команду кілька разів, якщо у вас є великий проект, поки не будуть отримані всі комісії Subversion:

git svn fetch

Після завершення Git перевірить SVN trunkв нове відділення. Будь-які інші гілки налаштовуються як віддалені. Ви можете переглянути інші відділення SVN за допомогою:

git branch -r

Якщо ви хочете зберегти інші віддалені гілки у вашому сховищі, ви хочете створити локальну гілку для кожного з них вручну. (Пропустити ствол / майстер.) Якщо цього не зробити, гілки не будуть клоновані на останньому кроці.

git checkout -b local_branch remote_branch
# It's OK if local_branch and remote_branch are the same name

Теги імпортуються як філії. Вам потрібно створити локальну гілку, зробити тег та видалити гілку, щоб вони були тегами у Git. Щоб зробити це з тегом "v1":

git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1

Клоніруйте свій сховище GIT-SVN в чистий сховище Git:

git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir

Локальні гілки, які ви створили раніше з віддалених гілок, будуть скопійовані лише як віддалені гілки до нового клонованого сховища. (Пропустити ствол / майстер.) Для кожної гілки, яку ви хочете зберегти:

git checkout -b local_branch origin/remote_branch

Нарешті, видаліть пульт із чистого сховища Git, який вказує на видалене тимчасове сховище:

git remote rm origin

36
Цей блог від Елке є чудовим перехресним посиланням на відповідь вище. blokspeed.net/blog/2010/09/converting-from-subversion-to-git
kgriffs

4
Це на 99% дивовижно, виконуючи ці кроки, у мене все було в порядку, крім гілок: після останнього кроку вони були лише віддалені (і як такі зникли, коли я виконав команду: git remote rm origin)
Брудний Генрі

4
У GitHub є дуже зручний крок за кроком: github.com/nirvdrum/svn2git#readme
Dan

8
Для тих, хто знаходиться під Windows, я створив сценарій PowerShell на основі цього методу: gist.github.com/Gimly/90df046dc38181bb18de
Gimly

5
Попередження про великі репости з великою кількістю історії, це повільно і туго . Я відмовився від спроби перенести всі старі гілки і просто мігрував стовбур.
Джесс

195

Чисто перенесіть ваше сховище Subversion у сховище Git . Спочатку потрібно створити файл, який відображає імена авторів фіксації Subversion до комітетів Git, скажіть ~/authors.txt:

jmaddox = Jon Maddox <jon@gmail.com>
bigpappa = Brian Biggs <bigpappa@gmail.com>

Потім ви можете завантажити дані Subversion у сховище Git:

mkdir repo && cd repo
git svn init http://subversion/repo --no-metadata
git config svn.authorsfile ~/authors.txt
git svn fetch

Якщо ви перебуваєте на Mac, ви можете отримати доступ git-svnвід MacPorts, встановивши git-core +svn.

Якщо ваше сховище субверсії знаходиться на тій же машині, що і ваше бажане сховище git, ви можете використовувати цей синтаксис для кроку init, інакше все те саме:

git svn init file:///home/user/repoName --no-metadata

1
Як я прокоментував інший відповідь, я повинен був видалити пробілу навколо =в users.txtтому , що імпорт був переривання , і я отримую порожній репозиторій.
Себастьян Гриньолі

8
Ах! Просте і ефективне пояснення. У моєму випадку file:///відмовились працювати, просто я використовував, svnserve.exe --daemonа потім використовував svn://localhost/home/user/repoзамість цього.
Даніель Рейс

На моєму Mac, що працює на вершині Mountain Lion, git svn не працюватиме, поки я не зайшов у Xcode та встановив Інструменти командного рядка, знайдені на вкладці "Завантаження" на панелі "Налаштування". Крім того, я міг би встановити лише інструменти командного рядка для OS X Mountain Lion, знайдені на сайті розробника Apple.
Дрю

3
У моєму випадку мені довелося перетворити файл authors.txtу utf-8 without BOM.
Сільван

Це чудово працювало для мене! Після того, як у мене було місцеве сховище, я використав пост cmcginty, починаючи з "Клоніруйте ваше сховище GIT-SVN в чисте сховище Git:" Я думаю, що головна причина, що мені сподобалась відповідь @zoul, - це використання git svn init, git svn configто, нарешті, git svn fetchяк було легше щоб зробити це таким чином, мені довелося кілька разів вийти, щоб це правильно. Однорядковий cmcginty git svn clone, який робить усі три, був для мене занадто заплутаним.
Майк

70

Я використав сценарій svn2git і працює як шарм.


4
З: Чи це виправлення пробілів у іменах тегів та гілок (дозволено у svn та не дозволено у git)?
spazm

2
Цей посібник для його використання корисний: troyhunt.com/2014/08/migrating-from-subversion-to-git-with.html
Morten Holmgaard

Мені це не вдалося зіткнутися з проблемою: groups.google.com/forum/#!topic/msysgit/7MQVwRO-2N4 - див. Також: github.com/nirvdrum/svn2git/isissue/50 Рішення було тут: stackoverflow.com/questions / 3009738 /…
HDave

Краще пояснювати відповіді, інакше ми виробляємо сценарії для дітей.
Джош Хабдас

А як бути, якщо всі ваші гілки в корені SVN і у вас немає стовбура чи тегів?
Кал

58

Я пропоную отримати комфорт із Git перед тим, як намагатися постійно використовувати git-svn, тобто зберігати SVN як централізовану репо і використовувати Git локально.

Однак для простої міграції з усією історією, ось кілька простих кроків:

Ініціалізуйте місцеве репо:

mkdir project
cd project
git svn init http://svn.url

Позначте, як далеко назад ви хочете імпортувати зміни:

git svn fetch -r42

(або просто "git svn fetch" для всіх оборотів)

Насправді все за цей час:

git svn rebase

Ви можете перевірити результат імпорту за допомогою Gitk. Я не впевнений, чи працює це в Windows, він працює на OSX та Linux:

gitk

Коли ваш репортаж SVN буде клонований локально, можливо, ви захочете переслати його до централізованого репортажу Git для легшої співпраці.

Спочатку створіть ваше порожнє віддалене репо (можливо, на GitHub ?):

git remote add origin git@github.com:user/project-name.git

Потім, необов'язково, синхронізуйте свою основну гілку, щоб операція витягання автоматично злила віддалений майстер із вашим локальним майстром, коли обидва містять нові речі:

git config branch.master.remote origin
git config branch.master.merge refs/heads/master

Після цього вам може бути цікаво спробувати мій власний git_remote_branchінструмент, який допомагає працювати з віддаленими гілками:

Перший пояснювальний пост: " Git віддалені гілки "

Підтримка останньої версії: " Час git співпрацює з git_remote_branch "


Надзвичайно корисно, це спрацювало чудово. Я хотів би додати, що є один останній крок, якщо ви синхронізуєтесь із віддаленим сховищем. Після кроків налаштування git, мені потрібно булоgit push origin master
mag382

31

Існує нове рішення для плавної міграції з Subversion на Git (або для використання обох одночасно): SubGit .

Я над цим проектом працюю сам. Ми використовуємо SubGit у наших сховищах - деякі мої товариші по команді використовують Git, а деякі Subversion, і поки це працює дуже добре.

Щоб перейти з Subversion на Git за допомогою SubGit, потрібно запустити:

$ subgit install svn_repos
...
TRANSLATION SUCCESSFUL 

Після цього ви отримаєте сховище Git у svn_repos / .git і зможете його клонувати або просто продовжувати використовувати Subversion і це нове сховище Git разом: SubGit забезпечить, щоб обидва завжди зберігалися в синхронізації.

Якщо ваш сховище Subversion містить декілька проектів, то в каталозі svn_repos / git буде створено кілька сховищ Git. Щоб налаштувати переклад перед запуском, виконайте такі дії:

$ subgit configure svn_repos
$ edit svn_repos/conf/subgit.conf (change mapping, add authors mapping, etc)
$ subgit install svn_repos

За допомогою SubGit ви можете перейти на чистий Git (не git-svn) і почати його використовувати, зберігаючи Subversion стільки, скільки вам потрібно (наприклад, для вже налаштованих інструментів збирання).

Сподіваюся, це допомагає!


4
Зауважте, що одноразовий імпорт (за допомогою subgit importкоманди) навіть не вимагає ліцензії. Точний переклад svn:ignoreвластивості у .gitignoreфайли також включений.
krlmlr

1
SubGit не розпізнає ні мого приватного ключа, ні будь-яких прапорів, які я встановив у командному рядку. Документація дуже погана. Це не є життєздатною альтернативою для git svn.
pfnuesel

1
помилка: 'svn_repos' не є дійсно налаштованим розташуванням; Файл конфігурації SubGit відсутній.
Джон Девіс

19

Дивіться офіційну сторінку git-svn . Зокрема, перегляньте "Основні приклади":

Відстеження та створення цілого проекту, керованого Subversion (у комплекті зі стовбуром, тегами та гілками):

# Clone a repo (like git clone):
    git svn clone http://svn.foo.org/project -T trunk -b branches -t tags

Ваша команда клонування спрацювала, ті, хто вище, не дали мені нічого, окрім порожніх репотів. Єдиною відмінністю, здається, є явний '-T магістраль'.
користувач1984717


14

SubGit (проти синього екрану смерті)

subgit import --svn-url url://svn.serv/Bla/Bla  directory/path/Local.git.Repo

Це все.

+ Для оновлення з SVN, сховища Git, створеного першою командою.

subgit import  directory/path/Local.git.Repo

Я використовував спосіб миттєвої міграції до Git для величезного сховища.
Звичайно, вам потрібна певна підготовка.
Але ви можете зовсім не зупинити процес розробки.

Ось мій шлях.

Моє рішення виглядає так:

  • Перенесіть SVN у сховище Git
  • Оновіть сховище Git безпосередньо перед переходом команди на .

Міграція потребує багато часу для великого сховища SVN.
Але оновлення завершеної міграції за кілька секунд.

Звичайно, я використовую SubGit , мамо . git-svn робить мене Синім екраном смерті . Просто постійно. І git-svn нудить мені з фатальною помилкою " занадто довге " ім'я файлу Git .

КРОКИ

1. Завантажте SubGit

2. Підготуйте команди міграції та оновлення.

Скажімо, ми робимо це для Windows (банально портувати до Linux).
У каталозі бін встановлення SubGit (subgit-2.XX \ bin) створіть два .bat файли.

Вміст файлу / команди для міграції:

start    subgit import --svn-url url://svn.serv/Bla/Bla  directory/path/Local.git.Repo

Команда "Пуск" тут необов'язкова (Windows). Це дозволить побачити помилки при запуску і залишить оболонку відкритою після завершення SubGit.

Ви можете додати сюди додаткові параметри, схожі на git-svn . Я використовую лише --dede-домен myCompanyDomain.com для виправлення домену електронної адреси авторів SVN.
У мене стандартна структура сховища SVN (магістраль / гілки / теги), і у нас не було проблем з "картографуванням авторів". Тому я більше нічого не роблю.

(Якщо ви хочете перемістити теги, такі як гілки, або у вашому SVN є кілька папок гілок / тегів, ви можете розглянути можливість використання більш детального підходу SubGit )

Порада 1 : Використовуйте --minimal-revision YourSvnRevNumber, щоб швидко побачити, як все википає (якась налагодження). Особливо корисно бачити вирішені імена авторів або електронні листи.
Або обмежити глибину історії міграції.

Порада 2 : Міграція може бути перервана ( Ctrl+ C) та відновлена ​​за допомогою наступної команди / файла оновлення.
Я не раджу робити це для великих сховищ. Я отримав "Немає пам'яті Java + виняток Windows".

Порада 3 : Краще створити копію оголеного сховища результатів.

Вміст файлу / команди для оновлення:

start    subgit import  directory/path/Local.git.Repo

Ви можете запускати його будь-яку кількість разів, коли хочете отримати останні зобов'язання команди у вашому сховищі Git.

Увага! Не торкайтеся голого сховища (наприклад, створення гілок).
Ви приймете наступну фатальну помилку:

Помилка, яку не можна знайти

3. Запустіть першу команду / файл. Для великого сховища знадобиться довгий час. 30 годин для мого скромного сховища.

Це все.
Ви можете будь-коли оновити своє сховище Git з SVN, запустивши другий файл / команду. І перед тим, як перейти на розробку до Git.
Це займе всього кілька секунд.



Є ще одне корисне завдання.

Перемістіть своє локальне сховище Git у віддалене сховище Git

Це ваш випадок? Давайте продовжимо.

  1. Налаштуйте пульти

Виконати:

$ git remote add origin url://your/repo.git
  1. Підготуйтеся до початкового відправлення вашого величезного локального сховища Git у віддалене сховище

За замовчуванням ваш Git не може надсилати великі куски. фатально: віддалений кінець повісив трубку несподівано

Давайте біжимо за цим:

git config --global http.postBuffer 1073741824

524288000 - 500 Мб 1073741824 - 1 Гб тощо.

Виправте локальні проблеми з сертифікатом . Якщо ваш git-сервер використовує пошкоджений сертифікат.

У мене є відключені сертифікати .

Також ваш сервер Git може мати обмеження щодо кількості запитів, які потрібно виправити .

  1. Натисніть всю міграцію до віддаленого сховища Git команди.

Запустити з локальним Git:

git push origin --mirror

( git push origin '*: *' для старих версій Git)

Якщо ви отримаєте наступне: помилка: не може породити git: Немає такого файлу чи каталогу ... Для мене повне відтворення мого сховища вирішує цю помилку (30 годин). Можна спробувати наступні команди

git push origin --all
git push origin --tags

Або спробуйте перевстановити Git ( марний для мене ). Або ви можете створити гілки з усіх тегів і натиснути їх. Або, або, або ...


10

репохірург

Для складних випадків інструментом вибору є репозиціонер Еріка С. Реймонда . Крім SVN, він підтримує багато інших систем управління версіями через fast-exportформат, а також CVS . Автор повідомляє про успішні перетворення давніх сховищ, таких як Emacs та FreeBSD .

Інструмент, очевидно, спрямований на майже ідеальне перетворення (наприклад, перетворення svn:ignoreвластивостей SVN у .gitignoreфайли) навіть для складних макетів сховища з довгою історією. У багатьох випадках інші інструменти можуть бути простішими у використанні.

Перш ніж заглиблюватися в документацію reposurgeonкомандного рядка, обов'язково прочитайте відмінний посібник з міграції DVCS, який переходить процес перетворення крок за кроком.


8

Цей посібник на веб-сайті atlassian - один із найкращих, що я знайшов:

https://www.atlassian.com/git/migration

Цей інструмент - https://bitbucket.org/atlassian/svn-migration-scripts - також дуже корисний для створення ваших авторів.txt, серед іншого.


Ця сторінка чудова, і IMHO найкраща відповідь! Це робить більшу частину грубої роботи для вас.
PfunnyGuy

8

Ви повинні встановити

git
git-svn

Скопійовано з цього посилання http://john.albin.net/git/convert-subversion-to-git .

1. Отримайте список усіх підконтрольних субверсії

Subversion просто перераховує ім’я користувача для кожного комітету. У довідках Git є набагато багатші дані, але, найпростіше, автору комісії потрібно вказати ім’я та електронну пошту. За замовчуванням інструмент git-svn буде просто перераховувати ім’я користувача SVN у полях автора та електронної пошти. Але трохи попрацювавши, ви можете створити список усіх користувачів SVN та їх відповідні ім’я та адреси Git. Цей список може використовуватися git-svn для перетворення простих імен користувачів svn у належні Git-виконавці.

З кореня локальної каси Subversion запустіть цю команду:

svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors-transform.txt

Це захопить усі повідомлення журналу, вилучить імена користувачів, усуне будь-які повторювані імена користувачів, впорядкує імена користувачів і помістить їх у файл «автори-перетворення.txt». Тепер відредагуйте кожен рядок у файлі. Наприклад, перетворити:

jwilkins = jwilkins <jwilkins>

в це:

jwilkins = John Albin Wilkins <johnalbin@example.com>

2. Клоніруйте сховище Subversion за допомогою git-svn

git svn clone [SVN repo URL] --no-metadata -A authors-transform.txt --stdlayout ~/temp

Це дозволить виконати стандартне перетворення git-svn (використовуючи створений на кроці файл авторів-transform.txt) та помістить сховище git у папку "~ / temp" всередині вашого домашнього каталогу.

3. Перетворити svn: ігнорувати властивості .gitignore

Якщо ваше svn repo використовувало властивості svn: ignore, ви можете легко перетворити це у файл .gitignore, використовуючи:

cd ~/temp
git svn show-ignore > .gitignore
git add .gitignore
git commit -m 'Convert svn:ignore properties to .gitignore.'

4. Натисніть сховище до голого сховища git

По-перше, створіть оголене сховище та зробіть його гілка за замовчуванням збігається з іменем гілки svn "trunk".

git init --bare ~/new-bare.git
cd ~/new-bare.git
git symbolic-ref HEAD refs/heads/trunk

Потім натисніть на тимчасове сховище до нового голого сховища.

cd ~/temp
git remote add bare ~/new-bare.git
git config remote.bare.push 'refs/remotes/*:refs/heads/*'
git push bare

Тепер ви можете безпечно видалити сховище ~ / temp.

5. Перейменуйте гілку "trunk" на "master"

Ваша основна галузь розвитку буде названа "магістраль", яка відповідає тому, що було в Subversion. Ви захочете перейменувати його в стандартну гілку Git, "головну", використовуючи:

cd ~/new-bare.git
git branch -m trunk master

6. Очистіть гілки та теги

git-svn робить усі теги Subversions на дуже короткі гілки в Git форми "теги / ім'я". Ви хочете перетворити всі ці гілки у фактичні теги Git, використовуючи:

cd ~/new-bare.git
git for-each-ref --format='%(refname)' refs/heads/tags |
cut -d / -f 4 |
while read ref
do
  git tag "$ref" "refs/heads/tags/$ref";
  git branch -D "tags/$ref";
done

Цей крок потребує певного набору тексту. :-) Але, не хвилюйтесь; ваша оболонка unix надасть вторинну підказку для наддовгої команди, яка починається з git for-every-ref.


7

GitHub тепер має функцію імпорту з сховища SVN . Я ніколи цього не пробував.


3
Поточна рекомендація GitHub - використовувати svn2gitпрограму, запропоновану в іншій відповіді .
ntc2

Імпортували зараз два досить великих проекти бездоганно. Всі гілки SVN були імпортовані (пам’ятайте, що НЕ використовуючи \ trunk частина у шляху репо). Я ще не знаю, що Github відстежуватиме нові зобов'язання.
Fr0sT

7

Дещо розширена відповідь із використанням лише git, SVN та bash. Він включає кроки для сховищ SVN, які не використовують звичайний макет із макетом каталогу магістралей / гілок / тегів (SVN не робить абсолютно нічого для забезпечення такого типу компонування).

Спочатку використовуйте цей скрипт bash, щоб сканувати ваше репортаж SVN для різних людей, які надали внесок, та створити шаблон для файлу відображення:

#!/usr/bin/env bash
authors=$(svn log -q | grep -e '^r' | awk 'BEGIN { FS = "|" } ; { print $2 }' | sort | uniq)
for author in ${authors}; do
  echo "${author} = NAME <USER@DOMAIN>";
done

Використовуйте це, щоб створити authorsфайл, де ви позначаєте імена користувачів svn на імена користувачів та електронну пошту, встановлені розробниками за допомогою git configвластивостей, user.nameі user.email(зауважте, що для такої служби, як GitHub, достатньо лише відповідного електронного листа).

Потім git svnклонуйте сховище svn до сховища git, розповівши йому про відображення:

git svn clone --authors-file=authors --stdlayout svn://example.org/Folder/projectroot

Це може зайняти надзвичайно багато часу, оскільки git svn індивідуально перевірятиме кожну редакцію для кожного тегу чи гілки, що існує. (зауважте, що теги у SVN - це справді гілки, тому вони як такі є у Git). Ви можете прискорити це, видаливши старі теги та гілки у SVN, які вам не потрібні.

Запуск цього на сервері в тій самій мережі або на тому ж сервері також може дійсно прискорити це. Крім того, якщо з якихось причин цей процес перерваний, ви можете відновити його за допомогою

git svn rebase --continue

У багатьох випадках ви закінчили тут. Але якщо ваше репортаж SVN має нетрадиційний макет, де у вас просто є каталог у SVN, який ви хочете розмістити у гітці git, ви можете зробити кілька додаткових кроків.

Найпростіший - просто зробити нове репортаж SVN на вашому сервері, який буде дотримуватися конвенції та використовувати svn copyдля розміщення вашого каталогу у стовбурі чи гілці. Це може бути єдиним способом, якщо ваш каталог знаходиться в корені репо, коли я останній раз пробував це, git svnпросто відмовився робити замовлення.

Ви також можете зробити це за допомогою git. Для git svn cloneпростого використання каталогу, який ви хочете розмістити у гітці git.

Після запуску

git branch --set-upstream master git-svn
git svn rebase

Зауважте, що для цього потрібен Git 1.7 або вище.


Я б запропонував поєднати цю інформацію за цим посиланням: sailmaker.co.uk/blog/2013/05/05/…
Joan PS

7

Я опублікував покроковий посібник ( тут ) для перетворення svn в git, включаючи перетворення тегів svn у теги git та svn гілок у гілки git.

Коротка версія:

1) клонувати svn з певного ревізійного номера. (номер редакції повинен бути найстарішим, який потрібно перенести)

git svn clone --username=yourSvnUsername -T trunk_subdir -t tags_subdir -b branches_subdir -r aRevisionNumber svn_url gitreponame

2) отримання даних svn. Цей крок - це той, на який потрібно найбільше часу.

cd gitreponame
git svn fetch

повторити git svn fetch, поки не закінчиться без помилок

3) оновити головну гілку

git svn rebase

4) Створіть локальні відділення з філій svn, скопіювавши посилання

cp .git/refs/remotes/origin/* .git/refs/heads/

5) конвертувати теги svn у теги git

git for-each-ref refs/remotes/origin/tags | sed 's#^.*\([[:xdigit:]]\{40\}\).*refs/remotes/origin/tags/\(.*\)$#\2 \1#g' | while read p; do git tag -m "tag from svn" $p; done

6) Поставте сховище в краще місце, наприклад, github

git remotes add newrepo git@github.com:aUser/aProjectName.git
git push newrepo refs/heads/*
git push --tags newrepo

Якщо ви хочете отримати більше деталей, прочитайте мій пост або запитайте мене.


6

Ми можемо використовувати git svn cloneкоманди, як показано нижче.

  • svn log -q <SVN_URL> | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors.txt

Вищенаведена команда створить авторський файл із SVN комітів.

  • svn log --stop-on-copy <SVN_URL>

Наведена вище команда дасть вам перший номер редакції, коли ваш проект SVN створений.

  • git svn clone -r<SVN_REV_NO>:HEAD --no-minimize-url --stdlayout --no-metadata --authors-file authors.txt <SVN_URL>

Вище команда створить сховище Git в локальному.

Проблема полягає в тому, що він не конвертує гілки та теги для просування. Робити їх доведеться вручну. Наприклад, нижче для галузей:

$ git remote add origin https://github.com/pankaj0323/JDProjects.git
$ git branch -a
* master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$$ git checkout -b MyDevBranch origin/MyDevBranch
Branch MyDevBranch set up to track remote branch MyDevBranch from origin.
Switched to a new branch 'MyDevBranch'
$ git branch -a
* MyDevBranch
  master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$

Для тегів:

$git checkout origin/tags/MyDevBranch-1.0
Note: checking out 'origin/tags/MyDevBranch-1.0'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 3041d81... Creating a tag
$ git branch -a
* (detached from origin/tags/MyDevBranch-1.0)
  MyDevBranch
  master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$ git tag -a MyDevBranch-1.0 -m "creating tag"
$git tag
MyDevBranch-1.0
$

Тепер пересуньте майстер, гілки та теги до віддаленого сховища git.

$ git push origin master MyDevBranch MyDevBranch-1.0
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (14/14), 2.28 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To https://github.com/pankaj0323/JDProjects.git
 * [new branch]      master -> master
 * [new branch]      MyDevBranch -> MyDevBranch
 * [new tag]         MyDevBranch-1.0 -> MyDevBranch-1.0
$

svn2git утиліта

Утиліта svn2git видаляє ручні зусилля з гілками та тегами.

Встановіть його за допомогою команди sudo gem install svn2git. Після цього запустіть команду нижче.

  • $ svn2git <SVN_URL> --authors authors.txt --revision <SVN_REV_NO>

Тепер ви можете перелічити гілки, теги та легко натиснути на них.

$ git remote add origin https://github.com/pankaj0323/JDProjects.git
$ git branch -a
  MyDevBranch
* master
  remotes/svn/MyDevBranch
  remotes/svn/trunk
$ git tag
  MyDevBranch-1.0
$ git push origin master MyDevBranch MyDevBranch-1.0

Уявіть, у вас є 20 гілок і тегів, очевидно, svn2git заощадить вам багато часу, і саме тому мені це подобається краще, ніж рідні команди. Це гарна обгортка навколо рідної git svn cloneкоманди.

Для повного прикладу див. Мій запис у блозі .




3

Якщо ви використовуєте SourceTree, ви можете зробити це безпосередньо з програми. Перейдіть у файл -> Створити / Клоніруйте:

  1. Введіть віддалений SVN URL як "Шлях до джерела / URL".
  2. Коли буде запропоновано, введіть свої облікові дані.
  3. Введіть місцеву папку як "Шлях до призначення".
  4. Дайте ім’я.
  5. У розширених параметрах виберіть "Git" зі спадного меню в "Створити локальний сховище типу".
  6. Ви можете необов'язково вказати версію, з якої клонуватись.
  7. Ударний клон.

Відкрийте репо в SourceTree, і ви побачите, що ваші повідомлення про перенесення також були переміщені.

Тепер перейдіть у Репозиторій -> Налаштування репозиторію та додайте нові відомості про віддалений репост. Якщо хочете, видаліть пульт SVN (я зробив це за допомогою параметра "Редагувати файл конфігурації").

Натисніть код на нове віддалене репо, коли ви будете готові і вільно кодуйте.


Дякую, надто швидко і швидко!
Рікард

Дякую. Це працювало на мене. Я використовую SourceTree та Stash.
VK_217

3

Для користувачів GitLab я розповів, як я мігрував із SVN тут:

https://gist.github.com/leftclickben/322b7a3042cbe97ed2af

Кроки з міграції зі SVN до GitLab

Налаштування

  • SVN розміщується в svn.domain.com.au.
  • SVN доступний через http(інші протоколи повинні працювати).
  • GitLab розміщується в git.domain.com.au:
    • Створюється група з простором імен dev-team.
    • Принаймні один обліковий запис користувача створюється, додається до групи та має ключ SSH для облікового запису, який використовується для міграції (тестування з використанням ssh git@git.domain.com.au).
    • Проект favourite-projectстворюється в dev-teamпросторі імен.
  • У файлі users.txtє відповідні реквізити користувача, один користувач на рядок, форми username = First Last <address@domain.com.au>, де usernameім’я користувача, вказане в журналах SVN. (Детальну інформацію див. У першому посиланні у розділі "Посилання", зокрема відповідь користувача Кейсі).

Версії

  • підривна версія 1.6.17 (r1128011)
  • git версія 1.9.1
  • Версія GitLab 7.2.1 ff1633f
  • Сервер Ubuntu 14.04

Команди

bash
git svn clone --stdlayout --no-metadata -A users.txt 
http://svn.domain.com.au/svn/repository/favourite-project
cd favourite-project
git remote add gitlab git@git.domain.com.au:dev-team/favourite-project.git
git push --set-upstream gitlab master

Це воно! Перезавантажте сторінку проекту у веб-інтерфейсі GitLab, і ви побачите всі перелічені файли та файли, які зараз перераховані.

Примітки

  • Якщо є невідомі користувачі, то git svn cloneкоманда зупиниться, і в цьому випадку поновлення users.txt, cd favourite-projectі git svn fetchбуде тривати від де він зупинився.
  • Стандарт trunk- tags- branchesмакет для SVN - сховища потрібно.
  • URL-адреса SVN, надана git svn cloneкоманді, зупиняється на рівні безпосередньо вище trunk/, tags/і branches/.
  • git svn cloneКоманда виробляє багато продукції, в тому числі таких сигналів завдання у верхній частині; Я ігнорував попередження.

Хоча це посилання може відповісти на питання, краще включити сюди суттєві частини відповіді та надати посилання для довідки. Відповіді лише на посилання можуть стати недійсними, якщо пов’язана сторінка зміниться.
Blackhole

1
Я не погоджуюсь. Зв'язаний вміст може змінитись, і вміст, що дублюється тут, не буде оновлюватися, а тому може бути застарілим (і насправді я вважаю, що він змінився з моменту первинного опублікування цієї відповіді). Ці вказівки говорять лише про те, щоб включити якийсь відповідний контекст для посилання, що я і зробив - на власне питання відповіли оптом за посиланням. Копіювання всього пов'язаного ресурсу сюди не потрібно чи потрібно. Невже я був заборонений за це ?!
leftclickben

2

Як інший бік, команда git-stash є знахідкою при спробі git за допомогою git-svn dcommiss.

Типовий процес:

  1. налаштувати git repo
  2. виконати деяку роботу над різними файлами
  3. вирішите перевірити деяку роботу, використовуючи git
  4. вирішити svn-dcommit
  5. отримати жахливу помилку "не може здійснити з брудним індексом".

Розчин (потрібен git 1.5.3+):

git stash; git svn dcommit ; git stash apply

2

Ось простий скрипт оболонки без залежностей, який конвертуватиме одне чи більше SVN-сховищ у git та підштовхуватиме їх до GitHub.

https://gist.github.com/NathanSweet/7327535

Приблизно в 30 рядках сценарію це: клонує за допомогою git SVN, створює файл .gitignore з властивостей SVN :: ігнорувати, вписує в оголене сховище git, перейменовує SVN-магістраль, щоб перетворити, перетворює SVN-теги в теги git і переміщує його в GitHub зберігаючи теги.

Я пережив сильний біль, щоб перенести десяток сховищ SVN з Google Code в GitHub. Це не допомогло, що я використовував Windows. Рубі були всілякі розбиті на моїй старій коробці Debian, і його робота в Windows була жартом. Інші рішення не спрацювали із шляхами Cygwin. Навіть коли я щось працював, я не міг зрозуміти, як змусити теги відображатися на GitHub (секрет - follow-tags).

Врешті-решт я спільно склав два короткі та прості сценарії, пов’язані вище, і це чудово працює. Рішення не повинно бути складнішим за це!


2
Я використав цей сценарій. Після трохи сліду та помилок, це спрацювало для мене. Будь ласка, майте на увазі, що для цього вам потрібен Git 1.8.3+ , оскільки --follow-теги підтримуються лише згодом.
nrobey

2

Я на Windows-машині і зробив невелику партію, щоб перенести репортаж SVN з історією (але без гілок) на репо GIT, просто зателефонувавши

transfer.bat http://svn.my.address/svn/myrepo/trunk https://git.my.address/orga/myrepo

Можливо, хтось може ним скористатися. Він створює папку TMP, перевіряючи там SVN-репо з git та додає нове походження та підштовхує його ... та видаляє папку ще раз.

@echo off 
SET FROM=%1 
SET TO=%2 
SET TMP=tmp_%random%

echo from:  %FROM% 
echo to:    %TO% 
echo tmp:   %TMP%

pause

git svn clone  --no-metadata --authors-file=users.txt %FROM% %TMP%  
cd %TMP% 
git remote add origin %TO% 
git push --set-upstream origin master


cd .. 
echo delete %TMP% ... 
pause

rmdir /s /q %TMP%

Ви все ще потребуєте users.txt із вашими відображеннями користувачів, як-от

User1 = User One <u.1@xxx.com>

Ця відповідь допомогла мені без проблем перенести всі мої сховища в BitBucket.
Гонсалінгуй

Радий почути. Я мав тільки досвід роботи з Gitea ... але переклав ~ ~ 40 репостів таким чином.
cljk

Дуже хороший! Thnx
b3wii

увага; У мене виникли погані проблеми із комірками. Я визнав це справді занадто пізно, але на це мені знадобилося кілька годин. Перевірте, чи містить у
вашій репортажі

1

Я просто хотів додати свій внесок до спільноти Git. Я написав простий скрипт bash, який автоматизує повний імпорт. На відміну від інших інструментів міграції, цей інструмент покладається на нативний git замість jGit. Цей інструмент також підтримує сховища з великою історією перегляду та чи великими краплями. Доступний через github:

https://github.com/onepremise/SGMS

Цей скрипт буде конвертувати проекти, що зберігаються у SVN, у такому форматі:

/trunk
  /Project1
  /Project2
/branches
     /Project1
     /Project2
/tags
 /Project1
 /Project2

Ця схема також популярна і підтримується:

/Project1
     /trunk
     /branches
     /tags
/Project2
     /trunk
     /branches
     /tags

Кожен проект буде синхронізований за назвою проекту:

Ex: ./migration https://svnurl.com/basepath project1

Якщо ви хочете перетворити повний репост, використовуйте наступний синтаксис:

Ex: ./migration https://svnurl.com/basepath .

0

Ефективне використання Git з Subversion - це щадне вступ до git-svn. Для існуючих сховищ SVN git-svn робить це дуже просто. Якщо ви запускаєте нове сховище, набагато простіше спершу створити порожнє сховище SVN, а потім імпортувати за допомогою git-svn, ніж це відбувається в зворотному напрямку. Створення нового сховища Git та імпортування у SVN можна зробити, але це трохи боляче, особливо якщо ви новачок у Git та сподіваєтесь зберегти історію фіксації.


0

Завантажте інсталятор Ruby для Windows та встановіть з ним останню версію. Додайте в свій шлях виконавчі файли Ruby.

  • Встановіть svn2git
  • Меню Пуск -> Усі програми -> Ruby -> Запустіть командний рядок за допомогою Ruby
  • Потім введіть “gem install svn2git” та введіть

    Міграція сховища субверсії

  • Відкрийте командний рядок Ruby та перейдіть до каталогу, де потрібно перемістити файли

    Тоді svn2git http: // [ ім'я домену ] / svn / [корінь сховища]

  • Переміщення проекту на Git може зайняти кілька годин, залежно від розміру коду проекту.

  • Цей головний крок допомагає створити структуру репозиторію Git, як зазначено нижче.

    SVN (/ Project_components) магістраль -> Git master SVN (/ Project_components) гілки -> Git гілки SVN (/ Project_components) теги -> Git теги

Створіть віддалений сховище та натисніть на зміни.


0

У GitHub є імпортер. Після створення сховища ви можете імпортувати з існуючого сховища через його URL-адресу. Він попросить ваші дані, якщо це можливо, і піде звідти.

Поки він працює, він знайде авторів, і ви зможете просто зіставити їх користувачам на GitHub.

Я використовував його для кількох сховищ зараз, і він досить точний і набагато швидший! На сховище було потрібно 10 хвилин з ~ 4000 комітами, а після того, як мій друг пройшов чотири дні!


0

Кілька відповідей тут посилаються на https://github.com/nirvdrum/svn2git , але для великих сховищ це може бути повільним. Я спробував використати https://github.com/svn-all-fast-export/svn2git, натомість це інструмент із точно такою ж назвою, але був використаний для переміщення KDE зі SVN до Git.

Трохи більше роботи над його налаштуванням, але коли конверсія сама для мене зайняла хвилини, де інший сценарій витратив години.


0

Для досягнення цієї мети існують різні методи. Я спробував деякі з них і виявив дійсно працюючий із встановленими на ОС Windows лише git та svn.

Передумови:

  1. git на windows (я використовував це) https://git-scm.com/
  2. svn із встановленими консольними інструментами (я використовував черепаху svn)
  3. Дамп-файл вашого сховища SVN. svnadmin dump /path/to/repository > repo_name.svn_dump

Кроки для досягнення кінцевої мети (переміщення всього сховища з історією до git, спочатку локального git, а потім віддаленого)

  1. Створіть порожній сховище (за допомогою консольних інструментів або tortoiseSVN) у каталозі REPO_NAME_FOLDER cd REPO_NAME_PARENT_FOLDER, поставте dumpfile.dump у REPO_NAME_PARENT_FOLDER

  2. svnadmin load REPO_NAME_FOLDER < dumpfile.dump Дочекайтеся цієї операції, можливо, це буде довго

  3. Ця команда безшумна, тому відкрийте друге вікно cmd: svnserve -d -R --root REPO_NAME_FOLDER Чому б просто не використовувати файл: /// ......? Тому що наступна команда не вдасться Unable to open ... to URL:, завдяки відповіді https://stackoverflow.com/a/6300968/4953065

  4. Створіть нову папку SOURCE_GIT_FOLDER

  5. cd SOURCE_GIT_FOLDER
  6. git svn clone svn: // localhost / Зачекайте цієї операції.

Нарешті, що у нас є?

Давайте перевіримо наш локальний сховище:

git log

Бачити попередні зобов’язання? Якщо так - добре

Отже, ви маєте повністю функціональне локальне сховище git зі своїми джерелами та старою історією svn. Тепер, якщо ви хочете перемістити його на якийсь сервер, використовуйте наступні команди:

git remote add origin https://fullurlpathtoyourrepo/reponame.git
git push -u origin --all # pushes up the repo and its refs for the first time
git push -u origin --tags # pushes up any tags

У моєму випадку мені не потрібні команди тегів, тому що у мого репо не є теги.

Удачі!


0

Перетворення svn підмодуля / папки "MyModule" в git з історією без тегів та гілок.

Щоб зберегти список ігнорування svn, використовуйте наведені вище коментарі після кроку 1

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.