2008-12-01 11 views
60

मान लीजिए कि मैं एक रिलीज शाखा से मास्टर शाखा में विलय करना चाहता हूं और कुछ रिलीज शाखा में कुछ काम करता है जिसे मैं मास्टर शाखा में शामिल नहीं करना चाहता हूं। क्या विलय करने का कोई तरीका है ताकि उनमें से एक या अधिक विलय नहीं किया जा सके?क्या गिट विलय करते समय विशिष्ट प्रतिबद्धताओं को बाहर करना संभव है?

मेरे रणनीति अब तक ऐसा करने के लिए है (मास्टर में) के बाद:

git merge --no-commit release-branch 
# Resolve conflicts and apply reverse patch of the commits that I don't want included 
git commit # Edit commit message so that it lists the commits that have been reverse-patched 

वहाँ यह करने के लिए एक बेहतर तरीका है?

+0

[गिट-स्किपिंग विशिष्ट विलय के दौरान विशिष्ट काम करता है] का संभावित डुप्लिकेट (https://stackoverflow.com/questions/727994/git-skipping- विशिष्ट-commits-when-merging) - मुझे पता है कि यह छोटा है, लेकिन इसकी [ स्वीकार्य उत्तर] (https://stackoverflow.com/a/729723/321973) IMHO बेहतर –

उत्तर

41

एक नई शाखा बनाएं, शाखा को अंतःक्रियात्मक रूप से दोबारा दबाएं और उन चीजों को छोड़ दें जिन्हें आप नहीं चाहते हैं, और फिर इसे मर्ज करें।

आप बिना किसी शाखा के बीच में शाखाओं के बीच में बदलाव नहीं कर सकते हैं, लेकिन सही बात तब होगी जब यह बाद में विलय में समान परिवर्तन देखेगी (उदाहरण के लिए चेरी-पिकिंग और क्या नहीं)।

+2

है लेकिन जब आप उस शाखा को फिर से मर्ज करने का प्रयास करते हैं तो क्या होता है? – Evgeny

+4

यह किस सटीक आदेश के साथ किया जाना है? मुझे कोई रास्ता नहीं दिखता कि मैं अवांछित कामों को कैसे छोड़ सकता हूं – Henning

+8

@ हेनिंग जब आप रीटेज करते हैं- मैं अन्य शाखा 'यह आपको टेक्स्ट ऑफ एडिटर देता है जिसमें यह काम करता है। उन लाइनों को हटाएं जिन्हें आप नहीं चाहते हैं। – Dustin

4

कारण यह सीधे नहीं किया जा सकता है कि प्रत्येक प्रतिबद्धता में माता-पिता के काम शामिल होते हैं (आमतौर पर केवल एक लेकिन विलय के लिए कई)। इस तरह यदि आपके पास एक प्रतिबद्धता है (इसके SHA1 योग से) पूरा इतिहास भी तय किया जाता है क्योंकि माता-पिता में उनके माता-पिता के लिंक भी शामिल होते हैं। तो इतिहास में पैच छोड़ने का एकमात्र तरीका एक नया लिखना है। एक नई बनाई गई शाखा पर गिट रिबेस- मैं शायद इसे प्राप्त करने का सबसे आसान तरीका है।

101

मुझे एक समाधान मिला है जो मेरे लिए काम करता है in the Pro Git book

मान लें कि आप फ़ाइल config.php को बाहर करना चाहते हैं।

शाखा एक पर: config.php merge=ours:

  1. एक ही निर्देशिका में .gitattributes नाम की एक फ़ाइल, इस लाइन के साथ बनाएँ। यह गिट बताता है कि फ़ाइल विलय करते समय किस रणनीति का उपयोग करना है। इस मामले में यह हमेशा आपका संस्करण रखता है, यानी। जिस शाखा में आप विलय कर रहे हैं उस संस्करण का संस्करण।

  2. .gitattributes फ़ाइल जोड़ें और प्रतिबद्ध

शाखा बी पर: दोहराने कदम 1-2

अब विलय की कोशिश करो। आपकी फाइल छूटे रहना चाहिए।

+1

भावी पाठकों के लिए, यह विशिष्ट फ़ाइलों सहित स्पष्ट रूप से * नहीं * के लिए बहुत अच्छा काम करता है। (मेरे मामले में, मैं अलग-अलग सर्वरों पर विभिन्न शाखाएं तैनात कर रहा हूं और प्रत्येक कैपिस्ट्रानो को प्रत्येक शाखा पर अद्वितीय स्क्रिप्ट रखना चाहता हूं।) – charliepark

+13

यह किसी कारण से मेरे लिए काम नहीं करता है। मैंने फ़ाइल को बदलने की प्रतिबद्धता के साथ एक नई शाखा बनाई, और दोनों शाखाओं में .gitattributes फ़ाइल जोड़ा। जब मैं मूल शाखा में वापस विलय करता हूं, तो यह पूरी तरह से .gitattributes में रेखा को अनदेखा करता है, और बदले में बदले गए फ़ाइल में खींचता है। क्या कोई सेटिंग है जो मुझे याद आ रही है? – robbles

+6

@robbles आपको यह याद आ रही है: http://stackoverflow.com/a/14099431/6309 – VonC

1

आप केवल कुछ करता है कि अंत में कर रहे हैं बाहर करना चाहते हैं, तो आप सिर्फ एक विशिष्ट करने के लिए प्रतिबद्ध कर सकते हैं प्रतिबद्ध संख्या:

git checkout partlyMergedFrom 
git whatchanged 
--> find the commit hash up to where you want to merge 
git checkout partlyMergedInto 
git merge e40a0e384f58409fe3c864c655a8d252b6422bfc 
git whatchanged 
--> check that you really got all the changes you want to have 
2

यह भी .git/जानकारी संशोधित करने के लिए संभव है/फ़ाइल विशेषताओं और इसे रखने के अंदर .git फ़ोल्डर को जोड़ने के बजाय .git फ़ोल्डर के अंदर उन्हें अंततः स्रोत नियंत्रण में जोड़ने की आवश्यकता होगी।

12

यदि आपके पास एक समर्थन शाखा है जहां आप बग ठीक करते हैं और नए संस्करण बनाते हैं। मास्टर पर आपके पास अगला संस्करण है जहां आप अक्सर नए संस्करण भी बनाते हैं।

हर बार जब आप एक नया संस्करण बनाते हैं तो आप कुछ फ़ाइल में संस्करण बदलते हैं, उस नई फ़ाइल को प्रतिबद्ध करते हैं, एक टैग बनाते हैं और पुश करते हैं। अब समर्थन से मास्टर से विलय हो जाता है जिसमें हमेशा संस्करण जानकारी वाली फ़ाइल में विवाद होंगे।

यदि फ़ाइल जानकारी वाली फ़ाइल में केवल में संस्करण जानकारी है, तो आप fcurella के उत्तर के साथ जा सकते हैं। लेकिन अगर यह वास्तव में विलय योग्य जानकारी (pom.xml, gradle.properties, MANIFEST.MF, ...) भी हो सकता है, तो आपको कुछ अतिरिक्त कार्रवाई करनी होगी।

निम्न उदाहरण

 C---D*---E---F* support 
    /
A---B---G---H*---I master 

जहां के साथ सितारों केवल संस्करण परिवर्तन है कि मर्ज के दौरान अनदेखा किया जाना चाहिए की वजह से परिवर्तन शामिल करता है का उपयोग करने देता है।

बिना संस्करण बनाता है की वजह से मर्ज-संघर्ष मास्टर में समर्थन मर्ज करने के लिए, आप निम्न में से किसी कर सकते हैं:

एकाधिक मर्ज करता

git checkout master 
git merge C 
git merge D -s ours 
git merge E 
git merge F -s ours 

-s ours तर्क के साथ हम कार्यक्षेत्र को बदलने के बिना केवल मर्ज रिकॉर्ड करने के लिए गिट को बता रहे हैं। यह तुलनीय to the --record-only option of svn है।

ऊपर निम्नलिखित लेआउट

 -------------C---D*---E---F* support 
    /   \ \ \ \ 
A---B---G---H*---I---J---K----L---M master 

एक मर्ज का उपयोग कर के लिए प्रतिबद्ध में परिणाम होगा चेरी लेने

git checkout master 
git merge support -s ours --no-commit 
git cherry-pick C E --no-commit 
git commit -m 'merged support into master' 

पहले हम, किसी मर्ज लेकिन केवल रिकॉर्ड है कि हम विलय कर रहे हैं शुरू कर रहे हैं को बदले बिना कार्यक्षेत्र और विलय प्रतिबद्ध किए बिना। फिर हम बिना किसी प्रतिबद्धता के फिर से विलय करने के लिए काम करते हैं। अंत में हम विलय कर रहे हैं।

ऊपर निम्नलिखित लेआउट

 C---D*---E---F* support 
    /   \ 
A---B---G---H*---I---J master 

एक भी चेरी पिकिंग को स्वचालित कर सकता का परिणाम देगा।

git checkout master 
git merge support -s ours --no-commit 
for id in `git log support --reverse --not HEAD --format="%H [%an] %s" | 
    grep -v "bump version" | 
    sed "s/\(\w*\)\s.*/\1/g"` 
do 
    git cherry-pick --no-commit $id 
done 
git commit -m 'merged support into master' 
+0

एकाधिक विलय को स्वचालित करने के लिए कोई उदाहरण है? – Santos

2

मुख्य सवाल यह है: आप कैसे करता आप छोड़ना चाहते का प्रतिनिधित्व करना चाहते हैं?

  1. sneakily उन्हें (नहीं मेरी पसंदीदा) छिपाने
  2. स्पष्ट रूप से उन्हें
  3. छोड़ स्पष्ट रूप से उन्हें पूर्ववत

दुर्भाग्य से कोई। इतिहास ग्राफ में व्यक्त करना असंभव है 2।

नंबर 1 संभव है, लेकिन मैं कभी नहीं ऐसा करता हूं: एक विलय प्रतिबद्धता में परिवर्तन हो सकते हैं। - आम तौर पर दो और अधिक शाखाओं के विलय के परिणामस्वरूप एक विलय प्रतिबद्ध बिंदु: उन शाखाओं में विकसित सभी चीजें विलय के बाद कोड में होनी चाहिए (यानी मर्ज प्रतिबद्ध द्वारा इंगित कोड में)। और इस प्रतिबद्धता में और कुछ भी नहीं होना चाहिए।

लेकिन आश्चर्य की बात है, आश्चर्य है, आप पूरे कोड बेस को बदल सकते हैं और इसे मर्ज के रूप में प्रस्तुत कर सकते हैं।विलय का प्रभाव दो गुना है: यह इतिहास के पेड़ को विलीन करता है और इसे दो कोड अड्डों को मर्ज करना चाहिए। पूर्व यह सुनिश्चित करने के लिए करता है (अन्यथा कोई भी इसे मर्ज नहीं करता है), बाद वाले के लिए यह असफल हो सकता है, उदा। जब एक विलय संघर्ष उत्पन्न हुआ और इसे गलत तरीके से हल किया गया (तब कोड बेस ठीक से विलय नहीं किए गए थे)।

कुछ अन्य उत्तरों इस छिपाने का सुझाव देते हैं। मैं स्पष्ट तरीके से अनुशंसा करता हूं: प्लस रिवर्ट मर्ज करें।

+0

यह अल्पकालिक शाखाओं के लिए एक महान रणनीति है। इस रणनीति के साथ समस्या यह है कि जब आप अपनी सही ढंग से विलय वाली शाखा (वापसी के साथ) को वापस काम करने वाली शाखा में विलय करते हैं, तो कार्यरत शाखा को भी वापसी मिल जाएगी, क्योंकि यह नियमित, वास्तविक प्रतिबद्धता है। यदि आपके पास ऐसा मामला है कि मजदूर शाखा में वास्तव में प्रतिबद्धता नहीं होनी चाहिए तो आपको वापस लौटना होगा। यह तब तक जारी रहेगा जब तक कि उस विशेष कार्यशील शाखा का उपयोग नहीं किया जा रहा है। –

+0

@RonWertlen आप इस कथन के साथ सही हैं कि मास्टर को उस "कार्यरत शाखा"/रिलीज शाखा में फिर से विलय के प्रभाव को पेश किए बिना विलय नहीं किया जा सकता है। - लेकिन यह मेरे उत्तर की मेरी सुझाई गई रणनीति 3 के लिए भी सही नहीं है, बल्कि रणनीति के लिए भी 1. यह एक कारण है कि मैं व्यक्तिगत रूप से ओपी के प्रश्न से वर्कफ़्लो का पीछा नहीं करता। –

+0

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

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