Geçmişi olan bir SVN deposunu yeni bir Git deposuna nasıl taşıyabilirim?


1509

Git kılavuzunu, SSS'yi, Git - SVN çarpışma kursunu vb. Okudum ve hepsi bunu ve bunu açıklıyor, ancak hiçbir yerde aşağıdaki gibi basit bir talimat bulamazsınız:

SVN deposu: svn://myserver/path/to/svn/repos

Git deposu: 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

Bu kadar basit olmasını beklemiyorum ve tek bir komut olmasını beklemiyorum. Ama hiçbir şeyi açıklamaya çalışmamasını bekliyorum - sadece bu örnekte hangi adımları atacağımı söylemek.



Aşağıdaki Casey yanıtını kullanın, ancak "svn clone ..." komutunu çalıştırmadan önce, user.txt dosyanıza fazladan "Visual SVN Server" satırını nasıl ekleyeceğinize bakın ... burada: stackoverflow.com/questions/8971208/ …
MacGyver

1
Ayrıca, GitHub profilinizde "e-postayı özel yap seçeneğini işaretlediyseniz, bunu kullanmak için users.txt içindeki e-posta adresiniz olarak kullanın. Yourgituser@users.noreply.github.com, böylece gerçek e-posta adresiniz görünmez kaydedilmesini üzerinde.
MacGyver

Yanıtlar:


529

Sihirli:

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

Git ve SVN çok farklı çalışır. Git'i öğrenmeniz gerekir ve SVN yukarı akışındaki değişiklikleri izlemek istiyorsanız öğrenmeniz gerekir git-svn. git-svn Ana sayfa iyi örnekler bölümü vardır :

$ git svn --help

140
@Casey'nin cevabı orijinal soruyu çok daha iyi cevaplıyor.
Doug Wilson

3
Bu dalları ve her şeyi tutacak mı? ya da sadece gövdeyi klonla?
Eildosa

7
@Eildosa: Bu sadece bagajı klonlayacak. Alternatif için Casey'nin cevabına bakınız.
sleske

3
@ DoWWilson ama burada Casey'nin cevabını göremiyorum. "Bir kullanıcı dosyası oluştur" ile başlayan 13 yazarlı aşağıdaki cevap mı?
Andrey Regentov

68
Buralarda yorumların sürü başvurulmaktadır "Casey cevabı" hangi merak ediyor başkası için, bu kadar bu bir (Casey cmcginty yaptığı nick değişti).
Stefan Monov

1560

users.txtSVN kullanıcılarını Git ile eşlemek için bir kullanıcı dosyası (ör. ) Oluşturun :

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

Bu tek astarı, mevcut SVN deponuzdan bir şablon oluşturmak için kullanabilirsiniz:

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

SVN, dosyada eksik bir SVN kullanıcısı bulursa duracaktır. Ancak bundan sonra dosyayı güncelleyebilir ve kaldığınız yerden devam edebilirsiniz.

Şimdi SVN verilerini depodan çekin:

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

Bu komut yeni bir Git deposu oluşturur dest_dir-tmpve SVN deposunu çekmeye başlar. "--Stdlayout" bayrağının ortak "trunk /, branch /, tags /" SVN düzenine sahip olduğunuzu ima ettiğini unutmayın. Senin düzen farklıdır, aşina değilse --tags, --branches, --trunkseçenekler (genel olarak git svn help).

Tüm ortak protokoller izin verilir: svn://, http://, https://. URL, http://svn.mycompany.com/myrepo/repository gibi bir temel depoyu hedeflemelidir . URL dizesi gerekir değil dahil /trunk, /tagveya /branches.

Bu komutu yürüttükten sonra genellikle işlemin "asılı / donmuş" gibi göründüğünü ve yeni veri havuzunu başlattıktan sonra uzun süre takılmasının oldukça normal olduğunu unutmayın. Sonunda, taşındığını gösteren günlük mesajları göreceksiniz.

Ayrıca, --no-metadatabayrağı atlarsanız Git'in ilgili SVN düzeltmesi hakkında bilgi tamamlama iletisine ekleyeceğini unutmayın (ör. git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>)

Bir kullanıcı adı bulunamazsa users.txtdosyanızı güncelleyin :

cd dest_dir-tmp
git svn fetch

Büyük bir projeniz varsa, tüm Subversion taahhütleri alınana kadar bu son komutu birkaç kez tekrarlamanız gerekebilir:

git svn fetch

Tamamlandığında Git, SVN'yi trunkyeni bir şubeye teslim eder. Diğer tüm şubeler uzaktan kumanda olarak kurulur. Diğer SVN şubelerini şununla görüntüleyebilirsiniz:

git branch -r

Deponuzda diğer uzak dalları tutmak istiyorsanız, her biri için manuel olarak yerel bir şube oluşturmak istiyorsunuz. (Trunk / master'ı atlayın.) Bunu yapmazsanız, dallar son adımda klonlanmayacaktır.

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

Etiketler dal olarak içe aktarılır. Git'te etiket olarak yerel bir şube oluşturmanız, bir etiket oluşturmanız ve şubeyi silmeniz gerekir. "V1" etiketi ile yapmak için:

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

GIT-SVN veri havuzunuzu temiz bir Git veri havuzuna kopyalayın:

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

Uzak dallardan daha önce oluşturduğunuz yerel dallar, yalnızca yeni klonlanmış depoya uzak dallar olarak kopyalanır. (Trunk / master'ı atla.) Saklamak istediğiniz her dal için:

git checkout -b local_branch origin/remote_branch

Son olarak, uzaktan kumandayı silinmiş geçici depoya işaret eden temiz Git deponuzdan kaldırın:

git remote rm origin

36
Eelke'nin bu blog yazısı yukarıdaki cevap için harika bir çapraz referans. blokspeed.net/blog/2010/09/converting-from-subversion-to-git
kgriffs

4
Bu% 99 harika, bu adımları izleyerek, dallar hariç her şeyi sırayla aldım: son adımdan sonra, sadece uzaktılar (ve komutu verdiğimde kayboldu: git remote rm origin)
Dirty Henry

4
GitHub'da çok kolay bir adım adım vardır: github.com/nirvdrum/svn2git#readme
Dan Nissenbaum

8
Windows altındakiler için, bu yönteme dayalı bir PowerShell betiği oluşturdum: gist.github.com/Gimly/90df046dc38181bb18de
Gimly

5
Çok geçmişi olan büyük depolar için uyarı , bu yavaş ve tedius . Tüm eski dalları taşımaya çalıştım ve sadece gövdeyi taşıdım.
Jess

195

Subversion Deponuzu Temiz Bir Git Deposuna Taşın . Öncelikle Subversion taahhüt yazar adlarınızı Git komiteleriyle eşleyen bir dosya oluşturmanız gerekir ~/authors.txt:

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

Ardından Subversion verilerini bir Git deposuna indirebilirsiniz:

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

Mac kullanıyorsanız, git-svnyükleyerek MacPorts'tan alabilirsiniz git-core +svn.

Subversion deponuz, istediğiniz git deposuyla aynı makinedeyse, init adımı için bu sözdizimini kullanabilirsiniz, aksi takdirde hepsi aynıdır:

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

1
Diğer yanıta yorumladığı gibi, etrafta boşlukları kaldırmak zorunda =içinde users.txtithalat durduruluyor çünkü ben boş depo başlamıştı.
Sebastián Grignoli

8
Ah! Basit ve etkili açıklama. Benim durumumda file:///çalışmayı reddetti, sadece kullandım svnserve.exe --daemonve sonra kullandım svn://localhost/home/user/repo.
Daniel Reis

Mountain Lion çalıştıran Mac bilgisayarımda, git svn, Xcode'a girip Tercihler bölmesinin İndirilenler sekmesinde bulunan Komut Satırı Araçlarını yükleyene kadar çalışmaz. Alternatif olarak, Apple'ın Geliştirici sitesinde bulunan OS X Mountain Lion için yalnızca Komut Satırı Araçlarını yükleyebilirdim.
Drew

3
Benim durumumda ben dosyayı dönüştürmek zorunda authors.txtiçin utf-8 without BOM.
Silvan

Bu benim için harika çalıştı! Yerel depoyu aldıktan sonra, cmcginty'nin "GIT-SVN veri havuzunuzu temiz bir Git deposuna kopyalayın" dan başlayarak kullandım: Sanırım @zoul'un cevabını sevmemin ana nedeni git svn init, git svn configdaha sonra nihayet git svn fetchdaha kolay olduğu bu şekilde yapabilmek için birkaç kez getirmem gerekiyordu. cmcginty'nin üçünü de yapan tek çizgisi git svn clonebenim için çok karışıktı.
mike

70

Svn2git komut dosyasını kullandım ve bir cazibe gibi çalışıyor.


4
S: Bu, etiket ve şube adlarındaki boşlukları düzeltir mi (svn'de izin verilir ve git'te izin verilmez)?
spazm



Cevapları açıklamak tercih edilir, aksi takdirde senaryo çocukları üretiriz.
Josh Habdas

Şubelerinizin tamamı SVN'nin kökenindeyse ve bagajınız veya etiketiniz yoksa ne olacak?
Kal

58

Git-svn'i sürekli kullanmaya çalışmadan önce Git ile rahat olmanızı, yani SVN'yi merkezi repo olarak tutmayı ve Git'i yerel olarak kullanmayı öneririm.

Bununla birlikte, tüm tarihle basit bir geçiş için birkaç basit adım şunlardır:

Yerel repoyu başlatın:

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

Düzeltmeleri içe aktarmaya ne kadar geri başlamak istediğinizi işaretleyin:

git svn fetch -r42

(veya tüm devirler için "git svn fetch")

Aslında o zamandan beri her şeyi getirin:

git svn rebase

İçe aktarmanın sonucunu Gitk ile kontrol edebilirsiniz. Bunun Windows üzerinde çalışıp çalışmadığından emin değilim, OSX ve Linux'ta çalışır:

gitk

SVN deposunuzu yerel olarak klonladığınızda, daha kolay işbirliği için merkezi bir Git deposuna iletmek isteyebilirsiniz.

Önce boş uzak deponuzu oluşturun (belki GitHub'da ?):

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

Ardından, isteğe bağlı olarak ana dalınızı senkronize edin, böylece çekme işlemi, her ikisi de yeni şeyler içerdiğinde uzak ana bilgisayarı yerel ana sisteminizle otomatik olarak birleştirir:

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

Bundan sonra, git_remote_branchuzak dallarla uğraşmaya yardımcı olan kendi aracımı denemek isteyebilirsiniz :

İlk açıklayıcı gönderi: " Git uzak dalları "

En son sürümün takibi: " git_remote_branch ile işbirliği yapma zamanı "


Son derece yararlı, bu mükemmel çalıştı. Uzak bir havuzla senkronize ediyorsanız atılacak son bir adım olduğunu ekleyeceğim. Git yapılandırma adımlarından sonragit push origin master
mag382

31

Subversion'dan Git'e (veya her ikisini aynı anda kullanmak için) sorunsuz geçiş için yeni bir çözüm var: SubGit .

Bu proje üzerinde kendim çalışıyorum. Havuzlarımızda SubGit kullanıyoruz - bazı takım arkadaşlarım Git ve bazı Subversion kullanıyor ve şimdiye kadar çok iyi çalışıyor.

SubGit ile Subversion'dan Git'e geçmek için çalıştırmanız gerekir:

$ subgit install svn_repos
...
TRANSLATION SUCCESSFUL 

Bundan sonra svn_repos / .git içinde Git deposunu alırsınız ve kopyalayabilir veya Subversion ile bu yeni Git deposunu birlikte kullanmaya devam edebilirsiniz: SubGit her ikisinin de her zaman senkronize olmasını sağlar.

Subversion deponuzda birden çok proje varsa, svn_repos / git dizininde birden çok Git deposu oluşturulur. Çeviriyi çalıştırmadan önce özelleştirmek için aşağıdakileri yapın:

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

İle SubGit saf Git (değil git-svn) göç ve ihtiyaç olarak hala (sizin önceden yapılandırılmış yapı araçları için örneğin) sürece Subversion tutarken kullanmaya başlayabilir.

Bu yardımcı olur umarım!


4
Bir kerelik içe aktarma işleminin ( subgit importkomutu kullanarak ) lisans gerektirmediğini unutmayın. svn:ignoreÖzelliğin .gitignoredosyalara doğru çevirisi de dahildir.
krlmlr

1
SubGit özel anahtarımı veya komut satırında ayarladığım bayrakları tanımaz. Dokümantasyon çok zayıf. Bu uygun bir alternatif değil git svn.
pfnuesel

1
hata: 'svn_repos' geçerli bir yapılandırılmış konum değil; SubGit yapılandırma dosyası eksik.
Jon Davis

19

Resmi git-svn kılavuzuna bakınız . Özellikle, "Temel Örnekler" altına bakın:

Subversion tarafından yönetilen tüm bir projeyi izleme ve katkıda bulunma (gövde, etiketler ve şubelerle birlikte):

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

Klon komutunuz işe yaradı, yukarıdaki olanlar bana boş git depolarından başka bir şey vermedi. Tek fark açık '-T bagaj' gibi görünüyor.
user1984717


14

SubGit (Ölümün Mavi Ekranı vs)

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

Hepsi bu.

+ SVN'den güncellemek için, ilk komut tarafından oluşturulan bir Git deposu.

subgit import  directory/path/Local.git.Repo

Büyük bir depo için Git'e anında geçiş yapmanın bir yolunu kullandım.
Tabii ki bazı hazırlıklara ihtiyacınız var.
Ancak geliştirme sürecini hiç durduramazsınız.

İşte benim yolum.

Benim çözümüm şöyle:

  • SVN'yi Git deposuna taşıma
  • Git deposunu takımın geçişine başlamadan hemen önce güncelleyin .

Geçiş, büyük bir SVN deposu için çok zaman alıyor.
Ancak tamamlanan taşıma işleminin yalnızca birkaç saniyede güncellenmesi.

Tabii ki SubGit kullanıyorum anne. git-svn beni Ölümün Mavi Ekranı yapar . Sadece sürekli. Git-svn beni Git'in " dosya adı çok uzun " ölümcül hatasıyla sıkıyor .

ADIMLARI

1. SubGit'i indirin

2. Taşıma ve güncelleme komutlarını hazırlayın.

Diyelim ki Windows için yapıyoruz (Linux'a bağlanmak önemsizdir).
Bir SubGit'in kurulum kutusu dizininde (subgit-2.XX \ bin) iki .bat dosyası oluşturun.

Taşıma için bir dosyanın / komutun içeriği:

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

"Başlat" komutu burada isteğe bağlıdır (Windows). Başlangıçta hataları görmeye izin verir ve SubGit tamamlandıktan sonra bir kabuk açıldı.

Buraya git-svn benzeri ek parametreler ekleyebilirsiniz . SVN yazarlarının e-posta adresinin etki alanını düzeltmek için yalnızca --default-domain myCompanyDomain.com kullanıyorum .
Ben standart SVN deposunun yapısı (gövde / dalları / etiketleri) var ve biz "yazarlar haritalama" ile sorun yoktu. Bu yüzden artık hiçbir şey yapmıyorum.

(Dallar gibi etiketleri taşımak istiyorsanız veya SVN'nizde birden çok dal / etiket klasörü varsa, daha ayrıntılı SubGit yaklaşımını kullanmayı düşünebilirsiniz )

İpucu 1 : İşlerin nasıl kaynadığını hızlı görmek için --minimal-revizyon YourSvnRevNumber kullanın (bir tür hata ayıklama). Çözülmüş yazar adlarını veya e-postalarını görmek özellikle yararlıdır.
Veya geçiş geçmişi derinliğini sınırlamak için.

İpucu 2 : Taşıma kesintiye uğramış olabilir ( Ctrl+C ) ve bir sonraki güncelleme komutu / dosyası çalıştırılarak geri yüklenebilir.
Bunu büyük depolar için tavsiye etmiyorum. "Bellek yetersiz Java + Windows istisnası" aldım.

3. İpucu : Sonuç havuzunuzun bir kopyasını oluşturmak daha iyidir.

Güncelleme için bir dosyanın / komutun içeriği:

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

Git deponuza son takımın taahhütlerini almak istediğiniz zaman bunu çalıştırabilirsiniz.

Uyarı! Çıplak deponuza dokunmayın (örneğin dalların oluşturulması).
Bir sonraki ölümcül hatayı alacaksınız:

Kurtarılamaz hata: senkronize değil ve senkronize edilemiyor ... Subversion revizyonlarını Git taahhütlerine çevirme ...

3. İlk komutu / dosyayı çalıştırın. Büyük bir depo için çok uzun zaman alacaktır. Mütevazı deposum için 30 saat.

Hepsi bu.
Git deponuzu SVN'den istediğiniz zaman ikinci dosyayı / komutu çalıştırarak güncelleyebilirsiniz. Geliştirme ekibinizi Git'e geçirmeden önce.
Sadece saniyeler sürecek.



Bir tane daha yararlı görev var.

Yerel Git veri havuzunuzu uzak bir Git veri havuzuna aktarın

Sizin durumunuz mu? Devam edelim.

  1. Uzaktan kumandalarınızı yapılandırın

Çalıştırmak:

$ git remote add origin url://your/repo.git
  1. Büyük yerel Git deponuzu uzak bir depoya ilk kez göndermeye hazırlanın

Varsayılan olarak Git'in büyük parçalar gönderemez. ölümcül: Uzak uç beklenmedik bir şekilde telefonu kapattı

Bunun için koşalım:

git config --global http.postBuffer 1073741824

524288000 - 500 MB 1073741824 - 1 GB, vb.

Yerel sertifika sorunlarınızı düzeltin . Git sunucunuz bozuk bir sertifika kullanıyorsa.

Sertifikaları devre dışı bıraktım .

Ayrıca Git sunucunuzun düzeltilmesi gereken bir istek miktarı sınırlamaları olabilir .

  1. Tüm taşımayı ekibin uzak Git deposuna aktarın.

Yerel bir Git ile çalıştırın:

git push origin --mirror

( eski Git sürümleri için git push origin '*: *' )

Aşağıdakileri alırsanız: hata: spawn git olamaz: Böyle bir dosya veya dizin yok ... Benim için depomun tamamen yeniden oluşturulması bu hatayı (30 saat) çözer. Sonraki komutları deneyebilirsiniz

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

Veya Git'i yeniden yüklemeyi deneyin ( benim için işe yaramaz ). Veya tüm etiketlerinizden dallar oluşturabilir ve onları itebilirsiniz. Veya, veya, veya ...


10

reposurgeon

Karmaşık vakalar için Eric S. Raymond tarafından reposurgeon tercih edilen araçtır. SVN'ye ek olarak, fast-exportformat ve CVS yoluyla diğer birçok sürüm kontrol sistemini de destekler . Yazar, Emacs ve FreeBSD gibi eski depoların başarılı dönüşümlerini bildiriyor .

Araç, görünüşe göre uzun bir geçmişi olan zor depo düzenleri için bile mükemmel bir dönüşümü (SVN'nin svn:ignoreözelliklerini .gitignoredosyalara dönüştürmek gibi) hedefliyor . Birçok durumda, diğer araçların kullanımı daha kolay olabilir.

reposurgeonKomut satırının belgelerine girmeden önce , dönüşüm sürecini adım adım geçen mükemmel DVCS taşıma kılavuzunu okuduğunuzdan emin olun .



8

Yüklemelisin

git
git-svn

Bu bağlantıdan kopyalandı http://john.albin.net/git/convert-subversion-to-git .

1. Tüm Subversion komisyonlarının bir listesini alın

Subversion, her bir taahhüdün kullanıcı adını listeler. Git'in taahhütlerinin çok daha zengin verileri vardır, ancak en basit haliyle, taahhüt yazarının listelenen bir ad ve e-postaya sahip olması gerekir. Varsayılan olarak git-svn aracı, hem yazar hem de e-posta alanlarında SVN kullanıcı adını listeler. Ancak biraz çalışma ile, tüm SVN kullanıcılarının bir listesini ve karşılık gelen Git adı ve e-postalarının ne olduğunu oluşturabilirsiniz. Bu liste git-svn tarafından düz svn kullanıcı adlarını uygun Git komutlarına dönüştürmek için kullanılabilir.

Yerel Subversion ödemenizin kökünden şu komutu çalıştırın:

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

Bu, tüm günlük mesajlarını alır, kullanıcı adlarını koparır, yinelenen kullanıcı adlarını ortadan kaldırır, kullanıcı adlarını sıralar ve bunları bir "authors-transform.txt" dosyasına yerleştirir. Şimdi dosyadaki her satırı düzenleyin. Örneğin, dönüştürün:

jwilkins = jwilkins <jwilkins>

bunun içine:

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

2. Git-svn kullanarak Subversion deposunu kopyalayın

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

Bu, standart git-svn dönüşümünü gerçekleştirir (1. adımda oluşturduğunuz authors-transform.txt dosyasını kullanarak) ve git deposunu ana dizininizdeki “~ / temp” klasörüne yerleştirir.

3. svn dönüştür: özellikleri .gitignore için yoksay

Svn deponuz svn: ignore özelliklerini kullanıyorsa, bunu kullanarak kolayca .gitignore dosyasına dönüştürebilirsiniz:

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

4. Havuzu bir çıplak git deposuna aktarın

İlk olarak, çıplak bir havuz oluşturun ve varsayılan dalını svn'nin “trunk” dal adıyla eşleştirin.

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

Ardından geçici veri havuzunu yeni çıplak veri havuzuna itin.

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

Artık ~ / temp deposunu güvenle silebilirsiniz.

5. “Trunk” dalını “master” olarak yeniden adlandırın

Ana geliştirme dalınız Subversion'daki adıyla eşleşen “trunk” olarak adlandırılacaktır. Aşağıdakileri kullanarak Git'in standart “ana” dalına yeniden adlandırmak isteyeceksiniz:

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

6. Şubeleri ve etiketleri temizleme

git-svn, tüm Subversions etiketlerini Git'te “tags / name” biçiminde çok kısa dallara dönüştürür. Tüm bu dalları şu kullanarak gerçek Git etiketlerine dönüştürmek istersiniz:

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

Bu adım yazmak biraz zaman alacaktır. :-) Ama endişelenme; unix kabuğunuz git için-her-ref ile başlayan ekstra uzun komut için> ikincil bilgi istemi sağlar.


7

GitHub'ın bir SVN deposundan içe aktarma özelliği var . Yine de hiç denemedim.


3
GitHub'ın şu anki önerisi başka bir cevaptasvn2git önerilen programı kullanmaktır .
ntc2

Şu anda kusursuz bir şekilde iki büyük proje ithal etti. Tüm SVN dalları içe aktarıldı (repo yolunda \ trunk kısmını KULLANMAYIN) unutmayın. Henüz bilmediğim bir şey, Github'un yeni taahhütleri takip edip etmeyeceği.
Fr0sT

7

Sadece git, SVN ve bash kullanarak biraz genişletilmiş yanıt. Bir trunk / branch / tags dizin düzeni ile geleneksel düzeni kullanmayan SVN depoları için adımlar içerir (SVN bu tür bir düzeni uygulamak için kesinlikle hiçbir şey yapmaz).

Öncelikle, katkıda bulunan farklı kişiler için SVN deponuzu taramak ve bir eşleme dosyası için şablon oluşturmak üzere bu bash komut dosyasını kullanın:

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

Bu özellikleri authorskullanarak svn kullanıcı adlarını geliştiricileri tarafından git configözellikleri user.nameve kullanıcı adlarını kullanarak eşlediğiniz bir dosya oluşturmak için kullanın user.email(GitHub gibi bir hizmet için yalnızca eşleşen bir e-postaya sahip olmanın yeterli olduğunu unutmayın).

Daha sonra git svnsvn deposunu bir eşleme havuzuna kopyalayın ve haritalama hakkında bilgi verin:

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

Git svn, var olan her etiket veya dal için her revizyonu ayrı ayrı kontrol edeceğinden, bu inanılmaz derecede uzun sürebilir. (SVN'deki etiketlerin gerçekten dallar olduğuna dikkat edin, bu nedenle Git'te olduğu gibi sonuçlanır). İhtiyacınız olmayan SVN'deki eski etiketleri ve dalları kaldırarak bunu hızlandırabilirsiniz.

Bunu aynı ağdaki bir sunucuda veya aynı sunucuda çalıştırmak da gerçekten hızlandırabilir. Nedense bu süreç kesintiye uğradıktan sonra da Ayrıca, yapabilirsiniz kullanarak sürdürmek

git svn rebase --continue

Birçok durumda burada işiniz bitti. Ancak, SVN deponuzun basitçe SVN'de bir git dalına koymak istediğiniz bir dizine sahip olduğunuz alışılmadık bir düzen varsa, bazı ek adımlar yapabilirsiniz.

En basit olanı, sunucunuzda kurallara uygun yeni bir SVN repo yapmak ve svn copydizininizi gövdeye veya bir şubeye koymak için kullanmaktır . Dizininizin repo köküne kadar tek yolu bu olabilir, en son denediğimde bu git svnsadece bir ödeme yapmayı reddetti.

Bunu git'i kullanarak da yapabilirsiniz. Bunun için git svn clonebir git dalına koymak istediğiniz dizini kullanın.

Koşudan sonra

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

Bunun Git 1.7 veya üstünü gerektirdiğini unutmayın.


Bu bilgiyi şu bağlantıyla birleştirmeyi öneriyorum: sailmaker.co.uk/blog/2013/05/05/…
Joan PS

7

Ben svn etiketlerini git etiketleri ve svn dallarını git dallarına dönüştürme de dahil olmak üzere svn'yi git'e dönüştürmek için adım adım kılavuz ( burada ) yayınladım .

Kısa versiyon:

1) belirli bir revizyon numarasından svn klonu. (revizyon numarası taşımak istediğiniz en eski numara olmalıdır)

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

2) svn verilerini getir. Bu adım en çok zaman alan adımdır.

cd gitreponame
git svn fetch

hatasız bitene kadar git svn getirisini tekrarlayın

3) Master şubeyi güncelleyin

git svn rebase

4) Referansları kopyalayarak svn şubelerinden yerel şubeler oluşturun

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

5) SVN etiketlerini Git Etiketlerine dönüştürün

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) Depoyu github gibi daha iyi bir yere koyun

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

Daha fazla ayrıntı istiyorsanız, benim okuma yazı veya bana sor.


6

git svn cloneKomutları aşağıdaki gibi kullanabiliriz .

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

Yukarıdaki komut SVN taahhütlerinden yazarlar dosyası oluşturur.

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

Yukarıdaki komut SVN projeniz oluşturulduğunda size ilk revizyon numarasını verecektir.

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

Yukarıdaki komut Git deposunu yerel olarak oluşturur.

Sorun, dalları ve etiketleri itmeye dönüştürmemesidir. Bunları manuel olarak yapmanız gerekecek. Aşağıdaki dallar için:

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

Etiketler için:

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

Şimdi master'ı, dalları ve etiketleri uzak git deposuna aktarın.

$ 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 yardımcı programı

svn2git yardımcı programı, dallar ve etiketlerle el ile yapılan çabaları kaldırır.

Komut kullanarak kurun sudo gem install svn2git. Bundan sonra aşağıdaki komutu çalıştırın.

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

Artık dalları, etiketleri listeleyebilir ve kolayca itebilirsiniz.

$ 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 şubeniz ve etiketiniz olduğunu hayal edin, svn2git size çok zaman kazandıracak ve bu yüzden yerel komutlardan daha iyi sevdim. Yerli git svn clonekomuta etrafında güzel bir sarıcı .

Tam bir örnek için blog girişime bakın .




3

SourceTree kullanıyorsanız bunu doğrudan uygulamadan yapabilirsiniz. Dosyaya Git -> Yeni / Klon ardından aşağıdakileri yapın:

  1. Uzak SVN URL'sini "Kaynak Yolu / URL" olarak girin.
  2. İstendiğinde kimlik bilgilerinizi girin.
  3. Yerel klasör konumunu "Hedef yolu" olarak girin.
  4. Bir isim ver.
  5. Gelişmiş seçeneklerde, "Türün yerel deposu oluştur" bölümündeki açılır menüden "Git" i seçin.
  6. İsteğe bağlı olarak kopyalanacak bir düzeltme belirleyebilirsiniz.
  7. Klon'a basın.

Depoyu SourceTree'de açın, taahhüt iletilerinizin de taşındığını göreceksiniz.

Şimdi Depo -> Depo Ayarları'na gidin ve yeni uzak repo ayrıntılarını ekleyin. İsterseniz SVN uzaktan kumandasını silin (Bunu "Yapılandırma Dosyasını Düzenle" seçeneğiyle yaptım.

Hazır olduğunuzda kodu yeni uzak repoya aktarın ve serbestçe kodlayın.


Supereasy ve hızlı teşekkürler!
Rikard

Bu benim için çalıştı, SourceTree ve Stash kullanıyorum.
VK_217

3

GitLab kullanıcıları için, burada SVN'den nasıl taşındığım konusunda bir özet verdim:

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

SVN'den GitLab'a geçiş adımları

Kurmak

  • SVN adresinde barındırılıyor svn.domain.com.au.
  • SVN'ye erişilebilir http(diğer protokoller çalışmalıdır).
  • GitLab şu konumda barındırılmaktadır git.domain.com.au:
    • Ad alanıyla bir grup oluşturulur dev-team.
    • En az bir kullanıcı hesabı oluşturulur, gruba eklenir ve taşıma için kullanılan hesap için bir SSH anahtarı bulunur (test kullanımı ssh git@git.domain.com.au).
    • Proje ad alanında favourite-projectoluşturulur dev-team.
  • Dosya users.txt, formun her satırında bir kullanıcı olan ilgili kullanıcı ayrıntılarını içerir; username = First Last <address@domain.com.au>burada usernameSVN günlüklerinde verilen kullanıcı adıdır. (Ayrıntılar için Referanslar bölümündeki ilk bağlantıya bakın, özellikle Casey kullanıcısı tarafından yanıt).

Sürümler

  • sürüm 1.1.17 (r1128011)
  • git sürüm 1.9.1
  • GitLab sürüm 7.2.1 ff1633f
  • Ubuntu sunucusu 14.04

Komutları

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

Bu kadar! Proje sayfasını GitLab web kullanıcı arayüzüne yeniden yüklediğinizde, şimdi listelenen tüm taahhütleri ve dosyaları göreceksiniz.

notlar

  • Bilinmeyen kullanıcı yoksa, git svn clonekomut, durdurma ve bu durumda, güncellemede olacak users.txt, cd favourite-projectve git svn fetchkaldığı yerden devam edecek.
  • SVN deposu için standart trunk- tags- branchesdüzen gereklidir.
  • Verilen SVN URL git svn clonekomutu hemen yukarıdaki seviyede durur trunk/, tags/ve branches/.
  • git svn cloneKomut üstündeki bazı uyarılar da dahil çıktı, bir sürü üretir; Uyarıları görmezden geldim.

Bu bağlantı soruyu cevaplayabilse de, cevabın temel kısımlarını buraya eklemek ve bağlantıyı referans olarak sağlamak daha iyidir. Bağlantı verilen sayfa değişirse, yalnızca bağlantı yanıtları geçersiz olabilir.
Kara delik

1
Katılmıyorum. Bağlantılı içerik değişebilir ve burada çoğaltılan içerik güncellenmeyecektir ve bu nedenle güncel olmayabilir (ve aslında bu cevabı ilk gönderdiğimden beri değiştiğine inanıyorum). Yönergeler sadece yaptığım bir bağlantı için bazı alakalı bağlamlar içerdiğini söylüyor - asıl soru bağlantı tarafından toptan olarak cevaplandı. Bağlı kaynağın tamamını buraya kopyalamak gerekli veya gerekli değildir. Bunun için reddedildim mi ?!
leftclickben

2

Başka bir kenara, git-svn dcommits ile gitmeye çalışırken git-stash komutu bir nimettir.

Tipik bir süreç:

  1. git repo'yu kur
  2. farklı dosyalar üzerinde biraz çalışma yap
  3. git kullanarak bazı çalışmaları kontrol etmeye karar ver
  4. a karar vermek svn-dcommit
  5. dreaded olsun "kirli bir dizin ile işlenemiyor" hatası.

Çözüm (git 1.5.3+ gerektirir):

git stash; git svn dcommit ; git stash apply

2

İşte bir veya daha fazla SVN deposunu git'e dönüştürecek ve GitHub'a gönderecek bağımlılıkları olmayan basit bir kabuk betiği.

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

Yaklaşık 30 satırlık komut satırında: git SVN kullanarak klonlar, SVN ::. Yoksaymalarından bir .gitignore dosyası oluşturur, çıplak bir git deposuna iter, SVN gövdesini ana olarak yeniden adlandırır, SVN etiketlerini git etiketlerine dönüştürür ve GitHub'a iter etiketleri korurken.

Bir düzine SVN deposunu Google Code'dan GitHub'a taşımak için çok acı çektim. Windows'u kullandığımda yardımcı olmadı. Ruby eski Debian kutumda her türlü kırılmıştı ve Windows üzerinde çalışmasını sağlamak bir şakaydı. Diğer çözümler Cygwin yollarıyla çalışamadı. Çalıştığım bir şey olsa bile, GitHub'da görünecek etiketlerin nasıl alınacağını anlayamadım (sır --follow-tags).

Sonunda yukarıda bağlantılı iki kısa ve basit senaryoyu bir araya getirdim ve harika çalışıyor. Çözümün bundan daha karmaşık olması gerekmez!


2
Bu senaryoyu kullandım. Biraz iz ve hatadan sonra, benim için çalıştı. Bunun için Git 1.8.3+ sürümüne ihtiyacınız olduğunu lütfen unutmayın; çünkü --follow etiketleri yalnızca bundan sonra desteklenir.
nrobey

2

Bir windows makinesindeyim ve geçmişi olan bir SVN deposunu (şubeleri olmayan) bir GIT deposuna aktarmak için küçük bir Toplu İş yaptım

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

Belki herkes kullanabilir. Bir TMP klasörü oluşturur, orada SVN deposunu git ile denetler ve yeni kaynağı ekler ve iter ... ve klasörü tekrar siler.

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

Hâlâ kullanıcı eşlemelerinizle users.txt dosyasına ihtiyacınız var

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

Bu cevap tüm depolarımı BitBucket'e sorunsuzca taşımama yardımcı oldu.
Gonzalingui

Duyduğuma sevindim. Gitea ile sadece deneyimim vardı ... ama ~ depoları bu şekilde aktardı ~~ 40.
cljk

Çok hoş! Thnx
b3wii

uyarı; Kötü karakter sorunları yaşadım. Bunu gerçekten çok geç fark ettim ama tamir etmek birkaç saat sürdü. Lütfen ortaya çıkan
repo'nun

1

Sadece Git topluluğuna katkımı eklemek istedim. Tam içe aktarmayı otomatikleştiren basit bir bash betiği yazdım. Diğer taşıma araçlarının aksine, bu araç jGit yerine native git'e dayanır. Bu araç ayrıca büyük bir düzeltme geçmişine ve / veya büyük lekelere sahip depoları da destekler. Github aracılığıyla kullanılabilir:

https://github.com/onepremise/SGMS

Bu komut dosyası, SVN'de depolanan projeleri aşağıdaki biçimde dönüştürür:

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

Bu şema da popüler ve destekleniyor:

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

Her proje, proje adıyla senkronize edilir:

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

Reponun tamamını dönüştürmek isterseniz, aşağıdaki sözdizimini kullanın:

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

0

Git'i Subversion ile etkili bir şekilde kullanmak git-svn için nazik bir giriş. Mevcut SVN depoları için git-svn bunu süper kolaylaştırır. Yeni bir depoya başlıyorsanız, önce boş bir SVN deposu oluşturmak ve sonra git-svn kullanarak ters yöne gitmekten almak çok daha kolaydır. Yeni bir Git deposu oluşturmak ve ardından SVN'ye aktarmak yapılabilir, ancak özellikle Git'te yeniyseniz ve işlem geçmişini korumayı umuyorsanız, biraz acı vericidir.


0

Windows için Ruby yükleyicisini indirin ve onunla en son sürümü yükleyin. Yolunuza Ruby yürütülebilir dosyaları ekleyin.

  • Svn2git yükleyin
  • Başlat menüsü -> Tüm programlar -> Ruby -> Ruby ile komut istemi başlatma
  • Sonra “gem install svn2git” yazın ve

    Subversion deposunu geçirme

  • Bir Ruby komut istemi açın ve dosyaların taşınacağı dizine gidin

    Sonra svn2git http: // [etki alanı adı] / svn / [depo kökü]

  • Projenin Git'e taşınması birkaç saat sürebilir, proje kodu boyutuna bağlıdır.

  • Bu büyük adım, aşağıda belirtildiği gibi Git depo yapısının oluşturulmasına yardımcı olur.

    SVN (/ Project_components) trunk -> Git ana SVN (/ Project_components) dalları -> Git dalları SVN (/ Project_components) etiketleri -> Git etiketleri

Uzak deposu oluşturun ve değişiklikleri itin.


0

GitHub'ın bir ithalatçısı var. Havuzu oluşturduktan sonra URL'sini kullanarak mevcut bir havuzdan içe aktarabilirsiniz. Varsa, kimlik bilgilerinizi isteyecek ve oradan gidecektir.

Çalışırken yazarları bulacak ve onları GitHub'daki kullanıcılarla eşleştirebilirsiniz.

Şimdi birkaç depo için kullandım ve oldukça doğru ve çok daha hızlı! ~ 4000 taahhüt içeren bir depo için 10 dakika sürdü ve arkadaşım dört gün sürdükten sonra!



0

Bu hedefe ulaşmak için farklı yöntemler vardır. Bazılarını denedim ve Windows işletim sisteminde yüklü sadece git ve svn ile gerçekten çalışan bir tane buldum.

Ön şartlar:

  1. Windows'ta git (bunu kullandım) https://git-scm.com/
  2. Konsol araçları yüklü svn (Ben kaplumbağa svn kullandım)
  3. SVN veri havuzunuzun döküm dosyası. svnadmin dump /path/to/repository > repo_name.svn_dump

Nihai hedefe ulaşmak için adımlar (geçmişe sahip tüm veri havuzunu bir git'e, önce yerel git'e, ardından uzaktan kumandaya taşıyın)

  1. REPO_NAME_FOLDER dizininde boş depo oluşturun (konsol araçlarını veya kaplumbağaSVN'yi kullanarak) cd REPO_NAME_PARENT_FOLDER, dumpfile.dump dosyasını REPO_NAME_PARENT_FOLDER klasörüne yerleştirin

  2. svnadmin load REPO_NAME_FOLDER < dumpfile.dump Bu işlemi bekleyin, uzun olabilir

  3. Bu komut sessizdir, bu yüzden ikinci cmd penceresini açın: svnserve -d -R --root REPO_NAME_FOLDER Neden sadece /// ...... dosyasını kullanmıyorsunuz? Çünkü https://stackoverflow.com/a/6300968/4953065Unable to open ... to URL: yanıtı sayesinde bir sonraki komut başarısız olacak

  4. Yeni klasör oluştur SOURCE_GIT_FOLDER

  5. cd SOURCE_GIT_FOLDER
  6. git svn clone svn: // localhost / Bu işlemi bekleyin.

Sonunda, elimizde ne var?

Yerel depomuzu kontrol edelim:

git log

Önceki taahhütlerinizi gördünüz mü? Evet ise - tamam

Artık kaynaklarınız ve eski svn geçmişinizle tamamen işlevsel yerel git deponuz var. Şimdi, onu bir sunucuya taşımak istiyorsanız, aşağıdaki komutları kullanın:

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

Benim durumumda, etiketlerim komutuna sahip olmadığım için etiketler komutuna ihtiyacım yok.

İyi şanslar!


0

Svn alt modülünü / klasörü 'MyModule' etiketsiz veya dalsız geçmişle git'e dönüştürme.

Svn yoksay listesini tutmak için 1. adımdan sonra yukarıdaki yorumları kullanın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.