git-svn: "svn anahtarı - relocate" ile eşdeğer nedir?


89

Git-svn aracılığıyla yansıttığım bir svn deposu URL'yi değiştirdi.

Vanilya svn'de sadece yaparsınız svn switch --relocate old_url_base new_url_base.

Git-svn kullanarak bunu nasıl yapabilirim?

Basitçe yapılandırma dosyasındaki svn url'sini değiştirmek başarısız olur.


Bu cevabı denemeli ve muhtemelen kabul etmelisiniz: stackoverflow.com/a/4061493/1221661
Fritz

En güncel cevap: stackoverflow.com/a/40523789/537554 . Aynı soru, ancak bir Git kullanıcısının bakış açısından soruldu.
ryenus

Yanıtlar:


61

Bu durumumu oldukça iyi idare ediyor:

https://git.wiki.kernel.org/index.php/GitSvnSwitch

file://Protokolü kullanarak klonladım ve protokole geçmek istedim http://.

Bölümündeki urlayarı düzenlemek cazip geliyor , ancak kendi başına bu çalışmıyor. Genel olarak aşağıdaki prosedürü izlemeniz gerekir:[svn-remote "svn"].git/config

  1. Svn-remote urlayarını yeni adla değiştirin.
  2. Çalıştır git svn fetch. Bunun svn'den en az bir yeni revizyon getirmesi gerekiyor!
  3. Svn-remote urlayarını orijinal URL'ye geri değiştirin.
  4. git svn rebase -lYerel bir yeniden temel oluşturmak için çalıştırın (son getirme işlemiyle gelen değişikliklerle).
  5. Svn-remote urlayarını yeni URL ile değiştirin.
  6. Şimdi git svn rebasetekrar çalışmalı.

Maceracı ruhlar denemek isteyebilir --rewrite-root.


2
Adil olmak gerekirse, bu aslında benim için başarısız oldu ve sonunda depoyu yeniden klonladım. Svn dizini yeniden adlandırıldığında git'in bunu işlemesini sağlamak zordur.
Gregg Lind

Daha ayrıntılı bir yazıyı kabul etmeyi tercih ederim, ancak yeterince adil, yeni bir cevap gelene kadar kabul edeceğim.
KCH

2
İşte o prosedürün başka açıklaması aşağıda verilmiştir: theadmin.org/articles/git-svn-switch-to-a-different-a-svn-url
n8gray

kabul edilen yanıtta sağlanan bağlantı güncel değil ve şu an itibariyle yeni olan: git.wiki.kernel.org/articles/g/i/t/GitSvnSwitch_8828.html "Genel Durum" u takip ettim ve basit ve gerçekten iyi çalıştı.
TcMaster

2
@TcMaster: benim için de çalıştı ... ama bu yüzden cevaplar sadece bağlantılar içermemeli , modası geçmiş ve işe yaramaz hale geliyorlar ... Bir topluluk wiki cevabı ekleyeceğim.
UncleZeiv

38

Aşağıdakilerin iyi çalışıp çalışmadığını görebilirsiniz:

  1. Eğer svn-remote.svn.rewriteRootyapar (yapılandırma dosyasında mevcut değil .git/config):

    git config svn-remote.svn.rewriteRoot <currentRepositoryURL>
    
  2. Eğer svn-remote.svn.rewriteUUIDyapar yapılandırma dosyasında mevcut değil:

    git config svn-remote.svn.rewriteUUID <currentRepositoryUUID>
    

    ' currentRepositoryUUIDDan elde edilebilir .git/svn/.metadata.

  3. git config svn-remote.svn.url <newRepositoryURL>


Harika - teşekkürler, bu benim için harika çalıştı (klonlandı file://, geçiş yap svn+ssh); sadece şunu belirtmek gerekir: bu prosedürün "svn'den en az bir yeni revizyon getirmesi" gerekmez; ayrıca ./.git/svn/.metadatailk önce as svn rebaseiçerir - ancak bu anahtarları kaldırmak için yeterli değildir ; bu yüzden anladığım kadarıyla bu anahtarlar kalıcı olarak orada tutulmalı. <newRepository>reposRootrewrite*.git/config
sdaau

1
Benim için de bir cazibe gibi çalıştı. OP bunu denemeli ve doğru cevap olarak almalıdır.
Rafareino

Mükemmel. Tarihte binlerce taahhüt içeren büyük bir projem vardı, bu yüzden yeni bir klon tarihi yok ederdi (ya da kontrol etmek gerçekten uzun zaman alırdı). Ben kullanıyorum svn+ssh://ve bizim svn-sunucu sadece alan adını değiştirdi .seiçin .comiç adlandırmayı arındırılamıyor.
UlfR

Benim için bir muamele yaptı. 1000'lerce taahhüt içeren 2 yıllık bir repo vardı, repo yeni bir ana bilgisayara taşındı, bu yüzden bu (korkunç) tam bir svn klonundan kaçındı.
David Victor

21

Maalesef bu cevaplardaki bağlantıların çoğu çalışmıyor, bu yüzden ileride başvurmak için git wiki'den biraz bilgi kopyalayacağım .

Bu çözüm benim için çalıştı:

  • Düzen svn-remote url(veya fetchiçinde yol) .git/confignoktasına yeni alan / url / yoluna

  • Git çalıştır git svn fetch. Bunun svn'den en az bir yeni revizyon getirmesi gerekiyor!

  • git svn rebaseŞimdi denerseniz , şuna benzer bir hata mesajı alırsınız:

    Unable to determine upstream SVN information from working tree history
    

    Sanırım bunun nedeni git svn, git-svn-idgetirmeden önceki son işleminizin, içinde bulunanla eşleşmeyen eski yolu göstereceği gerçeğiyle karıştırılıyor .git/config.

  • Çözüm olarak, orijinal etki alanına / url'ye / yola geri dönün svn-remote url(veya fetchyolu)

  • Şimdi git svn rebase -l, son getirme işlemiyle gelen değişikliklerle yerel bir yeniden ödeme yapmak için tekrar çalıştırın. Bu sefer olacak çünkü görünüşte işe git svngerçeğiyle rahatsızolmayacaksınız git-svn-idyeni başın içinde bulmuştur eşleşmiyor .git/config.

  • Son olarak, yeni etki alanına / url'ye / yola geri dönün svn-remote url(veya fetchyolu)

  • Bu noktada git svn rebasetekrar çalışmalı!

Orijinal bilgiler burada bulundu .


3

Git svn, büyük ölçüde svn URL'sine güvenir. Svn'den içe aktarılan her kayıt git-svn-id, svn URL'sini içeren bir işleme sahiptir .

Geçerli bir yeniden yerleştirme stratejisi, git-svn cloneyeni depoyu çağırmak ve değişiklikleri bu yeni kapanışla birleştirmektir. Daha ayrıntılı bir prosedür için şu makaleye bakın:

http://www.sanityinc.com/articles/relocating-git-svn-repositories


2

git filter-branch

Bir blog girişinden alınan bu komut dosyası benim için çalıştı. Aynı için olduğu gibi eski ve yeni repo URL'sini parametre olarak sağlayın svn switch --relocate.

Komut dosyası , kaydetme mesajlarındaki git filter-branchSubversion URL'lerini değiştirmeye çağırır git-svn-id, günceller .git/configve ayrıca git-svnbunu kullanarak yeniden oluşturarak meta verileri günceller git svn rebase. git svn cloneDaha sağlam bir çözüm olsa da, bu filter-branchyaklaşım büyük depolar için çok daha hızlı çalışır (saatler vs. günler).

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

1

git_fast_filter

Yine de daha hızlı git-filter-branch(yani, saatler yerine dakikalar), ancak ruh olarak benzer, kullanmaktır git_fast_filter. Bununla birlikte, bu biraz daha fazla kodlama gerektirir ve düzgün, hazır paketlenmiş bir çözüm yoktur. Aksine git-filter-branch, bu bir yaratacak yeni bir gelen repo eski biri. masterSon SVN kaydına işaret ettiği varsayılır .

  1. git_fast_filterGitorious deposundan klon .
  2. Bu Esasagit_fast_filter göre klonladığınız dizinde bir Python betiği oluşturun , çalıştırılabilir biti kullanarak ayarlayın . Eski ve yeni depo yollarını uyarlayın. (Komut dosyasının içeriği de aşağıya yapıştırılmıştır.)chmod +x
  3. Kullanarak yeni bir hedef depoyu başlatın git init, çalışma dizinini bu yeni depo olarak değiştirin.
  4. Aşağıdaki boruyu yürütün:

    (cd path/to/old/repo && git-fast-export --branches --tags --progress=100) | \
        path/to/git_fast_filter/commit_filter.py | git-fast-import
    
  5. Kopyala .git/config.git/infoEski depodan yeni depoya ve belki de diğer ilgili dosyaları .

  6. Kaldırmak .git/svn .
  7. Yapmak git-svnYeni revizyon numarası eşlemesinden haberdar

    1. Yürüt git branch refs/remotes/git-svn master

      • Sizin Git-svn uzaktan kumanda farklı olarak adlandırabileceğimiz refs/remotes/git-svndanışın .git/config,svn-remote section'lardan
    2. Yürüt git svn info . Bu komut donarsa, bir sorun var demektir. Revizyon numarası eşlemesini yeniden oluşturmalıdır.

    3. Sahte dalı kaldırın, refs/remotes/git-svnyeniden yaratılacaktır.git-svn

  8. Arayarak senkronize et git svn rebase .

Aşağıdakilerin içeriği commit_filter.py, değerlerini değiştirin IN_REPOve OUT_REPOuygun şekilde:

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

0

Yukarıdaki git svn rebase -lçözüm benim için işe yaramadı. Farklı bir yoldan gitmeye karar verdim:

  1. Eski SVN deposunu git deposuna oldve yeni SVN'yi git deposuna kopyalayınnew
  2. Getirme oldiçinenew
    • cd new
    • git fetch ../old
    • git tag old FETCH_HEAD
  3. Rebase newüstünde old(kök ağaçları için başarılı olması newve uç oldaynıdır)
    • git checkout master( masterDalın SVN kafasını işaret ettiğini varsayar . Bu, temiz bir klon ile geçerli olacaktır; aksi takdirde başlamadan önce dcommit.)
    • git rebase --root --onto old
  4. Rebase newiçin hesabın git-svn meta verilerini yeniden oluşturun
    • git update-ref --no-deref refs/remotes/git-svn master(uzaktan referansı nasıl klonladığınıza bağlı olarak ayarlayın, örneğin olabilir refs/remotes/svn/trunk)
    • rm -r .git/svn
    • git svn info

1. Yeni konumun yeniye yeni bir klonuyla mı başlıyorsunuz? Cevabınız evet ise, neden o noktada işiniz bitmedi? 2. Yeniyi eskiye yeniden bağlarsanız, eski kayıtlarınızın tümü svn-id commit günlük girişlerinde eski URL’den bahsediyor mu? 3. .git / svn kaldırmak için kaydedilmiş herhangi bir belge var mı? (3b: hangi komut git-svn meta verilerini, git svn bilgisini yeniden oluşturuyor?)
Micha Wiedenmann

0

Bu soruya verilen diğer yanıtlardan bazılarına dayanarak, git-svn yeniden konumlandırmayı işleyen bir Ruby betiği buldum. Bunu https://gist.github.com/henderea/6e779b66be3580c9a584 adresinde bulabilirsiniz .

Başka bir kopyayı teslim almadan yeniden konumlandırmayı gerçekleştirir ve hatta bir veya daha fazla dalda itilmemiş değişikliklerin olduğu durumu da idare eder (çünkü bu normal mantığı bozar). Git filter-branch cevabından (ana mantık için) ve repo'nun bir örneğinden diğerine dalların kopyalanması hakkındaki cevabı (itilmemiş değişikliklerle dalları kopyalamak için) kullanır.

Bunu, iş için sahip olduğum bir sürü git-svn deposunu yeniden konumlandırmak için kullanıyorum ve komut dosyasının bu sürümü (sayısız yinelemeden geçtim) benim için çalışıyor gibi görünüyor. Süper hızlı değil, ancak karşılaştığım tüm vakaları ele alıyor ve tamamen taşınmış bir repo ile sonuçlanıyor gibi görünüyor.

Komut dosyası, herhangi bir değişiklik yapmadan önce deponun bir kopyasını oluşturma seçeneği sunar, böylece bir yedekleme oluşturmak için bu seçeneği kullanabilirsiniz. Herhangi bir dalda aktarılmamış değişiklikleriniz varsa bir kopya oluşturmanız gerekir.

Komut dosyası, normal MRI Ruby kurulumunda yer almayan herhangi bir mücevher veya diğer kitaplıkları kullanmaz. MRI'da bulunan readline ve fileutils kitaplıklarını kullanır.

Umarım senaryom başkası için faydalı olur. Komut dosyası üzerinde değişiklik yapmaktan çekinmeyin.

NOT: Bu betiği yalnızca OS X 10.10 Yosemite üzerinde git 2.3.0 / 2.3.1 ve Ruby 2.2.0 ile test ettim (kullandığım ortam bu olduğundan), ancak diğer ortamlarda da çalışmasını bekliyorum. Yine de Windows konusunda hiçbir garanti yok.

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.