git-svn: `svn स्विच --relocate` के बराबर क्या है?


88

एक svn रिपॉजिटरी मैं git-svn के माध्यम से प्रतिबिंबित कर रहा हूँ URL बदल दिया है।

वेनिला svn में आप बस करेंगे svn switch --relocate old_url_base new_url_base

मैं git-svn का उपयोग कैसे कर सकता हूं?

बस config फाइल में svn url को बदलना विफल रहता है।


आपको कोशिश करनी चाहिए और संभवतः इस उत्तर को स्वीकार करना चाहिए: stackoverflow.com/a/4061493/1221661
Fritz

अधिकांश तिथि तक उत्तर: stackoverflow.com/a/40523789/537554 । एक ही सवाल है, लेकिन एक उपयोगकर्ता के दृष्टिकोण से पूछा।
रीनस

जवाबों:


61

यह मेरी स्थिति को बहुत अच्छी तरह से संभालता है:

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

मैंने file://प्रोटोकॉल का उपयोग करके क्लोन किया , और प्रोटोकॉल पर स्विच करना चाहता था http://

यह urlके [svn-remote "svn"]अनुभाग में सेटिंग को संपादित करने के लिए आकर्षक है .git/config, लेकिन अपने दम पर यह काम नहीं करता है। सामान्य तौर पर आपको निम्नलिखित प्रक्रिया का पालन करने की आवश्यकता है:

  1. urlनए नाम पर svn- रिमोट सेटिंग को स्विच करें।
  2. भागो git svn fetch। यह svn से कम से कम एक नया संशोधन लाने की जरूरत है!
  3. urlमूल URL पर वापस svn- रिमोट सेटिंग बदलें ।
  4. Daud git svn rebase -lएक स्थानीय रीबेस करने के लिए (उन परिवर्तनों के साथ जो अंतिम भ्रूण ऑपरेशन के साथ आए थे)।
  5. urlनए URL पर वापस svn-Remote सेटिंग बदलें ।
  6. अब, git svn rebaseफिर से काम करना चाहिए।

साहसी आत्माएं कोशिश करना चाह सकती हैं --rewrite-root


2
निष्पक्ष होना, यह वास्तव में मेरे लिए विफल रहा, और मैंने रेपो का पुन: क्लोनिंग किया। जब एसवीएन निर्देशिका का नाम बदला जाता है, तो इसे संभालना मुश्किल होता है।
ग्रेग लिंड

मैं एक अधिक विस्तृत लेखन को स्वीकार करना पसंद करूंगा, लेकिन पर्याप्त रूप से, मैं इसे स्वीकार करूंगा जब तक कि एक नया जवाब नहीं आता।
kch

2
यहाँ उस प्रक्रिया का एक और विवरण दिया गया है: theadmin.org/articles/git-svn-switch-to-a-different-a-svn-url
n8gray

स्वीकृत उत्तर में दिया गया लिंक पुराना है और अब तक का नया है: git.wiki.kernel.org/articles/g/i/t/GitSvnSwitch_8828.html मैंने "सामान्य मामला" का पालन किया और यह सरल और वास्तव में था। ठीक काम किया।
टीसीमास्टर

2
@ टीसीमास्टर: मेरे लिए भी काम किया ... लेकिन इसीलिए जवाबों में केवल लिंक नहीं होने चाहिए , वे पुराने हो गए और बेकार हो गए ... मैं एक सामुदायिक विकि उत्तर जोड़ने जा रहा हूं।
अंकलजीव

37

आप देख सकते हैं कि निम्नलिखित ठीक काम करता है:

  1. यदि svn-remote.svn.rewriteRootकॉन्फ़िगरेशन फ़ाइल में मौजूद नहीं है ( .git/config):

    git config svn-remote.svn.rewriteRoot <currentRepositoryURL>
    
  2. यदि svn-remote.svn.rewriteUUIDकॉन्फ़िगरेशन फ़ाइल में मौजूद नहीं है:

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

    currentRepositoryUUIDसे प्राप्त किया जा सकता .git/svn/.metadata

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


शानदार - धन्यवाद, यह मेरे लिए बहुत अच्छा काम किया (क्लोन के माध्यम से file://, स्विच करने के लिए svn+ssh); बस यह देखते हुए: इस प्रक्रिया को "svn से कम से कम एक नया संशोधन लाने की आवश्यकता नहीं है"; के ./.git/svn/.metadataबाद भी पहले svn rebaseके <newRepository>रूप में होता है reposRoot- लेकिन यह rewrite*कुंजी को हटाने के लिए पर्याप्त नहीं है .git/config; इस प्रकार उन चाबियों को स्थायी रूप से वहां रखा जाना चाहिए, जहां तक ​​मैं इसे समझता हूं।
सादाउ

1
यह मेरे लिए भी एक आकर्षण की तरह काम करता था। ओपी को यह प्रयास करना चाहिए और इसे सही उत्तर के रूप में प्राप्त करना चाहिए।
रफारेनो

उत्तम। मेरे पास इतिहास में हजारों कमिट्स के साथ एक बड़ी परियोजना थी इसलिए एक नए क्लोन ने इतिहास को नष्ट कर दिया (या चेकआउट करने के लिए वास्तव में लंबा समय लगेगा)। मैं उपयोग कर रहा हूं svn+ssh://और हमारे svn-server ने डोमेन को हमारे आंतरिक नामकरण को साफ .seकरने के .comलिए बदल दिया है ।
उल्फार

मेरे लिए एक इलाज का काम किया। 1,000 वर्ष के साथ 2 साल पुराना रेपो था, रेपो को एक नए मेजबान में स्थानांतरित कर दिया गया था, इसलिए इसने (खूंखार) पूर्ण स्वॉन क्लोन से बचा लिया।
डेविड विक्टर

21

दुर्भाग्य से इन उत्तरों में से अधिकांश लिंक काम नहीं कर रहे हैं, इसलिए मैं भविष्य के संदर्भ के लिए गिट विकी से थोड़ी जानकारी की नकल करने जा रहा हूं ।

इस समाधान ने मेरे लिए काम किया:

  • नए डोमेन / url / पथ को इंगित करने के लिए svn-remote url(या fetchपथ) संपादित करें.git/config

  • भागो जी git svn fetchयह svn से कम से कम एक नया संशोधन लाने की जरूरत है!

  • यदि आप git svn rebaseअभी प्रयास करते हैं, तो आपको इस तरह एक त्रुटि संदेश मिलेगा:

    Unable to determine upstream SVN information from working tree history
    

    मुझे लगता है कि यह इस git svnतथ्य से उलझन में है कि लाने से पहले आपकी नवीनतम प्रतिबद्धता git-svn-idपुराने पथ की ओर इशारा करती है, जो कि इसमें पाए गए से मेल नहीं खाती है .git/config

  • वर्कअराउंड के रूप में, मूल डोमेन / यूआरएल / पथ पर वापस svn-remote url(या fetchपथ) बदलें

  • अब git svn rebase -lफिर से लाएं और अंतिम भ्रूण ऑपरेशन के साथ आए परिवर्तनों के साथ एक स्थानीय रीबेस करने के लिए चलाएं । इस बार यह काम करेगा , जाहिरा तौर पर क्योंकि git svnयह इस तथ्य से भ्रमित नहीं होगा कि git-svn-idनए सिर का उस के साथ मेल नहीं खाता है .git/config

  • अंत में, नए डोमेन / यूआरएल / पथ पर वापस svn-remote url(या fetchपथ) बदलें

  • इस बिंदु पर git svn rebaseफिर से काम करना चाहिए!

मूल जानकारी यहां मिली थी ।


3

Git svn svn URL पर बहुत निर्भर करता है। Svn से आयात होने वाले प्रत्येक वचन git-svn-idमें svn URL शामिल होता है।

एक मान्य रिलोकेशन रणनीति git-svn cloneनई रिपॉजिटरी पर कॉल करने और उस नए क्लोज़ पर परिवर्तनों को मर्ज करने की है। अधिक विस्तृत प्रक्रिया के लिए, इस लेख को देखें:

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


2

git filter-branch

एक ब्लॉग प्रविष्टि से ली गई इस स्क्रिप्ट ने मेरे लिए काम किया है। पुराने और नए रेपो URL को पैरामीटर की तरह आपूर्ति करें, जैसे कि svn switch --relocate

स्क्रिप्ट कमिट मैसेज, अपडेट्स git filter-branchमें सबवर्सन URL को बदलने के लिए कॉल करती है , और मेटाडेटा को अपडेट करके इसे फिर से उपयोग करके अपडेट भी करती है । जबकि अधिक मजबूत समाधान हो सकता है, दृष्टिकोण विशाल रिपॉजिटरी (घंटे बनाम दिन) के लिए बहुत तेजी से काम करता है।git-svn-id.git/configgit-svngit svn rebasegit svn clonefilter-branch

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

फिर भी तेजी से git-filter-branch(यानी, घंटों के बजाय मिनट), लेकिन आत्मा में समान, का उपयोग करना है git_fast_filter। हालाँकि, इसके लिए थोड़ी अधिक कोडिंग की आवश्यकता होती है, और कोई भी साफ-सुथरा पैक तैयार नहीं होता है। इसके विपरीत git-filter-branch, यह एक पुराने से एक नया रेपो बनाएगा । यह माना जाता है कि अंतिम एसवीएन कमिट की ओर इशारा करता है।master

  1. git_fast_filterGitorious रेपो से क्लोन ।
  2. एक ही निर्देशिका में एक पायथन स्क्रिप्ट बनाएं जहां आपने इस Gist केgit_fast_filter आधार पर क्लोन किया था, निष्पादन योग्य बिट का उपयोग करके सेट करें । पुराने और नए रिपॉजिटरी रास्तों को अपनाएं। (स्क्रिप्ट की सामग्री नीचे भी चिपकाई गई है।)chmod +x
  3. एक नया लक्ष्य रिपॉजिटरी का उपयोग करके आरंभ करें git init, कार्य निर्देशिका को इस नए रेपो में बदलें।
  4. निम्नलिखित पाइप निष्पादित करें:

    (cd path/to/old/repo && git-fast-export --branches --tags --progress=100) | \
        path/to/git_fast_filter/commit_filter.py | git-fast-import
    
  5. कॉपी .git/config, और शायद अन्य प्रासंगिक फाइलों में.git/infoपुराने रेपो से लेकर नए रेपो तक की ।

  6. हटा दें .git/svn
  7. git-svnनए संशोधन संख्या मानचित्रण के बारे में पता करें

    1. निष्पादित git branch refs/remotes/git-svn master

      • आपके git-svn remotes से अलग refs/remotes/git-svn, परामर्श .git/config, svn-remoteअनुभाग कहे जा सकते हैं
    2. निष्पादित करें git svn info। यदि यह आदेश जमा करता है, तो कुछ गलत है। इसे रिविजन नंबर मैपिंग को फिर से बनाना चाहिए।

    3. नकली शाखा निकालें refs/remotes/git-svn, इसे फिर से बनाया जाएगाgit-svn

  8. कॉल करके सिंक्रनाइज़ करें git svn rebase

नीचे सामग्री दी गई है commit_filter.py, के मानों को बदलें IN_REPOऔर OUT_REPOउचित रूप में:

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

उपरोक्त git svn rebase -lसमाधान मेरे लिए काम नहीं किया। मैंने इसके बारे में एक अलग तरीके से जाने का फैसला किया:

  1. पुराने एसवीएन रेपो को गिट रेपो में oldऔर नए एसवीएन को गिट रेपो में क्लोन करेंnew
  2. लायें oldमेंnew
    • cd new
    • git fetch ../old
    • git tag old FETCH_HEAD
  3. के newशीर्ष पर रिबेस करें old(सफल होना चाहिए क्योंकि जड़ newऔर टिप के पेड़ oldसमान हैं)
    • git checkout master(मान लिया गया कि masterशाखा एसवीएन प्रमुख की ओर इशारा कर रही है। यह एक साफ क्लोन के साथ मामला होगा।
    • git rebase --root --onto old
  4. की Git-SVN मेटाडाटा पुनर्निर्माण newरिबेस के लिए खाते में
    • git update-ref --no-deref refs/remotes/git-svn master(आप कैसे क्लोन किया जा सकता है, इसके आधार पर दूरस्थ रेफरी को समायोजित करें refs/remotes/svn/trunk)
    • rm -r .git/svn
    • git svn info

1. क्या आप नए स्थान के नए क्लोन के साथ नई शुरुआत करते हैं? यदि हाँ, तो उस बिंदु पर क्यों नहीं किया गया? 2. यदि आप पुराने पर नए रीबेज़ करते हैं, तो क्या आपके पुराने सभी पुराने URL का उल्लेख उनके svn-id कमिट लॉग एंट्री में करते हैं? 3. क्या कोई दस्तावेज है जो इसे हटाने के लिए बचा है। (3 बी: कौन सी कमान git-svn मेटाडाटा, git svn जानकारी का पुनर्निर्माण कर रही है?)
Micha Wiedenmann

0

इस सवाल के कुछ अन्य जवाबों के आधार पर, मैं रूबी स्क्रिप्ट के साथ आया हूं जो गिट-स्वॉन को स्थानांतरित करने का काम संभालती है। आप इसे https://gist.github.com/henderea/6e779b66be3580c9a584 पर पा सकते हैं ।

यह दूसरी कॉपी को चेक किए बिना रिलॉकेट को हैंडल करता है, और यह उस केस को भी हैंडल करता है, जहां एक या एक से अधिक ब्रांच में अन-पुश किए गए बदलाव होते हैं (क्योंकि वह रेगुलर लॉजिक को तोड़ता है)। यह git फ़िल्टर-शाखा उत्तर (मुख्य तर्क के लिए) और रेपो के एक उदाहरण से दूसरे में शाखाओं की प्रतिलिपि बनाने के बारे में उत्तर का उपयोग करता है (बिना-पुश किए गए शाखाओं के साथ शाखाओं की प्रतिलिपि बनाने के लिए)।

मैं इसे git-svn repos का एक गुच्छा स्थानांतरित करने के लिए उपयोग कर रहा हूं जो मेरे पास काम के लिए है, और स्क्रिप्ट का यह संस्करण (मैं अनगिनत पुनरावृत्तियों के माध्यम से रहा हूं) मेरे लिए काम करने लगता है। यह सुपर-फास्ट नहीं है, लेकिन यह मेरे द्वारा सामना किए गए सभी मामलों को संभालने के लिए लगता है और परिणामस्वरूप पूरी तरह से स्थानांतरित रेपो में होता है।

स्क्रिप्ट आपको कोई भी बदलाव करने से पहले रेपो की एक प्रति बनाने का विकल्प देती है, ताकि आप बैकअप बनाने के लिए इस विकल्प का उपयोग कर सकें। यदि आपको किसी भी शाखा में अन-पुश परिवर्तन हुए हैं, तो एक प्रति बनाना आवश्यक है।

स्क्रिप्ट किसी भी रत्न या अन्य पुस्तकालयों का उपयोग नहीं करती है जो सामान्य एमआरआई रूबी स्थापना में शामिल नहीं हैं। यह एमआरआई में शामिल रीडलाइन और फाइलुटिल पुस्तकालयों का उपयोग करता है।

उम्मीद है कि मेरी स्क्रिप्ट किसी और के लिए उपयोगी साबित होगी। स्क्रिप्ट में बदलाव करने के लिए स्वतंत्र महसूस करें।

नोट: मैंने केवल इस स्क्रिप्ट को git 2.3.0 / 2.3.1 और रूबी 2.2.0 के साथ OS X 10.10 Yosemite पर परीक्षण किया है (क्योंकि मैं जिस पर्यावरण का उपयोग करता हूं), लेकिन मैं इसके साथ ही अन्य वातावरणों पर भी काम करने की उम्मीद करूंगा। हालांकि, विंडोज के बारे में कोई गारंटी नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.