2009-09-23 22 views
23

मैं गिट में बाइनरी फाइलों के साथ दो शाखाएं रखने की कोशिश कर रहा हूं - एक "विकास" और एक "स्थिर"। विकास शाखा में इन फ़ाइलों के कई बदलाव हो सकते हैं इससे पहले कि मैं उन्हें स्थिर शाखा में "रिलीज़" करना चाहता हूं (और स्थिर शाखा में उन फ़ाइलों का नाम बदल दिया गया है, यदि यह प्रासंगिक है)।गिट मर्ज स्क्वैश बार-बार

मैं सामान्य विलय कर सकता हूं, यह ठीक काम करता है, लेकिन "स्थिर" शाखा खींचते समय बहुत अधिक इतिहास को संरक्षित करता है, "विकास" शाखा से सभी मध्यवर्ती कार्य भी खींचे जाते हैं (क्योंकि वे माता-पिता होते हैं) । लेकिन हम बाइनरी फाइलों के बारे में बात कर रहे हैं जिनके पास कोई समझदार विलय रणनीति नहीं है (उनके/हमारे को छोड़कर), इसलिए विकास शाखा पर फ़ाइलों का वास्तविक इतिहास बेकार है। जब मैं "स्थिर" शाखा खींच, मैं इस मिल:

 
      X-------------------G stable 
     /    /
    a---b---c---d---e---f---g development 

क्योंकि जी विकास शाखा में एक माता पिता है, मैं विकास शाखा के पूरे इतिहास (के लिए सी, डी, ई, एफ डेटा वस्तुओं मिलता है और जी) मेरे भंडार में, जिसमें मुझे कोई दिलचस्पी नहीं है (एक्स बी के समान है, कुछ फ़ाइल नामांकन लागू होने के साथ)।

तो मैंने विकास शाखा से स्थिर शाखा तक git merge --squash परिवर्तनों की कोशिश की। इस तरह की पहली मर्ज और प्रतिबद्ध ठीक चला गया, परिणाम अपेक्षित थे के रूप में (प्रतिबद्ध संदेश, विकास शाखा से कोई संबंध नहीं में अच्छे परिवर्तन लॉग):

   X-------------------G stable 
     /     
    a---b---c---d---e---f---g development

बाद मैं इस कुचल शाखा स्थिर खींच, मुझे इस मिल मेरी भंडार है, जो मैं चाहता:

 
a---b---X---G 

लेकिन दूसरे मर्ज करना विफल (क्योंकि Git कोई रास्ता पता करने के लिए कितना मैं पहले से ही विलय कर दिया और उलझन में मिल गया था)।

  • क्या किसी भी तरह से दो माता-पिता के साथ "विलय प्रतिबद्धता" उत्पन्न किए बिना विलय को रिकॉर्ड करना संभव है?
  • या, क्या एसवीएन में संशोधन की केवल एक निश्चित "सीमा" को मर्ज करने के लिए गिट को बताना संभव है?
  • या, खींचते समय दूसरी शाखा से सभी रेफरी डाउनलोड किए बिना सामान्य विलय करना संभव है?
  • या मुझे प्रश्न में फाइलों के लिए एक कस्टम मर्ज ड्राइवर प्रदान करना चाहिए, जो कि "उनके" संस्करण को "हमारे" में बदल देता है, जिससे संघर्ष हल हो जाता है? मुझे अभी भी डर है कि --squash हमेशा पूरे इतिहास को मर्ज करने की कोशिश करेगा, आम माता-पिता तक, मेरी समस्या का केवल आधा हल करेगा।

अद्यतन: रिबेसिंग

मैं सही ढंग से रिबेसिंग को समझते हैं, मैं इस के साथ खत्म हो जाएगा:

 
           X stable 
          /
    a---b---c---d---e---f---g development 

कौन सा मुझे हो जाता है सभी डेटा मैं (ग में कोई दिलचस्पी नहीं हूँ , डी, ई, एफ) और बोनस के रूप में, मैं जानकारी खो दूंगा कि बी शाखा में एक स्थिर संस्करण था।

प्रत्येक विकास संशोधन भंडार आकार में लगभग 5 एमबी जोड़ता है (और पूरे रेपो को केवल 10% घटता है), "स्थिर" शाखा लगभग मुफ्त में आती है (डेटा पहले से मौजूद है)। मैं केवल नई 5 एमबी खींचने के लिए स्थिर शाखा से एक नया संशोधन खींचना चाहता हूं, लेकिन एक्स से जी से 25 एमबी डाउनलोड करने के बजाय, क्योंकि मैं किसी भी तरह से यह कहने में सक्षम नहीं हूं कि मुझे सी, डी की सामग्री की परवाह नहीं है , ई और एफ।

उत्तर

23

 X stable 
    /     
a---b---c---d---e---f---g development 

आप कॉपी करने के लिए पिछले अपने विकास शाखा से अपने स्थिर शाखा के लिए प्रतिबद्ध निम्न चरणों का उपयोग कर सकते हैं के साथ शुरू साथ:

 X-------------------G stable 
    /     
a---b---c---d---e---f---g development 

आप "विकास" पर काम करते हैं, जैसे,

 X-------------------G stable 
    /     
a---b---c---d---e---f---g---h---i---j development 

जारी रखते हैं तो आप एक ही Git के रूप में ऊपर आदेश को दोहरा सकते हैं और आप के साथ खत्म हो जाएगा:

 X-------------------G-----------J stable 
    /     
a---b---c---d---e---f---g---h---i---j development 
+1

यह बहुत अच्छा लग रहा है, लेकिन मुझे समझ में नहीं आता कि अस्थायी शाखा बनाने के लिए इसकी आवश्यकता क्यों है और फिर इसका नाम बदलें। क्या ऐसा इसलिए है क्योंकि आप अभी भी प्रतिबद्ध होने के बाद अलग हैं? –

+0

@ किम-सुलिवान: "बिल्कुल क्यों": जब आप उपरोक्त उदाहरण में प्रतिबद्धता करते हैं, तो यह नई प्रतिबद्धता को इंगित करने के लिए 'HEAD' चलाता है लेकिन 'स्थिर' नहीं होता है - सिर अभी भी" अलग "होता है, और' स्थिर 'अभी भी पिछले संस्करण (एक्स, आपके मूल उदाहरण में) को इंगित करता है। शाखा करना और नाम बदलें (चेकआउट तकनीकी रूप से वैकल्पिक है, हालांकि इसके बिना आपको 'गिट शाखा-एम' के लिए तर्कों की आपूर्ति करने की आवश्यकता होगी, और आप अभी भी अलग हो जाएंगे, जो संभवतः गैर-वांछनीय है) स्थिर बिंदु पर कारण बनता है जे के लिए (उत्तर प्रति)। – lindes

+4

इसके अलावा: आपको सूचनाओं के लिए आदेशों की इस श्रृंखला के साथ प्रत्येक बिंदु पर 'गिट लॉग - ग्राफ़ - ऑनलाइन - सभी - डिकोरेट' और 'गिट स्थिति' चल रहा है। और/या .git /, शायद 'grep' के साथ विभिन्न फ़ाइलों की सामग्री को देख रहे हैं। .git/HEAD .git/refs/head/* ' – lindes

7

merge --squash का उपयोग करने के लिए यह सही जगह नहीं है।इसका उपयोग करने के लिए एक अच्छी जगह एक फेंकने वाली विषय शाखा में है, जिसे आप अपनी मुख्य शाखा में विलय करने जा रहे हैं और फिर से छुटकारा पाएं। विषय शाखा में किए गए सभी विकास को मुख्य शाखा में एक प्रतिबद्धता के रूप में दिखाया गया है। आपकी स्थिति में, आपको सामान्य रूप से विकास शाखा से विलय करना चाहिए, और फिर इच्छित इच्छाओं को स्क्वैश करने के लिए git-rebase --interactive का उपयोग करना चाहिए।

यह किसी भी तरह मर्ज रिकॉर्ड करने के लिए, एक दो माता पिता के साथ "मर्ज प्रतिबद्ध" उत्पादन के बिना संभव है?

अगर मैं सवाल सही ढंग से समझ, नहीं। बिल्कुल नहीं।

यह SVN में की तरह, सिर्फ एक निश्चित संशोधन "सीमा" विलय करने के लिए Git बताने के लिए संभव है?

हां। git merge [commit hash]

या, यह जब खींच अन्य शाखा से सभी refs डाउनलोड करने के लिए बिना एक सामान्य मर्ज करने के लिए संभव है?

पिछले प्रश्न का उत्तर देखें।

या मैं प्रश्न में फ़ाइलों के लिए एक कस्टम मर्ज ड्राइवर, जो केवल एक "अपने" संस्करण का नाम बदलता है करने के लिए "हमारे", जिससे संघर्ष को हल करने प्रदान करना चाहिए? मुझे अभी भी डर है कि - स्क्वैश हमेशा पूरे इतिहास को मर्ज करने की कोशिश करेगा, आम माता-पिता तक, मेरी समस्या का केवल आधा हल करेगा।

नहीं! बस git merge --squash का उपयोग न करें। इसका उपयोग करने के लिए यह सही जगह नहीं है!

+0

आपके उत्तर के लिए धन्यवाद! मुझे यकीन नहीं है कि पुन: प्रयास करना मुझे चाहिए। मुझे "स्थिर" शाखा में कुछ इतिहास रिकॉर्ड करने की आवश्यकता है, इसलिए मैं "रिलीज" के बीच आगे और आगे जा सकता हूं।यह वही है जो मैं चाहता हूं: ' डी -> एस डी | डी | डी -> एस डी | डी -> एस'लेकिन मुझे केवल एस शाखा से इतिहास की आवश्यकता है - मुझे डी शाखा से इतिहास की परवाह नहीं है। मुझे जिस समस्या को हल करने की आवश्यकता है वह एस शाखा को सभी शाखाओं को डी शाखा से खींचने के बिना खींचने के लिए है (अगर मैं इसे सही ढंग से समझता हूं, तो रिबेसिंग पिछले सभी एसआई से छुटकारा पाती है जो मैं नहीं चाहता)। ' विकास -> एक्स विकास विकास विकास -> एक्स विकास विकास -> S' –

+0

हाँ, मैं समझता हूँ कि आप एस शाखा से मौजूदा इतिहास को संरक्षित करने की जरूरत है। नहीं, रिबेसिंग सभी पिछले एस कामों से छुटकारा नहीं पाती है; विकास को स्थिर में विलय करने से पहले, [प्रतिबद्ध हैश] पर ध्यान दें और फिर गिट रिबेस -आई [प्रतिबद्ध हैश] - तो आप प्रभावी रूप से केवल विलय करने वाले कामों को स्क्वैश कर देंगे। साथ ही, जहां तक ​​रिलीज का संबंध है, क्यों न सिर्फ विशिष्ट रिलीज के रूप में टैग करता है? – artagnon

+0

मुझे खेद है कि मैं आपके डी -> एस डी को काफी समझ नहीं पा रहा हूं। डी आरेख बहुत अच्छी तरह से। मुझे उम्मीद है कि मेरी पिछली टिप्पणी ने सबकुछ स्पष्ट किया है। – artagnon

4

आप git rebase -i (इंटरैक्टिव मोड) इस्तेमाल कर सकते हैं अपने सभी परिवर्तनों sqash के लिए, बस m या meld को पंक्तियों में परिवर्तन (अद्यतन: नए Git के लिए विज्ञप्ति टाइप s या squash)

आप से एक भी वादा करना होगा जो आप विलय कर सकते हैं।अगर आप अपने आरक्षित आरक्षित कदम को चाहते हैं, तो आपको रीबेज करने से पहले अपनी हैकिंग शाखा पर एक और शाखा बनाना होगा, यह git branch small-dirty-changes-i-don’t-want-anybody-to-see

के साथ किया जा सकता है, यह सब विलय करने का प्रयास करने से पहले किया जाना चाहिए; चरण दर चरण:

git checkout [email protected]{0} # get working tree from "development", detach HEAD 
git reset --soft stable # reposition detached HEAD on "stable" 
git commit # enter the appropriate commit message 
git branch temp # create a temporary branch "temp" at HEAD 
git checkout temp # get on the new temporary branch 
git branch -M stable # rename "temp" to "stable" 
तो

आप अंत:

# on branch "hacking": hack commit hack commit hack commit 

# create a reference to your history 
$ git branch dirty-history 

# sqash your commits by setting all lines to "meld" 
$ git rebase -i 

# checkout master or the branch you want to merge to 
$ git checkout master 

# merge your squashed commit 
$ git merge hacking 
# or: $ git pull hacking 
+0

एचएम, मैं शायद कुछ समय में विकास शाखा ("गंदे") में बदलावों को दोबारा कर सकता हूं (वास्तव में, स्थिर और रिहाई में विलय करने से पहले), इसलिए मेरे पास उन सभी मध्यवर्ती बाइनरी नहीं हैं जिनकी मुझे बहुत परवाह नहीं है । स्थिर रिलीज के बीच एकमात्र महत्वपूर्ण बात हैश और प्रतिबद्ध संदेश है ... हैश परीक्षण के लिए महत्वपूर्ण है (जिसका निर्माण परीक्षण किया गया था और जो नहीं था)। मुझे इसके बारे में और कुछ सोचना होगा। –

+0

अच्छा जवाब, मुझे लगता है कि आजकल "मिलल्ड" का मतलब है "स्क्वैश" (आपका जवाब 200 9 से है!) –

+1

हां, अब यह 's'/squash' है। – knittl

-1

मैं git करने के लिए नया हूँ, लेकिन ऐसा लगता है - स्क्वैश वह है जो आप चाहते हैं, आपको बस शाखा को अलग-अलग संभालना होगा।

$ git merge --squash development 
$ git branch -d development 
$ git checkout -b development 
# continue work on development branch 

यह अनिवार्य रूप से विकास शाखा के इतिहास को छोटा कर देगा, और अगला विलय केवल वही होगा जो आप चाहते थे। मैन पेज को देखकर ऐसा लगता है कि git branch -f development शाखा को हटाने और पुनर्निर्माण के समान ही काम कर सकता है।

जैसा कि मैंने कहा, मैं गिट करने के लिए काफी नया हूं, इसलिए मुझे इस विचार पर कुछ प्रतिक्रिया पसंद आएगी।

0

top voted answer प्रभावी रूप से स्थिर और विकास शाखाओं को अलग करता है और एक प्रतिबद्धता के रूप में स्थिर में अनुपलब्ध सभी परिवर्तनों को लागू करता है। ऐसा करने का एक वैकल्पिक तरीका है:

$ git checkout stable 
$ git diff stable development | git apply --index - 
$ git commit 

आपके प्रतिबद्ध होने से पहले, आप चरणबद्ध फ़ाइलों की समीक्षा कर सकते हैं। यदि आप diff लागू करने के बाद प्रक्रिया को निरस्त करना चाहते हैं, तो आप इंडेक्स और कार्यशील निर्देशिका से परिवर्तनों को हटाने के लिए केवल बुनियादी आदेशों का उपयोग कर सकते हैं।

$ git reset --hard 

आप प्रक्रिया कितनी भी बार दोहरा सकते हैं जब से तुम प्रभावी ढंग से सिर्फ diff-इंग हर बार जब आप को आपस में दोनों शाखाओं के सुझाव दिए गए हैं।

ध्यान दें कि यहां पर धारणा है कि दूसरे उत्तर पर भी लागू होता है: विकास शाखा से आने वाले अन्य लोगों के अलावा स्थिर शाखा में कोई काम नहीं है। यदि दोनों शाखाओं में एक ही पंक्ति स्वतंत्र रूप से बदल दी गई थी, नियमित मर्ज के विपरीत, यह दृष्टिकोण आपको एक संघर्ष नहीं देगा। इसके बजाए, यह विकासशील लोगों के साथ स्थिर शाखा में बदलावों को ओवरराइड करेगा।

यदि आप इस बारे में चिंतित हैं, हर बार जब आप स्थिर पर प्रतिबद्ध होते हैं, तो आप प्रतिबद्ध संदेश में विलय विकास प्रतिबद्ध हैश रेंज डाल सकते हैं। इस तरह, यदि आपके पास कभी भी बैकट्रैक की आवश्यकता है, तो आपके पास कुछ रिकॉर्ड है।

संबंधित मुद्दे