Bagaimana cara memigrasi repositori SVN dengan riwayat ke repositori Git baru?

1509

Saya membaca manual Git, FAQ, kursus kilat Git - SVN, dll. Dan mereka semua menjelaskan ini dan itu, tetapi di mana pun Anda tidak dapat menemukan instruksi sederhana seperti:

Repositori SVN di: svn://myserver/path/to/svn/repos

Dapatkan repositori di: 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

Saya tidak berharap itu sesederhana itu, dan saya tidak berharap itu menjadi satu perintah. Tapi saya berharap itu tidak mencoba menjelaskan apa pun - hanya untuk mengatakan langkah apa yang harus diambil dengan memberikan contoh ini.

Milan Babuškov
sumber
6
Semakin mudah, saya hanya menyelesaikannya sendiri dan mendokumentasikan temuan saya dengan bantuan SO jmoses.co/2014/03/21/moving-from-svn-to-git.html
John Moses
Gunakan jawaban Casey di bawah ini, tetapi sebelum Anda menjalankan perintah "svn clone ...", lihat bagaimana menambahkan baris "Visual SVN Server" tambahan ke file user.txt Anda ... di sini: stackoverflow.com/questions/8971208/ …
MacGyver
1
Juga, jika Anda memiliki opsi "buat email pribadi diperiksa di profil GitHub Anda, gunakan ini sebagai alamat email Anda di users.txt untuk mencocokkan. [email protected], sehingga alamat email asli Anda tidak muncul sedang berkomitmen
MacGyver

Jawaban:

529

Sihir:

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

Git dan SVN beroperasi sangat berbeda. Anda perlu mempelajari Git, dan jika Anda ingin melacak perubahan dari SVN hulu, Anda harus belajar git-svn. The git-svn halaman utama memiliki bagian contoh yang baik :

$ git svn --help
jfm3
sumber
140
Jawaban dari @Casey menjawab pertanyaan asli jauh lebih baik.
Doug Wilson
3
Apakah ini akan menjaga cabang dan segalanya? atau hanya mengkloning bagasi?
Eildosa
7
@ Eildosa: Ini hanya akan mengkloning bagasi. Lihat jawaban Casey sebagai alternatif.
sleske
3
@ DouglasWilson tapi saya tidak bisa melihat jawaban Casey di sini. Apakah jawaban di bawah ini dengan 13 penulis yang dimulai dengan "Buat file pengguna"?
Andrey Regentov
68
Untuk orang lain yang bertanya-tanya yang merupakan "jawaban Casey" yang direferensikan dalam banyak komentar di sekitar sini, inilah yang ini (Casey mengubah nama panggilannya menjadi cmcginty).
Stefan Monov
1560

Buat file pengguna (yaitu users.txt) untuk memetakan pengguna SVN ke Git:

user1 = First Last Name <[email protected]>
user2 = First Last Name <[email protected]>
...

Anda bisa menggunakan one-liner ini untuk membangun templat dari repositori SVN yang ada:

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

SVN akan berhenti jika menemukan pengguna SVN yang hilang tidak ada dalam file. Tetapi setelah itu Anda dapat memperbarui file dan mengambil di mana Anda tinggalkan.

Sekarang tarik data SVN dari repositori:

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

Perintah ini akan membuat repositori Git baru dest_dir-tmpdan mulai menarik repositori SVN. Perhatikan bahwa flag "--stdlayout" menyiratkan Anda memiliki tata letak "trunk /, branch /, tag /" SVN yang umum. Jika tata letak Anda berbeda, kenallah--tags , --branches, --trunkpilihan (pada umumnya git svn help).

Semua protokol umum diperbolehkan: svn://, http://, https://. URL harus menargetkan repositori dasar, sesuatu seperti http://svn.mycompany.com/myrepo/repository . String URL tidak boleh menyertakan /trunk, /tagatau/branches .

Perhatikan bahwa setelah menjalankan perintah ini sangat sering terlihat seperti operasi "hang / freezed", dan itu cukup normal bahwa itu dapat macet untuk waktu yang lama setelah menginisialisasi repositori baru. Akhirnya Anda akan melihat pesan log yang menunjukkan bahwa itu sedang dimigrasi.

Juga perhatikan bahwa jika Anda menghilangkan --no-metadataflag, Git akan menambahkan informasi tentang revisi SVN yang sesuai dengan pesan commit (yaitu git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>)

Jika nama pengguna tidak ditemukan, perbarui users.txtfile Anda kemudian:

cd dest_dir-tmp
git svn fetch

Anda mungkin harus mengulangi perintah terakhir itu beberapa kali, jika Anda memiliki proyek besar, sampai semua Subversion berkomitmen diambil:

git svn fetch

Setelah selesai, Git akan checkout SVN trunkke cabang baru. Cabang-cabang lain diatur sebagai remote. Anda dapat melihat cabang SVN lainnya dengan:

git branch -r

Jika Anda ingin menyimpan cabang jarak jauh lainnya di repositori Anda, Anda ingin membuat cabang lokal untuk masing-masing secara manual. (Lewati trunk / master.) Jika Anda tidak melakukan ini, cabang tidak akan dikloning pada langkah terakhir.

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

Tag diimpor sebagai cabang. Anda harus membuat cabang lokal, membuat tag dan menghapus cabang untuk menjadikannya sebagai tag di Git. Untuk melakukannya dengan tag "v1":

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

Kloning repositori GIT-SVN Anda ke repositori Git yang bersih:

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

Cabang lokal yang Anda buat sebelumnya dari cabang jarak jauh hanya akan disalin sebagai cabang jarak jauh ke repositori hasil kloning baru. (Lewati trunk / master.) Untuk setiap cabang yang ingin Anda pertahankan:

git checkout -b local_branch origin/remote_branch

Terakhir, hapus remote dari repositori Git bersih Anda yang menunjuk ke repositori sementara yang sekarang dihapus:

git remote rm origin
cmcginty
sumber
36
Posting blog ini oleh Eelke adalah referensi silang yang bagus untuk jawaban di atas. blokspeed.net/blog/2010/09/converting-from-subversion-to-git
kgriffs
4
Ini 99% luar biasa, mengikuti langkah-langkah ini, saya mendapatkan semuanya dalam urutan kecuali cabang: setelah langkah terakhir, mereka jauh saja (dan dengan demikian menghilang ketika saya melakukan perintah: git remote rm origin)
Dirty Henry
4
GitHub memiliki langkah-demi-langkah yang sangat mudah: github.com/nirvdrum/svn2git#readme
Dan Nissenbaum
8
Bagi mereka yang di bawah Windows, saya membuat skrip PowerShell berdasarkan metode ini: gist.github.com/Gimly/90df046dc38181bb18de
Gimly
5
Peringatan untuk repo besar dengan banyak sejarah, ini lambat dan membosankan . Saya menyerah mencoba untuk memigrasi semua cabang lama dan hanya bermigrasi bagasi.
Jess
195

Migrasikan Repositori Subversi Anda ke Repositori Git . Pertama, Anda harus membuat file yang memetakan nama penulis komit Subversi Anda ke komit Git, katakan ~/authors.txt:

jmaddox = Jon Maddox <[email protected]>
bigpappa = Brian Biggs <[email protected]>

Kemudian Anda dapat mengunduh data Subversion ke dalam repositori Git:

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

Jika Anda menggunakan Mac, Anda bisa dapatkan git-svndari MacPorts dengan menginstal git-core +svn.

Jika repositori subversi Anda berada di mesin yang sama dengan repositori git yang Anda inginkan, maka Anda dapat menggunakan sintaks ini untuk langkah init, jika tidak semuanya sama:

git svn init file:///home/user/repoName --no-metadata
zoul
sumber
1
Ketika saya mengomentari jawaban lain, saya harus menghapus spasi di =dalam users.txtkarena impor dibatalkan dan saya mendapatkan repositori kosong.
Sebastián Grignoli
8
Ah! Penjelasan sederhana dan efektif. Dalam kasus saya file:///menolak untuk bekerja, hanya saya yang digunakan svnserve.exe --daemondan kemudian digunakan svn://localhost/home/user/repo.
Daniel Reis
Di Mac saya yang menjalankan Mountain Lion, git svn tidak akan berfungsi sampai saya masuk ke Xcode dan menginstal Command Line Tools yang ditemukan di tab Downloads di panel Preferences. Atau, saya bisa menginstal hanya Alat Baris Perintah untuk OS X Mountain Lion yang ditemukan di situs Pengembang Apple.
Drew
3
Untuk kasus saya, saya harus mengkonversi file authors.txtke utf-8 without BOM.
Silvan
Ini bekerja dengan baik untuk saya! Setelah saya memiliki repositori lokal, saya menggunakan posting cmcginty mulai dari "Kloning repositori GIT-SVN Anda ke repositori Git yang bersih:" Saya pikir alasan utama saya suka jawaban @ zoul adalah penggunaannya git svn init, git svn configkemudian akhirnya git svn fetchkarena lebih mudah untuk melakukannya dengan cara ini, saya harus mengambil beberapa kali untuk memperbaikinya. Single-line cmcginty git svn clone, yang bertiga, terlalu kacau untuk saya.
Mike
70

Saya menggunakan skrip svn2git dan bekerja seperti mantra.

Uwe Keim
sumber
4
T: apakah ini memperbaiki spasi dalam nama tag dan cabang (diizinkan dalam svn dan tidak diizinkan di git)?
spazm
2
Panduan ini sangat berguna: troyhunt.com/2014/08/migrating-from-subversion-to-git-with.html
Morten Holmgaard
Lebih baik untuk menjelaskan jawaban kalau tidak kita menghasilkan skrip kiddies.
Josh Habdas
Bagaimana jika semua cabang Anda ada di root SVN dan Anda tidak memiliki trunk atau tag?
Kal
58

Saya menyarankan untuk merasa nyaman dengan Git sebelum mencoba menggunakan git-svn terus-menerus, yaitu menjaga SVN sebagai repo terpusat dan menggunakan Git secara lokal.

Namun, untuk migrasi sederhana dengan semua riwayat, berikut adalah beberapa langkah sederhana:

Inisialisasi repo lokal:

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

Tandai seberapa jauh Anda ingin mulai mengimpor revisi:

git svn fetch -r42

(atau hanya "git svn fetch" untuk semua revs)

Sebenarnya mengambil semuanya sejak itu:

git svn rebase

Anda dapat memeriksa hasil impor dengan Gitk. Saya tidak yakin apakah ini berfungsi pada Windows, ini berfungsi pada OSX dan Linux:

gitk

Ketika Anda mendapatkan repo SVN Anda dikloning secara lokal, Anda mungkin ingin mendorongnya ke repo Git terpusat untuk kolaborasi yang lebih mudah.

Pertama buat repo jarak jauh kosong Anda (mungkin di GitHub ?):

git remote add origin [email protected]:user/project-name.git

Kemudian, secara opsional sinkronkan cabang utama Anda sehingga operasi tarikan akan secara otomatis menggabungkan master jarak jauh dengan master lokal Anda, ketika keduanya berisi hal-hal baru:

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

Setelah itu, Anda mungkin tertarik untuk mencoba sendiri git_remote_branch alat , yang membantu menangani cabang-cabang jarak jauh:

Posting penjelasan pertama: " Git cabang jarak jauh "

Tindak lanjuti untuk versi terbaru: " Saatnya git berkolaborasi dengan git_remote_branch "

webmat
sumber
Sangat membantu, ini bekerja dengan sempurna. Saya akan menambahkan bahwa ada satu langkah terakhir yang harus diambil jika Anda menyinkronkan ke repositori jarak jauh. Setelah langkah-langkah konfigurasi git, saya perlugit push origin master
mag382
31

Ada solusi baru untuk kelancaran migrasi dari Subversion ke Git (atau untuk menggunakan keduanya secara bersamaan): SubGit .

Saya sedang mengerjakan proyek ini sendiri. Kami menggunakan SubGit dalam repositori kami - beberapa rekan satu tim saya menggunakan Git dan beberapa Subversi dan sejauh ini berfungsi sangat baik.

Untuk bermigrasi dari Subversion ke Git dengan SubGit, Anda perlu menjalankan:

$ subgit install svn_repos
...
TRANSLATION SUCCESSFUL 

Setelah itu Anda akan mendapatkan repositori Git di svn_repos / .git dan dapat mengkloningnya, atau teruskan menggunakan Subversion dan repositori Git baru ini bersama-sama: SubGit akan memastikan bahwa keduanya selalu tetap sinkron.

Jika repositori Subversion Anda berisi beberapa proyek, maka beberapa repositori Git akan dibuat di direktori svn_repos / git. Untuk menyesuaikan terjemahan sebelum menjalankannya lakukan hal berikut:

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

Dengan SubGit Anda dapat bermigrasi ke Git murni (bukan git-svn) dan mulai menggunakannya sambil tetap menyimpan Subversi selama Anda membutuhkannya (misalnya, untuk alat bangunan yang sudah dikonfigurasi,).

Semoga ini membantu!

Alexander Kitaev
sumber
4
Perhatikan bahwa impor satu kali (menggunakan subgit importperintah) bahkan tampaknya tidak memerlukan lisensi. Terjemahan akurat svn:ignoreproperti ke .gitignorefile juga disertakan.
krlmlr
1
SubGit tidak akan mengenali kunci pribadi saya, maupun bendera apa pun yang saya atur di baris perintah. Dokumentasi sangat buruk. Ini bukan alternatif yang layak untuk git svn.
pfnuesel
1
error: 'svn_repos' bukan lokasi terkonfigurasi yang valid; File konfigurasi SubGit tidak ada.
Jon Davis
19

Lihat halaman resmi git-svn . Secara khusus, lihat di bawah "Contoh Dasar":

Melacak dan berkontribusi ke seluruh proyek yang dikelola Subversion (lengkap dengan trunk, tag, dan cabang):

# Clone a repo (like git clone):
    git svn clone http://svn.foo.org/project -T trunk -b branches -t tags
EfForEffort
sumber
Perintah klon Anda berfungsi, yang di atas tidak memberi saya apa-apa selain repo git kosong. Satu-satunya perbedaan tampaknya adalah '-T trunk' yang eksplisit.
user1984717
14

SubGit (vs Blue Screen of Death)

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

Itu semua.

+ Untuk memperbarui dari SVN, repositori Git dibuat oleh perintah pertama.

subgit import  directory/path/Local.git.Repo

Saya menggunakan cara untuk bermigrasi ke Git secara instan untuk repositori besar.
Tentu saja Anda perlu persiapan.
Tetapi Anda mungkin tidak menghentikan proses pengembangan sama sekali.

Ini jalan saya.

Solusi saya terlihat seperti:

  • Migrasikan SVN ke repositori Git
  • Perbarui repositori Git sesaat sebelum tim beralih ke .

Migrasi membutuhkan banyak waktu untuk repositori SVN besar.
Tetapi memperbarui migrasi selesai hanya beberapa detik.

Tentu saja saya menggunakan SubGit , mama. git-svn membuat saya Blue Screen of Death . Terus-menerus. Dan git-svn membuat saya bosan dengan kesalahan fatal " nama file terlalu lama " Git .

LANGKAH

1. Unduh SubGit

2. Mempersiapkan migrasi dan memperbarui perintah.

Katakanlah kita melakukannya untuk Windows (itu mudah untuk port ke Linux).
Dalam direktori nampan instalasi SubGit (subgit-2.XX \ bin), buat dua file .bat.

Konten file / perintah untuk migrasi:

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

Perintah "mulai" adalah opsional di sini (Windows). Ini akan memungkinkan untuk melihat kesalahan saat memulai dan membiarkan shell dibuka setelah SubGit selesai.

Anda dapat menambahkan parameter tambahan di sini mirip dengan git-svn . Saya hanya menggunakan --default-domain myCompanyDomain.com untuk memperbaiki domain dari alamat email penulis SVN.
Saya memiliki struktur repositori SVN standar (trunk / branch / tag) dan kami tidak memiliki masalah dengan "pemetaan penulis". Jadi saya tidak melakukan apa-apa lagi.

(Jika Anda ingin memigrasi tag seperti cabang atau SVN Anda memiliki beberapa folder cabang / tag, Anda dapat mempertimbangkan untuk menggunakan pendekatan SubGit yang lebih verbose )

Tips 1 : Gunakan --minimal-revisi YourSvnRevNumber untuk melihat dengan cepat bagaimana hal-hal mendidih (semacam debugging). Yang sangat berguna adalah untuk melihat nama atau email penulis yang diselesaikan.
Atau untuk membatasi kedalaman riwayat migrasi.

Tip 2 : Migrasi dapat terganggu ( Ctrl+ C) dan dikembalikan dengan menjalankan perintah / file pembaruan berikutnya.
Saya tidak menyarankan melakukan ini untuk repositori besar. Saya telah menerima "Kehabisan memori Java + Windows exception".

Tip 3 : Lebih baik membuat salinan dari repositori telanjang hasil Anda.

Konten file / perintah untuk memperbarui:

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

Anda dapat menjalankannya berapapun kali ketika Anda ingin mendapatkan komitmen tim terakhir ke repositori Git Anda.

Peringatan! Jangan menyentuh gudang kosong Anda (misalnya membuat cabang).
Anda akan mengambil kesalahan fatal berikutnya:

Kesalahan yang tidak dapat dipulihkan: tidak sinkron dan tidak dapat disinkronkan ... Menerjemahkan revisi Subversion ke Git berkomitmen ...

3. Jalankan perintah / file pertama. Ini akan membutuhkan waktu lama untuk repositori besar. 30 jam untuk repositori saya yang sederhana.

Itu semua.
Anda dapat memperbarui repositori Git Anda dari SVN kapan saja berapapun dengan menjalankan file / perintah kedua. Dan sebelum beralih dari tim pengembangan Anda ke Git.
Ini akan memakan waktu hanya beberapa detik.



Ada satu tugas lagi yang bermanfaat.

Dorong repositori Git lokal Anda ke repositori Git jarak jauh

Apakah ini kasus Anda? Mari kita lanjutkan.

  1. Konfigurasikan remote Anda

Lari:

$ git remote add origin url://your/repo.git
  1. Bersiaplah untuk mengirim awal repositori Git lokal besar Anda ke repositori jarak jauh

Secara default, Git Anda tidak dapat mengirim potongan besar. fatal: Ujung yang jauh menutup secara tak terduga

Mari kita jalankan untuk itu:

git config --global http.postBuffer 1073741824

524288000 - 500 MB 1073741824 - 1 GB, dll.

Perbaiki masalah sertifikat lokal Anda . Jika git-server Anda menggunakan sertifikat yang rusak.

Saya telah menonaktifkan sertifikat .

Juga server Git Anda mungkin memiliki batasan jumlah permintaan yang perlu diperbaiki .

  1. Dorong semua migrasi ke repositori Git jarak jauh tim.

Jalankan dengan Git lokal:

git push origin --mirror

( git push origin '*: *' untuk versi Git lama)

Jika Anda mendapatkan yang berikut: kesalahan: tidak dapat menelurkan git: Tidak ada file atau direktori seperti itu ... Bagi saya rekreasi penuh dari repositori saya menyelesaikan kesalahan ini (30 jam). Anda dapat mencoba perintah selanjutnya

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

Atau coba instal ulang Git ( tidak berguna bagi saya ). Atau Anda dapat membuat cabang dari semua tag Anda dan mendorongnya. Atau, atau, atau ...

it3xl
sumber
10

reposurgeon

Untuk kasus-kasus rumit, reposurgeon oleh Eric S. Raymond adalah alat pilihan. Selain SVN, ia mendukung banyak sistem kontrol versi lain melalui fast-exportformat, dan juga CVS . Penulis melaporkan konversi repositori kuno yang berhasil seperti Emacs dan FreeBSD .

Alat ini tampaknya bertujuan konversi yang hampir sempurna (seperti mengkonversi svn:ignoreproperti SVN ke .gitignorefile) bahkan untuk tata letak repositori yang sulit dengan sejarah panjang. Untuk banyak kasus, alat lain mungkin lebih mudah digunakan.

Sebelum mempelajari dokumentasi reposurgeonbaris perintah, pastikan untuk membaca panduan migrasi DVCS yang luar biasa yang membahas proses konversi langkah demi langkah.

Peter Mortensen
sumber
8

Anda harus Instal

git
git-svn

Disalin dari tautan ini http://john.albin.net/git/convert-subversion-to-git .

1. Ambil daftar semua pengalih Subversion

Subversi cukup mencantumkan nama pengguna untuk setiap komit. Komit Git memiliki banyak data yang lebih kaya, tetapi yang paling sederhana, pembuat komit perlu memiliki nama dan email yang terdaftar. Secara default alat git-svn hanya akan mencantumkan nama pengguna SVN di bidang penulis dan surel. Tetapi dengan sedikit kerja, Anda dapat membuat daftar semua pengguna SVN dan apa nama dan email Git yang sesuai. Daftar ini dapat digunakan oleh git-svn untuk mengubah nama pengguna svn polos menjadi commiter Git yang tepat.

Dari akar checkout Subversion lokal Anda, jalankan perintah ini:

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

Itu akan mengambil semua pesan log, mencabut nama pengguna, menghilangkan setiap nama pengguna duplikat, mengurutkan nama pengguna dan menempatkannya ke dalam file "penulis-transform.txt". Sekarang edit setiap baris dalam file. Misalnya, konversi:

jwilkins = jwilkins <jwilkins>

dalam hal ini:

jwilkins = John Albin Wilkins <[email protected]>

2. Kloning repositori Subversion menggunakan git-svn

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

Ini akan melakukan transformasi git-svn standar (menggunakan file author-transform.txt yang Anda buat pada langkah 1) dan menempatkan repositori git di folder “~ / temp” di dalam direktori home Anda.

3. Konversi svn: abaikan properti menjadi .gitignore

Jika repo svn Anda menggunakan svn: abaikan properti, Anda dapat dengan mudah mengonversi ini ke file .gitignore menggunakan:

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

4. Dorong repositori ke repositori kosong

Pertama, buat repositori kosong dan buat pencocokan cabang default dengan nama cabang "trunk" svn.

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

Kemudian dorong repositori temp ke repositori kosong yang baru.

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

Anda sekarang dapat menghapus repositori ~ / temp dengan aman.

5. Ganti nama cabang "trunk" menjadi "master"

Cabang pengembangan utama Anda akan diberi nama "trunk" yang cocok dengan nama di Subversion. Anda akan ingin menamainya menjadi cabang "master" standar Git menggunakan:

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

6. Bersihkan cabang dan tag

git-svn membuat semua tag Subversi menjadi cabang yang sangat pendek di Git dari bentuk "tag / nama". Anda ingin mengonversi semua cabang tersebut menjadi tag Git aktual menggunakan:

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

Langkah ini akan membutuhkan sedikit pengetikan. :-) Tapi, jangan khawatir; shell unix Anda akan memberikan prompt sekunder untuk perintah ekstra panjang yang dimulai dengan git untuk-masing-masing ref.

Valarpirai
sumber
7

GitHub sekarang memiliki fitur untuk mengimpor dari repositori SVN . Saya tidak pernah mencobanya.

webmat
sumber
3
Rekomendasi GitHub saat ini adalah menggunakan svn2gitprogram yang disarankan dalam jawaban lain .
ntc2
Mengimpor dua proyek yang cukup besar sekarang dengan sempurna. Semua cabang SVN diimpor (ingat JANGAN menggunakan bagian \ trunk di jalur repo). Satu hal yang saya belum tahu adalah apakah Github akan melacak komit baru.
Fr0sT
7

Jawaban yang agak panjang hanya menggunakan git, SVN, dan bash. Ini termasuk langkah-langkah untuk repositori SVN yang tidak menggunakan tata letak konvensional dengan tata letak direktori trunk / cabang / tag (SVN sama sekali tidak melakukan apa pun untuk menegakkan tata letak semacam ini).

Pertama-tama gunakan skrip bash ini untuk memindai repo SVN Anda untuk orang-orang berbeda yang berkontribusi dan membuat templat untuk file pemetaan:

#!/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

Gunakan ini untuk membuat authorsfile di mana Anda memetakan nama pengguna ke nama pengguna dan email yang ditetapkan oleh pengembang Anda menggunakan git configproperti user.namedan user.email(perhatikan bahwa untuk layanan seperti GitHub hanya memiliki email yang cocok sudah cukup).

Kemudian git svnklon repositori svn ke repositori git, ceritakan tentang pemetaan:

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

Ini bisa memakan waktu sangat lama, karena git svn akan memeriksa setiap revisi untuk setiap tag atau cabang yang ada. (perhatikan bahwa tag di SVN benar-benar cabang, sehingga berakhir seperti itu di Git). Anda dapat mempercepat ini dengan menghapus tag dan cabang lama di SVN yang tidak Anda butuhkan.

Menjalankan ini di server di jaringan yang sama atau di server yang sama juga bisa mempercepat ini. Juga, jika karena alasan tertentu proses ini terganggu Anda dapat melanjutkannya menggunakan

git svn rebase --continue

Dalam banyak kasus Anda selesai di sini. Tetapi jika repo SVN Anda memiliki tata letak yang tidak konvensional di mana Anda hanya memiliki direktori di SVN yang ingin Anda masukkan ke dalam cabang git, Anda dapat melakukan beberapa langkah tambahan.

Yang paling sederhana adalah dengan hanya membuat repo SVN baru di server Anda yang tidak mengikuti konvensi dan digunakan svn copyuntuk meletakkan direktori Anda di trunk atau cabang. Ini mungkin satu-satunya cara jika direktori Anda berada di akar repo, ketika saya terakhir mencoba ini git svnhanya menolak untuk melakukan checkout.

Anda juga dapat melakukan ini menggunakan git. Untuk git svn clonecukup menggunakan direktori yang ingin Anda masukkan ke dalam cabang git.

Setelah lari

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

Perhatikan bahwa ini membutuhkan Git 1.7 atau lebih tinggi.

thoutbecker
sumber
Saya akan mengusulkan untuk menggabungkan informasi ini dengan tautan ini: sailmaker.co.uk/blog/2013/05/05/…
Joan PS
7

Saya telah memposting panduan langkah demi langkah (di sini ) untuk mengkonversi svn ke git termasuk mengkonversi svn tag ke git tag dan svn branch in menjadi git branch.

Versi pendek:

1) mengkloning svn dari nomor revisi tertentu. (nomor revisi harus yang tertua yang ingin Anda migrasikan)

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

2) mengambil data svn. Langkah ini yang paling memakan waktu.

cd gitreponame
git svn fetch

ulangi git svn fetch sampai selesai tanpa kesalahan

3) perbarui cabang utama

git svn rebase

4) Buat cabang lokal dari cabang svn dengan menyalin referensi

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

5) mengkonversi svn tag menjadi git tag

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) Letakkan repositori di tempat yang lebih baik seperti github

git remotes add newrepo [email protected]:aUser/aProjectName.git
git push newrepo refs/heads/*
git push --tags newrepo

Jika Anda ingin detail lebih lanjut, baca posting saya atau tanyakan kepada saya.

Pablo Belaustegui
sumber
6

Kita dapat menggunakan git svn cloneperintah seperti di bawah ini.

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

Perintah di atas akan membuat file penulis dari komit SVN.

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

Perintah di atas akan memberi Anda nomor revisi pertama ketika proyek SVN Anda dibuat.

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

Perintah di atas akan membuat repositori Git di lokal.

Masalahnya adalah itu tidak akan mengkonversi cabang dan tag untuk mendorong. Anda harus melakukannya secara manual. Misalnya di bawah ini untuk cabang:

$ 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
$

Untuk tag:

$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
$

Sekarang dorong master, cabang dan tag ke repositori git jarak jauh.

$ 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
$

utilitas svn2git

utilitas svn2git menghapus upaya manual dengan cabang dan tag.

Instal menggunakan perintah sudo gem install svn2git. Setelah itu jalankan perintah di bawah ini.

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

Sekarang Anda dapat membuat daftar cabang, memberi tag dan mendorongnya dengan mudah.

$ 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

Bayangkan Anda memiliki 20 cabang dan tag, jelas svn2git akan menghemat banyak waktu dan itu sebabnya saya lebih suka daripada perintah asli. Ini pembungkus yang bagus di sekitar git svn cloneperintah asli .

Untuk contoh lengkap, lihat entri blog saya .

Pankaj
sumber
3

Saya sangat merekomendasikan rangkaian screencast pendek yang baru saya temukan ini. Penulis menuntun Anda melalui operasi dasar, dan menampilkan beberapa penggunaan yang lebih maju.

ripper234
sumber
3

Jika Anda menggunakan SourceTree, Anda dapat melakukan ini langsung dari aplikasi. File Goto -> Baru / Klon kemudian lakukan hal berikut:

  1. Masukkan URL SVN jarak jauh sebagai "Jalur / URL Sumber".
  2. Masukkan kredensial Anda saat diminta.
  3. Masukkan lokasi folder lokal sebagai "Jalur tujuan".
  4. Beri nama.
  5. Dalam opsi lanjutan pilih "Git" dari dropdown di "Buat repositori jenis lokal".
  6. Anda dapat secara opsional menentukan revisi untuk dikloning.
  7. Hit Klon.

Buka repo di SourceTree dan Anda akan melihat pesan komit Anda juga telah dimigrasi.

Sekarang pergi ke Repositori -> Pengaturan Repositori dan tambahkan detail repo jarak jauh yang baru. Hapus remote SVN jika Anda mau (saya melakukan ini melalui opsi "Edit File Config".

Dorong kode ke repo jarak jauh yang baru saat Anda siap dan kode bebas.

Craig Myles
sumber
Terima kasih, supereasi dan cepat!
Rikard
Terima kasih. Ini berhasil untuk saya. Saya menggunakan SourceTree dan Stash.
VK_217
3

Untuk pengguna GitLab saya telah membuat inti tentang bagaimana saya bermigrasi dari SVN di sini:

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

Langkah-langkah untuk bermigrasi dari SVN ke GitLab

Mendirikan

  • SVN di-host di svn.domain.com.au.
  • SVN dapat diakses melalui http(protokol lain harus berfungsi).
  • GitLab di-host di git.domain.com.audan:
    • Grup dibuat dengan namespace dev-team.
    • Setidaknya satu akun pengguna dibuat, ditambahkan ke grup, dan memiliki kunci SSH untuk akun yang digunakan untuk migrasi (menggunakan pengujian ssh [email protected]).
    • Proyek favourite-projectini dibuat di dev-teamnamespace.
  • File tersebut users.txtberisi rincian pengguna yang relevan, satu pengguna per baris, dari formulir username = First Last <[email protected]>, di mana usernamenama pengguna diberikan dalam log SVN. (Lihat tautan pertama di bagian Referensi untuk detail, khususnya jawaban oleh pengguna Casey).

Versi

  • versi subversi 1.6.17 (r1128011)
  • git versi 1.9.1
  • GitLab versi 7.2.1 ff1633f
  • Server Ubuntu 14.04

Perintah

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 [email protected]:dev-team/favourite-project.git
git push --set-upstream gitlab master

Itu dia! Muat ulang halaman proyek di GitLab web UI dan Anda akan melihat semua komit dan file sekarang terdaftar.

Catatan

  • Jika ada pengguna yang tidak dikenal, git svn cloneperintah akan berhenti, dalam hal ini, perbarui users.txt, cd favourite-projectdan git svn fetchakan melanjutkan dari tempat itu berhenti.
  • Diperlukan tata letak - trunk- standar untuk repositori SVN.tagsbranches
  • URL SVN yang diberikan kepada git svn cloneperintah berhenti di tingkat tepat di atas trunk/, tags/dan branches/.
  • The git svn cloneperintah menghasilkan banyak output, termasuk beberapa peringatan di atas; Saya mengabaikan peringatan itu.
Xharze
sumber
Meskipun tautan ini dapat menjawab pertanyaan, lebih baik untuk memasukkan bagian-bagian penting dari jawaban di sini dan memberikan tautan untuk referensi. Jawaban hanya tautan dapat menjadi tidak valid jika halaman tertaut berubah.
Blackhole
1
Saya tidak setuju. Konten yang ditautkan mungkin berubah, dan konten yang diduplikasi di sini tidak akan diperbarui, dan karena itu mungkin sudah ketinggalan zaman (dan sebenarnya saya percaya itu telah berubah sejak saya awalnya memposting jawaban ini). Pedoman hanya mengatakan untuk memasukkan beberapa konteks yang relevan untuk sebuah tautan, yang saya lakukan - pertanyaan sebenarnya dijawab secara grosir oleh tautan tersebut. Menyalin seluruh sumber daya yang ditautkan di sini tidak diperlukan atau tidak perlu. Apakah saya kalah suara untuk ini ?!
leftclickben
2

Sebagai samping lain, perintah git-simpanan adalah anugerah ketika mencoba untuk git dengan komit git-svn.

Proses yang khas:

  1. atur git repo
  2. lakukan beberapa pekerjaan pada file yang berbeda
  3. memutuskan untuk memeriksa beberapa pekerjaan, menggunakan git
  4. memutuskan untuk svn-dcommit
  5. dapatkan kesalahan "tidak dapat dilakukan dengan indeks kotor" yang ditakuti.

Solusinya (membutuhkan git 1.5.3+):

git stash; git svn dcommit ; git stash apply
Gregg Lind
sumber
2

Berikut ini adalah skrip shell sederhana tanpa dependensi yang akan mengonversi satu atau lebih repositori SVN ke git dan mendorongnya ke GitHub.

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

Di sekitar 30 baris skrip: klon menggunakan git SVN, membuat file .gitignore dari SVN :: abaikan properti, dorong ke dalam repositori bare git, ganti nama SVN trunk menjadi master, ubah tag SVN menjadi git tag, dan dorong ke GitHub sambil menjaga tag.

Saya mengalami banyak rasa sakit untuk memindahkan selusin repositori SVN dari Google Code ke GitHub. Tidak membantu saya menggunakan Windows. Ruby adalah semua jenis rusak pada kotak Debian lama saya dan membuatnya bekerja di Windows adalah lelucon. Solusi lain gagal bekerja dengan jalur Cygwin. Bahkan ketika saya mendapatkan sesuatu yang berfungsi, saya tidak tahu bagaimana cara agar tag muncul di GitHub (rahasianya adalah --follow-tag).

Pada akhirnya saya membuat dua skrip pendek dan sederhana, dihubungkan di atas, dan itu bekerja dengan baik. Solusinya tidak perlu lebih rumit dari itu!

NateS
sumber
2
Saya menggunakan skrip ini. Setelah sedikit jejak dan kesalahan, itu berhasil untuk saya. Harap diperhatikan bahwa Anda memerlukan Git 1.8.3+ untuk ini, karena --follow-tag hanya didukung setelahnya.
nrobey
2

Saya menggunakan mesin windows dan membuat batch kecil untuk mentransfer repo SVN dengan sejarah (tetapi tanpa cabang) ke repo GIT hanya dengan menelepon

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

Mungkin siapa saja bisa menggunakannya. Itu menciptakan folder TMP memeriksa repo SVN di sana dengan git dan menambahkan asal baru dan mendorongnya ... dan menghapus folder itu lagi.

@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%

Anda masih membutuhkan users.txt dengan pemetaan pengguna seperti

User1 = User One <[email protected]>
cljk
sumber
Jawaban ini membantu saya memindahkan semua repositori saya ke BitBucket tanpa masalah.
Gonzalingui
Senang mendengar. Saya hanya punya pengalaman dengan Gitea ... tapi ditransfer ~~ 40 repos dengan cara ini.
CLJK
Sangat bagus! Thnx
b3wii
peringatan; Saya mengalami masalah charset yang buruk. Saya mengenali ini sangat terlambat, tetapi saya perlu beberapa jam untuk memperbaikinya. Silakan periksa apakah repo yang Anda hasilkan berisi sumber yang diharapkan (!)
cljk
1

Saya hanya ingin menambahkan kontribusi saya ke komunitas Git. Saya menulis skrip bash sederhana yang mengotomatiskan impor penuh. Tidak seperti alat migrasi lainnya, alat ini bergantung pada git asli dan bukan jGit. Alat ini juga mendukung repositori dengan riwayat revisi besar dan atau gumpalan besar. Ini tersedia melalui github:

https://github.com/onepremise/SGMS

Skrip ini akan mengonversi proyek yang disimpan di SVN dengan format berikut:

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

Skema ini juga populer dan didukung:

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

Setiap proyek akan disinkronkan dengan nama proyek:

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

Jika Anda ingin mengonversi repo penuh menjadi lebih, gunakan sintaks berikut:

Ex: ./migration https://svnurl.com/basepath .
Jason Huntley
sumber
0

Efektif menggunakan Git dengan Subversion adalah pengantar lembut untuk git-svn. Untuk repositori SVN yang ada, git-svn membuatnya sangat mudah. Jika Anda memulai repositori baru, jauh lebih mudah untuk membuat repositori SVN kosong dan kemudian mengimpor menggunakan git-svn daripada menuju ke arah yang berlawanan. Membuat repositori Git baru kemudian mengimpor ke SVN dapat dilakukan, tetapi itu sedikit menyakitkan, terutama jika Anda baru mengenal Git dan berharap untuk melestarikan sejarah komit.

burkestar
sumber
0

Unduh pemasang Ruby untuk Windows dan instal versi terbaru dengannya. Tambahkan Ruby yang dapat dieksekusi ke jalur Anda.

  • Instal svn2git
  • Mulai menu -> Semua program -> Ruby -> Mulai prompt perintah dengan Ruby
  • Kemudian ketik "gem install svn2git" dan masukkan

    Migrasikan repositori Subversion

  • Buka prompt perintah Ruby dan buka direktori tempat file akan dimigrasi

    Kemudian svn2git http: // [ nama domain ] / svn / [repositori root]

  • Mungkin butuh beberapa jam untuk memigrasi proyek ke Git tergantung pada ukuran kode proyek.

  • Langkah utama ini membantu dalam membuat struktur repositori Git seperti yang disebutkan di bawah ini.

    Batang SVN (/ Project_components) -> Cabang Git master SVN (/ Project_components) -> Cabang Git Tag SVN (/ Project_components) -> Tag Git

Buat repositori jarak jauh dan dorong perubahan.

Nanda
sumber
0

GitHub memiliki importir. Setelah Anda membuat repositori, Anda dapat mengimpor dari repositori yang ada, melalui URL-nya. Itu akan meminta kredensial Anda jika berlaku dan pergi dari sana.

Saat berjalan, ia akan menemukan penulis, dan Anda bisa memetakannya ke pengguna di GitHub.

Saya telah menggunakannya untuk beberapa repositori sekarang, dan itu cukup akurat dan jauh lebih cepat juga! Butuh 10 menit untuk repositori dengan ~ 4000 komitmen, dan setelah itu butuh teman saya empat hari!

Josh Benson
sumber
0

Beberapa jawaban di sini merujuk ke https://github.com/nirvdrum/svn2git , tetapi untuk repositori besar ini bisa lambat. Saya sudah mencoba menggunakan https://github.com/svn-all-fast-export/svn2git yang merupakan alat dengan nama yang persis sama tetapi digunakan untuk memigrasi KDE dari SVN ke Git.

Sedikit lebih banyak pekerjaan untuk mengaturnya tetapi ketika melakukan konversi itu sendiri bagi saya butuh beberapa menit di mana script lain menghabiskan berjam-jam.

Zitrax
sumber
0

Ada berbagai metode untuk mencapai tujuan ini. Saya sudah mencoba beberapa dari mereka dan menemukan benar-benar bekerja dengan hanya git dan svn diinstal pada OS Windows.

Prasyarat:

  1. git di windows (Saya sudah menggunakan ini) https://git-scm.com/
  2. svn dengan alat konsol diinstal (Saya telah menggunakan tortoise svn)
  3. File Dump dari gudang SVN Anda. svnadmin dump /path/to/repository > repo_name.svn_dump

Langkah-langkah untuk mencapai tujuan akhir (pindahkan semua repositori dengan sejarah ke git, pertama git lokal, lalu jauh)

  1. Buat repositori kosong (menggunakan alat konsol atau tortoiseSVN) di direktori REPO_NAME_FOLDER cd REPO_NAME_PARENT_FOLDER, masukkan dumpfile.dump ke REPO_NAME_PARENT_FOLDER

  2. svnadmin load REPO_NAME_FOLDER < dumpfile.dump Tunggu operasi ini, mungkin lama

  3. Perintah ini diam, jadi buka jendela cmd kedua: svnserve -d -R --root REPO_NAME_FOLDER Mengapa tidak hanya menggunakan file: /// ......? Penyebab perintah berikutnya akan gagal Unable to open ... to URL:, berkat jawaban https://stackoverflow.com/a/6300968/4953065

  4. Buat folder baru SOURCE_GIT_FOLDER

  5. cd SOURCE_GIT_FOLDER
  6. git svn clone svn: // localhost / Tunggu operasi ini.

Akhirnya, apa yang kita dapat?

Mari kita periksa repositori lokal kami:

git log

Lihat komit Anda sebelumnya? Jika ya - baiklah

Jadi sekarang Anda memiliki repositori git lokal yang berfungsi penuh dengan sumber dan riwayat svn lama Anda. Sekarang, jika Anda ingin memindahkannya ke beberapa server, gunakan perintah berikut:

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

Dalam kasus saya, saya tidak perlu perintah tag karena repo saya tidak punya tag.

Semoga berhasil!

Ruslan Makrenko
sumber
0

Mengubah submodule / folder svn 'MyModule' menjadi git dengan histori tanpa tag atau cabang.

Untuk mempertahankan daftar abaikan svn gunakan komentar di atas setelah langkah 1

PShetty
sumber