Repositori svn yang saya tiru melalui git-svn telah mengubah URL.
Di vanilla svn yang baru saja Anda lakukan svn switch --relocate old_url_base new_url_base
.
Bagaimana saya bisa melakukan ini menggunakan git-svn?
Cukup mengubah url svn di file konfigurasi gagal.
Jawaban:
Ini menangani situasi saya dengan cukup baik:
https://git.wiki.kernel.org/index.php/GitSvnSwitch
Saya mengkloning menggunakan
file://
protokol, dan ingin beralih kehttp://
protokol.Anda tergoda untuk mengedit
url
pengaturan di[svn-remote "svn"]
bagian.git/config
, tapi ini tidak berhasil. Secara umum, Anda perlu mengikuti prosedur berikut:url
pengaturan remote-svn ke nama baru.git svn fetch
. Ini perlu mengambil setidaknya satu revisi baru dari svn!url
kembali ke URL asli.git svn rebase -l
untuk melakukan rebase lokal (dengan perubahan yang datang dengan operasi pengambilan terakhir).url
kembali ke URL baru.git svn rebase
harus bekerja lagi.Jiwa petualang mungkin ingin mencoba
--rewrite-root
.sumber
Anda dapat melihat apakah berikut ini berfungsi dengan baik:
Jika
svn-remote.svn.rewriteRoot
tidak ada di file config (.git/config
):Jika
svn-remote.svn.rewriteUUID
tidak ada di file konfigurasi:The
currentRepositoryUUID
dapat diperoleh dari.git/svn/.metadata
.git config svn-remote.svn.url <newRepositoryURL>
sumber
file://
, beralih kesvn+ssh
); hanya mencatat bahwa: prosedur ini tidak perlu "mengambil setidaknya satu revisi baru dari svn"; juga./.git/svn/.metadata
setelah yang pertamasvn rebase
berisi<newRepository>
asreposRoot
- tetapi ini tidak cukup untuk menghapusrewrite*
kunci dari.git/config
; jadi kunci-kunci itu harus disimpan secara permanen di sana, sejauh yang saya mengerti.svn+ssh://
dan svn-server kami baru saja mengubah domain dari.se
menjadi.com
untuk membersihkan penamaan internal kami.Sayangnya sebagian besar tautan di jawaban ini tidak berfungsi, jadi saya akan menduplikasi sedikit informasi dari git wiki untuk referensi di masa mendatang.
Solusi ini berhasil untuk saya:
Edit
svn-remote
url
(ataufetch
jalur) di.git/config
untuk mengarah ke domain / url / jalur baruJalankan git
git svn fetch
. Ini perlu mengambil setidaknya satu revisi baru dari svn!Jika Anda mencoba
git svn rebase
sekarang, Anda akan mendapatkan pesan kesalahan seperti ini:Saya rasa ini karena
git svn
dibingungkan oleh fakta bahwa komit terbaru Anda sebelum pengambilan akangit-svn-id
mengarah ke jalur lama, yang tidak cocok dengan yang ditemukan di.git/config
.Sebagai solusinya, ubah
svn-remote
url
(ataufetch
jalur) kembali ke domain / url / jalur asliSekarang jalankan
git svn rebase -l
lagi untuk melakukan rebase lokal dengan perubahan yang datang dengan operasi pengambilan terakhir. Kali ini akan berhasil, tampaknya karenagit svn
tidak akan bingung dengan fakta bahwagit-svn-id
kepala baru tidak cocok dengan yang ditemukan di.git/config
.Terakhir, ubah
svn-remote
url
(ataufetch
jalur) kembali ke domain / url / jalur baruPada titik ini
git svn rebase
harus bekerja lagi!Informasi asli ditemukan di sini .
sumber
Git svn sangat bergantung pada URL svn. Setiap komit yang diimpor dari svn memiliki
git-svn-id
yang menyertakan URL svn.Strategi relokasi yang valid adalah memanggil
git-svn clone
repositori baru dan menggabungkan perubahan ke penutupan baru itu. Untuk prosedur yang lebih detail, lihat artikel ini:http://www.sanityinc.com/articles/relocating-git-svn-repositories
sumber
git filter-branch
Skrip ini , diambil dari entri blog , telah berhasil untuk saya. Berikan URL repo lama dan baru sebagai parameter, seperti untuk
svn switch --relocate
.Skrip memanggil
git filter-branch
untuk menggantikan URL Subversion digit-svn-id
dalam pesan komit, pembaruan.git/config
, dan juga memperbaruigit-svn
metadata dengan membuat ulang menggunakangit svn rebase
. Meskipungit svn clone
mungkin merupakan solusi yang lebih kuat,filter-branch
pendekatan ini bekerja lebih cepat untuk repositori besar (jam vs. hari).#!/bin/sh # Must be called with two command-line args. # Example: git-svn-relocate.sh http://old.server https://new.server if [ $# -ne 2 ] then echo "Please invoke this script with two command-line arguments (old and new SVN URLs)." exit $E_NO_ARGS fi # Prepare URLs for regex search and replace. oldUrl=`echo $1 | awk '{gsub("[\\\.]", "\\\\\\\&");print}'` newUrl=`echo $2 | awk '{gsub("[\\\&]", "\\\\\\\&");print}'` filter="sed \"s|^git-svn-id: $oldUrl|git-svn-id: $newUrl|g\"" git filter-branch --msg-filter "$filter" -- --all sed -i.backup -e "s|$oldUrl|$newUrl|g" .git/config rm -rf .git/svn git svn rebase
sumber
git_fast_filter
Namun lebih cepat dari
git-filter-branch
(yaitu, menit, bukan jam), tetapi serupa dalam semangat, adalah menggunakangit_fast_filter
. Namun, ini membutuhkan sedikit lebih banyak pengkodean, dan tidak ada solusi siap pakai yang rapi. Berbeda dengangit-filter-branch
, ini akan membuat repo baru dari yang lama . Diasumsikan bahwamaster
menunjuk ke komit SVN terakhir.git_fast_filter
dari repo Gitorious.git_fast_filter
berdasarkan Gist ini , setel bit yang dapat dieksekusi menggunakanchmod +x
. Sesuaikan jalur repositori lama dan baru. (Isi skrip juga ditempel di bawah.)git init
, ubah direktori kerja ke repo baru ini.Jalankan pipa berikut:
Salin
.git/config
, dan mungkin file lain yang relevan.git/info
dari repo lama ke repo baru..git/svn
.Membuat
git-svn
menyadari pemetaan angka revisi baruMenjalankan
git branch refs/remotes/git-svn master
refs/remotes/git-svn
, berkonsultasi.git/config
,svn-remote
bagianJalankan
git svn info
. Jika perintah ini macet, ada yang salah. Ini harus membangun kembali pemetaan nomor revisi.Hapus cabang palsu
refs/remotes/git-svn
, itu akan dibuat ulang olehgit-svn
git svn rebase
.Di bawah ini adalah isi
commit_filter.py
, ganti nilaiIN_REPO
dan yangOUT_REPO
sesuai:#!/usr/bin/python from git_fast_filter import Commit, FastExportFilter import re import sys IN_REPO = "https://svn.code.sf.net/p/matsim/code" OUT_REPO = "https://svn.code.sf.net/p/matsim/source" IN_REPO_RE = re.compile("^git-svn-id: %s" % re.escape(IN_REPO), re.M) OUT_REPO_RE = "git-svn-id: %s" % OUT_REPO def my_commit_callback(commit): commit.message = IN_REPO_RE.sub(OUT_REPO_RE, commit.message) sys.stderr.write(".") filter = FastExportFilter(commit_callback = my_commit_callback) filter.run()
sumber
git svn rebase -l
Solusi di atas tidak berhasil untuk saya. Saya memutuskan untuk melakukannya dengan cara yang berbeda:old
dan SVN baru ke dalam git reponew
old
kenew
cd new
git fetch ../old
git tag old FETCH_HEAD
new
di atasold
(semestinya berhasil karena pohon di akarnew
dan ujungnyaold
identik)git checkout master
(Asumsikan bahwamaster
cabang menunjuk ke kepala SVN. Ini akan menjadi kasus dengan klon bersih; jika tidak lakukan sebelum Anda memulai.)git rebase --root --onto old
new
untuk memperhitungkan rebasegit update-ref --no-deref refs/remotes/git-svn master
(sesuaikan referensi jarak jauh tergantung pada bagaimana Anda mengkloning, misalnya bisa jadirefs/remotes/svn/trunk
)rm -r .git/svn
git svn info
sumber
Berdasarkan beberapa tanggapan lain untuk pertanyaan ini, saya telah menemukan skrip Ruby yang menangani relokasi git-svn. Anda dapat menemukannya di https://gist.github.com/henderea/6e779b66be3580c9a584 .
Ini menangani relokasi tanpa memeriksa salinan lain, dan bahkan menangani kasus di mana ada perubahan yang tidak didorong di satu atau lebih cabang (karena itu merusak logika reguler). Ini menggunakan hal-hal dari jawaban git filter-branch (untuk logika utama) dan jawaban tentang menyalin cabang dari satu contoh repo ke yang lain (untuk menyalin cabang dengan perubahan yang tidak didorong).
Saya telah menggunakan ini untuk merelokasi sekelompok repo git-svn yang saya miliki untuk bekerja, dan versi skrip ini (saya telah melalui iterasi yang tak terhitung jumlahnya) tampaknya berhasil untuk saya. Ini tidak super cepat, tetapi tampaknya menangani semua kasus yang saya temui dan menghasilkan repo yang sepenuhnya dipindahkan.
Skrip memberi Anda opsi untuk membuat salinan repo sebelum membuat perubahan apa pun, sehingga Anda dapat menggunakan opsi ini untuk membuat cadangan. Membuat salinan diperlukan jika Anda memiliki perubahan yang tidak didorong di cabang mana pun.
Skrip tidak menggunakan permata atau pustaka lain yang tidak termasuk dalam instalasi normal MRI Ruby. Itu menggunakan library readline dan fileutils yang disertakan dalam MRI.
Semoga naskah saya terbukti bermanfaat bagi orang lain. Jangan ragu untuk melakukan perubahan pada skrip.
CATATAN: Saya hanya menguji skrip ini dengan git 2.3.0 / 2.3.1 dan Ruby 2.2.0 di OS X 10.10 Yosemite (karena itulah lingkungan yang saya gunakan), tetapi saya berharap ini juga berfungsi di lingkungan lain. Tidak ada jaminan tentang Windows.
sumber