2010-07-10 10 views
12

मेरे पास दो गिट भंडार हैं जो सामरिक रूप से संबंधित हैं। अर्थात्, एक की सामग्री दूसरे के पूर्ववर्ती थी। मैं डिपॉजिटरी ए को डिपॉजिटरी ए के पूर्ण इतिहास को किसी भी तरह से प्रस्तुत करना चाहता हूं, ताकि ए की नोक रिपोजिटरी बी के पहले बदलाव के माता-पिता होगी? दोनों में इतिहास सुंदर रैखिक हैं।दो गिट इतिहास कैसे सम्मिलित करें?

क्या यह संभव है?

उत्तर

9

आप भ्रष्टाचार फ़ाइल (.git/info/grafts) जहां

भी देखें "What are .git/info/grafts for?" और "How to prepend the past to a git repository?" (projectB माता पिता projectA के नवीनतम के लिए होने के पहले की तरह) एक के पिता के ऊपर लिख सकता है प्रतिबद्ध का उपयोग कर की कोशिश कर सकते इस हेरफेर पर अधिक के लिए।


skalee लेख "Git: Grafting repositories" एक ठोस उदाहरण के लिए (अतः Ben Straub उपयोगकर्ता से) के बारे में comments

अब हम क्या करना चाहते हैं बदल पहली "nuevo" रेपो ("New commit #1") इतना है कि अपनी मूल पिछले "पुराने" रेपो में प्रतिबद्ध है में प्रतिबद्ध ("ओल्ड # 3") है। कुछ वूडू के लिए समय:

git fetch ../old master:ancient_history 

Git आप किसी भी अन्य Git भंडार से ला नहीं, कि क्या यह रेपो यह करने के लिए नहीं संबंधित है या देता है! प्रतिभाशाली! यह हमें इस के साथ छोड़ देता है:

enter image description here

नोट कैसे हम ancient_history को पुराने मास्टर शाखा का नाम बदला। अगर हम नहीं थे, तो गिट ने दोनों को मर्ज करने की कोशिश की होगी, और शायद घृणा में छोड़ दिया होगा।

अब हमें अभी भी एक समस्या है।
दो पेड़ जुड़े नहीं हैं, और वास्तव में एक गिट पुल को प्राचीन_हैतिहासिक शाखा भी नहीं मिलेगी। हमें दोनों के बीच संबंध बनाने का एक तरीका चाहिए।

गिट में एक भ्रष्टाचार नामक सुविधा है, जो मूल रूप से दो कामों के बीच एक मूल लिंक बनाता है।
एक करने के लिये इस प्रारूप में .git/info/grafts फ़ाइल में एक पंक्ति सम्मिलित करें:

[ref] [parent] 

इन दोनों प्रश्न में प्रतिबद्ध से भरा हैश की जरूरत है। तो चलो उन्हें ढूँढते हैं:

$ git rev-list master | tail -n 1 
d7737bffdad86dc05bbade271a9c16f8f912d3c6 

$ git rev-parse ancient_history 
463d0401a3f34bd381c456c6166e514564289ab2 

$ echo d7737bffdad86dc05bbade271a9c16f8f912d3c6 \ 
     463d0401a3f34bd381c456c6166e514564289ab2 \ 
     > .git/info/grafts 

echo $(git rev-list master | tail -n 1) $(git rev-parse ancient_history) > .git/info/grafts 

वहाँ (ssokolow द्वारा suggested के रूप में एक पंक्ति, में)।अब हमारे इतिहास इस तरह दिखता है:

enter image description here

इस में इस रेपो परिणाम क्लोनिंग:

enter image description here

ओह। यह पता चला है कि ग्राफ्ट केवल स्थानीय भंडार के लिए प्रभावी होते हैं। हम git fast-import का विवेकपूर्ण आवेदन के साथ इसे ठीक कर सकते हैं:

$ git fast-export --all > ../export 

$ mkdir ../nuevo-complete 

$ cd ../nuevo-complete 

$ git init 

$ git fast-import < ../export 
git-fast-import statistics: [...] 

git filter-branch $(git rev-parse ancient_history)..HEAD 

यह प्रभावी रूप में हमारे "नकली" इतिहास लिंक धर्मान्तरित (ssokolow द्वारा suggested के रूप में एक पंक्ति में) अकेले हैं।
सभी इंजीनियरों को इस नए भंडार से फिर से क्लोन करना होगा, क्योंकि हैश सभी अलग होंगे, लेकिन यह डाउनटाइम और एक पूर्ण इतिहास के लिए भुगतान करने के लिए एक छोटी सी कीमत है।

enter image description here

रूप Qix टिप्पणी below:

fast-import सिर्फ Git जानकारी आयात करने के लिए प्रकट होता है, लेकिन कुछ भी की जाँच नहीं करता है।
git init मूल रूप से आपको मास्टर पर रखता है, इसलिए आपको की आवश्यकता है ताकि वास्तव में fast-import के बाद फ़ाइलों को चेक आउट कर सकें।

+0

मेरे लिए ठीक काम किया, धन्यवाद वॉनसी, ऐसा नहीं लगता था कि यह इतना आसान होगा। – SilentGhost

+1

फिर आप 'गिट फ़िल्टर-शाखा' का उपयोग करके इतिहास को फिर से लिख सकते हैं ताकि यह सुनिश्चित किया जा सके कि कौन सा भ्रष्टाचार स्थायी लाया गया है ... लेकिन यह इतिहास को फिर से लिखता है। –

+0

लघु और साफ लेख जो वास्तव में मुझे समझने में मदद करता है कि कौन से ग्राफ्ट हैं और चरण-दर-चरण उन इतिहासों में कैसे शामिल हों: http://ben.straubnet.net/post/939181602/git-grafting-repositories – skalee