मेरा कार्यालय चाहता है कि अनंत शाखा नीति के रूप में विलीन हो जाए; हमारे पास और क्या विकल्प हैं?


119

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

हमारा मुद्दा दीर्घकालिक साइडब्रांचों के साथ है - जिस तरह से आपको कुछ लोग मिल रहे हैं जो एक साइडब्रंच काम करते हैं जो मास्टर से विभाजित होता है, हम कुछ महीनों के लिए विकसित होते हैं, और जब हम एक मील के पत्थर पर पहुंचते हैं तो हम दो को सिंक करते हैं।

अब, IMHO, इसको संभालने का प्राकृतिक तरीका है, साइडब्रंच को एक सिंगल कमिट में स्क्वैश करना। masterआगे बढ़ता रहता है; जैसा कि यह होना चाहिए - हम रेट्रोएक्टली डंपिंग के समानांतर विकास के महीनों को masterइतिहास में शामिल नहीं कर रहे हैं । और अगर किसी को साइडब्रंच के इतिहास के लिए बेहतर समाधान की आवश्यकता है, तो ठीक है, निश्चित रूप से यह सब अभी भी वहां है - यह बस में नहीं है master, यह साइडब्रंच में है।

यहाँ समस्या है: मैं विशेष रूप से कमांड लाइन के साथ काम करता हूं, लेकिन मेरी टीम के बाकी लोग GUIS का उपयोग करते हैं। और मुझे पता चला है कि GUIS के पास अन्य शाखाओं से इतिहास प्रदर्शित करने के लिए एक उचित विकल्प नहीं है । इसलिए यदि आप "यह विकास शाखा से स्क्वैश" कहते हुए, एक स्क्वैश कमेटी तक पहुँचते हैं XYZ, तो यह देखने के लिए बहुत बड़ा दर्द होता है कि क्या है XYZ

SourceTree पर, जहां तक ​​मैं खोजने में सक्षम हूं, यह बहुत बड़ा सिरदर्द है: यदि आप चालू हैं master, और आप इतिहास देखना चाहते हैं master+devFeature, तो आपको या तो चेक master+devFeatureआउट करना होगा (हर एक फ़ाइल को छूना अलग है), या फिर एक लॉग के माध्यम से स्क्रॉल करें जब तक कि आपको सही जगह नहीं मिलती समानांतर में अपनी सभी रिपॉजिटरी की शाखाएं प्रदर्शित करें। और अच्छी किस्मत यह है कि आप वहां हैं।

मेरे टीम के साथी, काफी हद तक विकास के इतिहास को इतना दुर्गम नहीं बनाना चाहते। इसलिए वे चाहते हैं कि ये बड़े, लंबे विकास-साइडब्रांच में विलय हो, हमेशा एक मर्ज कमिट के साथ। वे ऐसा कोई इतिहास नहीं चाहते हैं जो मास्टर शाखा से तुरंत सुलभ न हो।

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

क्या हमारे पास मर्ज-कमिट के साथ लगातार मास्टरबेशन को मर्ज करने के अलावा यहां कोई विकल्प है? या, क्या कोई कारण है कि लगातार मर्ज-कमिट का उपयोग करना उतना बुरा नहीं है जितना मुझे डर है?


84
क्या मर्ज के रूप में मर्ज रिकॉर्ड करना वास्तव में बुरा है? मैं देख सकता हूं कि एक रेखीय इतिहास में स्क्वैशिंग के अपने फायदे हैं, लेकिन मुझे आश्चर्य है कि ऐसा नहीं करने से "सबसे अच्छा सब कुछ जो आप अच्छे प्रबंधन प्रबंधन के बारे में जानते हैं" के खिलाफ जाता है। वास्तव में क्या समस्याएं हैं जिनसे आप डरते हैं?
IMSoP

65
ठीक है, लेकिन मेरे मन में एक लंबे समय से चल शाखा वास्तव में जगह है जहाँ आप कर , ताकि दोषी मानते हैं और दो भागों में बांटती बस पर "परिवर्तन 2016 के बिग पुनर्लेखन के हिस्से के रूप पेश किया गया था" भूमि नहीं है कुछ दृश्यता चाहते हैं। मुझे उत्तर के रूप में पोस्ट करने के लिए पर्याप्त विश्वास नहीं है, लेकिन मेरी वृत्ति यह है कि यह सुविधा शाखा के भीतर के कार्य हैं जिन्हें स्क्वैश किया जाना चाहिए, ताकि आपके पास मुख्य इतिहास से सुलभ परियोजना का एक छोटा-ईश इतिहास हो, बिना एक अनाथ शाखा की जाँच करें।
IMSoP

5
यह कहा जा रहा है, यह इस प्रकार संभव है कि प्रश्न "मैं अपने साथियों की तुलना में उच्च स्तर पर गिट का उपयोग करने की कोशिश कर रहा हूं; मैं उन्हें अपने लिए गड़बड़ करने से कैसे बचा सकता हूं।" जो, काफी हद तक, मैं ईमानदारी से git log master+bugfixDec10thब्रेकिंग पॉइंट होने की उम्मीद नहीं करता था : - /
स्टैंडबैक

26
"लंबे समय तक साइडब्रांच - जिस तरह से आपको कुछ लोग ऐसे साइडब्रंच काम कर रहे हैं जो मास्टर से अलग होते हैं, हम कुछ महीनों के लिए विकसित होते हैं, और जब हम एक मील के पत्थर पर पहुंचते हैं तो हम दोनों को सिंक करते हैं।" क्या आप समय-समय पर मास्टर से साइड ब्रांच में नहीं खींचते हैं? यह करते हुए कि प्रत्येक (कुछ) कई मामलों में जीवन को सरल बनाने के लिए मास्टर की ओर जाता है।
TafT

4
है merge --no-ffकि तुम क्या चाहते हो? पर masterही आप एक प्रतिबद्ध है कि यह बताता है कि शाखा में बदल है, लेकिन करता के सभी अभी भी मौजूद हैं और सिर के लिए parented रहे हैं।
16:97 पर CAD97

जवाबों:


244

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

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

पुनर्लेखन, चेरी-पिकिंग या स्क्वैशिंग हटाने या इतिहास को फिर से लिखने जैसे कार्य। विशेष रूप से, परिणामी कमिट्स मूल संदर्भों को संदर्भित नहीं करता है। इस पर विचार करो:

  • आप कुछ कमिट्स को स्क्वैश करते हैं और कमिट मैसेज में ध्यान देते हैं कि स्क्वैस्ड हिस्ट्री ओरिजिनल कमिट abcd123 में उपलब्ध है।
  • आप [1] सभी शाखाओं या टैगों को हटा देते हैं जिनमें abcd123 शामिल हैं क्योंकि वे विलय हो चुके हैं।
  • आप कचरा संग्रहकर्ता को चलने दें।

[१]: कुछ गिट सर्वर शाखाओं को आकस्मिक विलोपन से सुरक्षित रखने की अनुमति देते हैं, लेकिन मुझे संदेह है कि आप अपनी सभी सुविधा शाखाओं को अनंत काल तक रखना चाहते हैं।

अब आप उस कमिट को नहीं देख सकते - यह अभी मौजूद नहीं है।

एक प्रतिबद्ध संदेश में शाखा का नाम देना और भी बुरा है, क्योंकि शाखा के नाम एक रेपो के लिए स्थानीय हैं। master+devFeatureआपके स्थानीय चेकआउट में क्या है doodlediduhमेरा हो सकता है। शाखाएँ केवल ऐसे लेबल चलती हैं जो किसी प्रतिबद्ध वस्तु की ओर इशारा करती हैं।

सभी इतिहास पुनर्लेखन तकनीकों में से, रिबेसिंग सबसे अधिक सौम्य है क्योंकि यह उनके सभी इतिहासों के साथ पूर्ण प्रतिबद्धताओं की नकल करता है, और सिर्फ एक माता-पिता की जगह बदल देता है।

उस masterइतिहास में सभी शाखाओं का पूरा इतिहास शामिल है जिन्हें इसमें मिला दिया गया था, यह एक अच्छी बात है, क्योंकि यह वास्तविकता का प्रतिनिधित्व करता है। [२] अगर समानांतर विकास हुआ था, जो लॉग में दिखाई देनी चाहिए।

[२]: इस कारण से, मैं यह भी चाहता हूं कि लीनियराइज़ किए गए स्पष्ट रूप से मर्ज किए गए कमिटमेंट्स, लेकिन अंततः नकली इतिहास रिबासिंग के परिणामस्वरूप।

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

लंबे समय से चली आ रही शाखाओं का सबसे अच्छा समाधान उन शाखाओं को रोकना है जो केवल कुछ महीनों के बाद ही विलय हो जाती हैं। जब हाल ही में परिवर्तन होते हैं तो विलय आसान होता है। आदर्श रूप से, आप प्रति सप्ताह कम से कम एक बार विलय करेंगे। निरंतर एकीकरण (एक्सट्रीम प्रोग्रामिंग में, जैसा कि "आइए एक जेनकिंस सर्वर सेट करें"), यहां तक ​​कि प्रति दिन कई मर्ज का सुझाव देते हैं, अर्थात् अलग सुविधा शाखाओं को बनाए रखने के लिए नहीं बल्कि एक टीम के रूप में एक विकास शाखा साझा करते हैं। किसी सुविधा से पहले विलय करना QA'd के लिए आवश्यक है कि सुविधा एक सुविधा ध्वज के पीछे छिपी हो।

बदले में, लगातार एकीकरण संभावित समस्याओं को बहुत पहले से ही संभव बनाता है, और एक सुसंगत वास्तुकला रखने में मदद करता है: दूरगामी परिवर्तन संभव हैं क्योंकि ये परिवर्तन जल्दी से सभी शाखाओं में शामिल हैं। यदि कोई परिवर्तन कुछ कोड को तोड़ता है, तो यह केवल कुछ दिनों का काम करेगा, न कि कुछ महीनों का।

इतिहास पुनर्लेखन वास्तव में बहुत बड़ी परियोजनाओं के लिए समझ में आता है जब कोड की कई लाखों लाइनें और सैकड़ों या हजारों सक्रिय डेवलपर्स होते हैं। यह उल्लेखनीय है कि इस तरह की एक बड़ी परियोजना को अलग-अलग पुस्तकालयों में विभाजित होने के बजाय एकल गिट रेपो क्यों बनना पड़ेगा, लेकिन इस पैमाने पर यह अधिक सुविधाजनक है यदि केंद्रीय रेपो में केवल व्यक्तिगत घटकों के "रिलीज" शामिल हों। उदा। लिनक्स कर्नेल मुख्य इतिहास को प्रबंधनीय रखने के लिए स्क्वैशिंग का उपयोग करता है। कुछ ओपन सोर्स प्रोजेक्ट्स को एक git-level मर्ज के बजाय ईमेल के माध्यम से भेजे जाने वाले पैच की आवश्यकता होती है।


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

11
"यह जवाब देना आम तौर पर असंभव है" क्या यह मूल रूप से इस या उस शाखा पर प्रतिबद्ध था? "" मैं इस तथ्य को देखता हूं कि "शाखाएं" सिर्फ अपने आप में वास्तविक इतिहास के साथ आने के लिए कोई संकेत नहीं हैं क्योंकि यह सबसे बड़ी डिजाइन दोषों में से एक है। । मैं वास्तव में अपने संस्करण नियंत्रण प्रणाली "तारीख x पर शाखा x में क्या था" पूछने में सक्षम होना चाहता हूं।
पीटर ग्रीन

80
कुछ भी अधिक निराशाजनक नहीं है जो कोड का उपयोग करके बग के कारण की पहचान करने की कोशिश कर रहा है git bisect, केवल यह एक शाखा शाखा से 10,000 लाइन यूबर-कम पर पहुंचने के लिए है।
tpg2114

2
@ स्टैंडबैक IMHO जितना छोटा होता है, यह उतना ही पठनीय और अनुकूल होता है। एक ऐसा कमेंट जो कुछ बिंदुओं से अधिक को छूता है, पहली नजर में समझ पाना असंभव है, इसलिए आप केवल विवरण को अंकित मूल्य पर लेते हैं। यह विवरण की पठनीयता है (उदाहरण के लिए "लागू सुविधा X"), न कि केवल कमिट (कोड)। बल्कि मेरे पास एक-एक अक्षर के 1000 "जैसे http से बदलकर https" हो जाएगा
:)

2
चेरी-पिक इतिहास को फिर से लिखना या हटाना नहीं करता है। यह सिर्फ नए कमिट बनाता है जो मौजूदा कमिट्स से बदलाव को दोहराते हैं
सर्ज बोर्स्च

111

मुझे अमोन का जवाब पसंद है , लेकिन मुझे लगा कि एक छोटे से हिस्से पर बहुत अधिक जोर देने की जरूरत है: आप अपनी जरूरतों को पूरा करने के लिए लॉग को देखते हुए आसानी से इतिहास को सरल बना सकते हैं, लेकिन अन्य लोग अपनी जरूरतों को पूरा करने के लिए लॉग को देखते हुए इतिहास को जोड़ नहीं सकते। यही कारण है कि इतिहास को बनाए रखना बेहतर होता है।

यहां हमारे एक रिपॉजिटरी से एक उदाहरण है। हम एक पुल-रिक्वेस्ट मॉडल का उपयोग करते हैं, इसलिए प्रत्येक सुविधा इतिहास में आपकी लंबी चलने वाली शाखाओं की तरह दिखती है, भले ही वे आमतौर पर केवल एक सप्ताह या उससे कम चलती हैं। व्यक्तिगत डेवलपर्स कभी-कभी विलय से पहले अपने इतिहास को स्क्वैश करने के लिए चुनते हैं, लेकिन हम अक्सर सुविधाओं पर जोड़ते हैं, इसलिए यह अपेक्षाकृत असामान्य है। यहाँ शीर्ष कुछ में आते हैं gitk, जो गिट के साथ आता है:

मानक गिट्ट दृश्य

हां, थोड़ा सा उलझन है, लेकिन हम इसे भी पसंद करते हैं क्योंकि हम ठीक से देख सकते हैं कि किस समय क्या परिवर्तन हुआ था। यह हमारे विकास के इतिहास को सटीक रूप से दर्शाता है। यदि हम उच्च-स्तरीय दृश्य देखना चाहते हैं, तो एक समय में एक पुल अनुरोध मर्ज कर सकते हैं, हम निम्नलिखित दृश्य को देख सकते हैं, जो git log --first-parentकमांड के बराबर है :

gitk --first- जनक के साथ

git logआपके पास अपने इच्छित विचारों को देने के लिए कई और विकल्प हैं। चित्रमय दृश्य बनाने के लिए gitkकोई भी मनमाना git logतर्क ले सकते हैं । मुझे यकीन है कि अन्य GUI में समान क्षमताएं हैं। डॉक्स पढ़ें और git logमर्ज समय पर हर किसी पर अपने पसंदीदा दृश्य को लागू करने के बजाय इसे ठीक से उपयोग करना सीखें ।


24
मैं इस विकल्प से परिचित नहीं था! यह मेरे लिए बहुत बड़ी मदद है, और लगता है कि अधिक लॉग विकल्प सीखने से मुझे इस और आसानी से जीने में मदद मिलेगी।
स्टैंडबैक

25
+1 के लिए "आप अपनी आवश्यकताओं को पूरा करने के लिए लॉग देखने के दौरान आसानी से इतिहास को सरल बना सकते हैं, लेकिन अन्य लोग अपनी आवश्यकताओं को पूरा करने के लिए लॉग देखने के दौरान इतिहास को नहीं जोड़ सकते हैं।" इतिहास को फिर से लिखना हमेशा संदिग्ध होता है। अगर आपने कमिटमेंट के समय रिकॉर्ड करना जरूरी समझा तो यह महत्वपूर्ण था। भले ही आपको लगे कि यह गलत था या फिर बाद में ऐसा हुआ जो इतिहास का हिस्सा है। कुछ गलतियाँ केवल तभी समझ में आती हैं जब आप दोष में देख सकते हैं कि यह एक पंक्ति बाद में फिर से लिखने से बची थी। जब गलतियों को बाकी महाकाव्य के साथ जोड़ दिया जाता है, तो आप समीक्षा नहीं कर सकते कि चीजें क्यों समाप्त हुईं।
TafT

@Standback संबंधित, एक चीज़ जो मेरे लिए इस संरचना को बनाए रखने में मदद करती है, का उपयोग कर रही है merge --no-ff- तेजी से अग्रेषित मर्ज का उपयोग न करें, इसके बजाय हमेशा एक मर्ज कमिट बनाएं ताकि --first-parentइसके साथ काम करने के लिए कुछ हो
इज़ाकटा

34

हमारा मुद्दा दीर्घकालिक साइडब्रांचों के साथ है - जिस तरह से आपको कुछ लोग मिल रहे हैं जो एक साइडब्रंच काम करते हैं जो मास्टर से विभाजित होता है, हम कुछ महीनों के लिए विकसित होते हैं, और जब हम एक मील के पत्थर पर पहुंचते हैं तो हम दो को सिंक करते हैं।

मेरा पहला विचार है - ऐसा तब तक न करें जब तक कि बिल्कुल आवश्यक न हो। आपका मर्ज कभी-कभी चुनौतीपूर्ण होना चाहिए। शाखाओं को स्वतंत्र और यथासंभव अल्पकालिक रखें। यह एक संकेत है कि आपको अपनी कहानियों को छोटे कार्यान्वयन वाले खंडों में तोड़ने की आवश्यकता है।

इस घटना में कि आपको यह करना है, तो यह संभव है कि git --no-ff विकल्प के साथ मर्ज करें ताकि इतिहास को अपनी शाखा पर अलग रखा जा सके। मर्ज अभी भी मर्ज किए गए इतिहास में दिखाई देगा, लेकिन फीचर शाखा पर अलग से भी देखा जा सकता है ताकि कम से कम यह निर्धारित करना संभव हो सके कि वे किस लाइन के विकास का हिस्सा थे।

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


3
मैं पूर्ण समझौते में हूं; हर कोई मास्टर के करीब रहना पसंद करता है। लेकिन यह एक अलग मुद्दा है, जो मेरे अपने विनम्र प्रभाव के तहत बहुत बड़ा और बहुत कम है :-P
स्टैंडबैक

2
+1 के लिएgit merge --no-ff
0xcaff

1
इसके लिए भी +1 git merge --no-ff। यदि आप gitflow का उपयोग करते हैं, तो यह डिफ़ॉल्ट हो जाता है।
डेविड हैमन्स

10

मुझे सीधे और स्पष्ट रूप से अपनी बातों का जवाब देने दें:

हमारा मुद्दा दीर्घकालिक साइडब्रांचों के साथ है - जिस तरह से आपको कुछ लोग मिल रहे हैं जो एक साइडब्रंच काम करते हैं जो मास्टर से विभाजित होता है, हम कुछ महीनों के लिए विकसित होते हैं, और जब हम एक मील के पत्थर पर पहुंचते हैं तो हम दो को सिंक करते हैं।

आप आम तौर पर महीनों के लिए अपनी शाखाओं को बिना अनुमति के नहीं रखना चाहते हैं।

आपकी सुविधा शाखा ने आपके वर्कफ़्लो के आधार पर किसी चीज़ को बंद कर दिया है; चलो इसे masterसरलता के लिए ही कहेंगे । अब, जब भी आप गुरु के लिए प्रतिबद्ध होते हैं, आप कर सकते हैं और करना चाहिए git checkout long_running_feature ; git rebase master। इसका अर्थ है कि आपकी शाखाएँ डिज़ाइन द्वारा, हमेशा सिंक में हैं।

git rebaseयहाँ करना भी सही बात है। यह हैक या कुछ अजीब या खतरनाक नहीं है, बल्कि पूरी तरह से प्राकृतिक है। आप एक जानकारी खो देते हैं, जो कि सुविधा शाखा का "जन्मदिन" है, लेकिन यह है। अगर किसी को यह पता नहीं है कि महत्वपूर्ण होने के लिए, इसे कहीं और बचत करके प्रदान किया जा सकता है (आपके टिकट सिस्टम में, या, यदि आवश्यकता महान है, तो git tag...)।

अब, IMHO, इसको संभालने का प्राकृतिक तरीका है, साइडब्रंच को एक सिंगल कमिट में स्क्वैश करना।

नहीं, आप बिल्कुल ऐसा नहीं चाहते हैं, आप मर्ज कमिटमेंट चाहते हैं। मर्ज कमिटमेंट भी "सिंगल कमिट" है। यह, किसी भी तरह, सभी व्यक्तिगत शाखा को "मास्टर" में सम्मिलित नहीं करता है। यह दो माता-पिता के साथ एक एकल प्रतिबद्ध है - masterमर्ज के समय सिर और शाखा प्रमुख।

--no-ffविकल्प निर्दिष्ट करना सुनिश्चित करें , निश्चित रूप से; --no-ffआपके परिदृश्य में, बिना विलय के , सख्ती से मना किया जाना चाहिए। दुर्भाग्य से, --no-ffडिफ़ॉल्ट नहीं है; लेकिन मेरा मानना ​​है कि एक विकल्प है जिसे आप सेट कर सकते हैं जो इसे बनाता है। देखें git help mergeकि क्या --no-ffकरता है (संक्षेप में: यह पिछले पैराग्राफ में वर्णित व्यवहार को सक्रिय करता है), यह महत्वपूर्ण है।

हम मास्टर के इतिहास में समानांतर विकास के महीनों को डंपिंग नहीं कर रहे हैं।

बिल्कुल नहीं - आप कभी भी किसी शाखा के "इतिहास में" कुछ डंप नहीं कर रहे हैं, खासकर मर्ज कमिट के साथ नहीं।

और अगर किसी को साइडब्रंच के इतिहास के लिए बेहतर समाधान की आवश्यकता है, तो ठीक है, निश्चित रूप से यह सब अभी भी वहां है - यह सिर्फ मास्टर में नहीं है, यह साइडब्रंच में है।

मर्ज कमिटमेंट के साथ, यह अभी भी है। मास्टर में नहीं, लेकिन साइडब्रंच में, मर्ज के माता-पिता में से एक के रूप में स्पष्ट रूप से दिखाई देता है, और अनंत काल के लिए रखा जाता है, जैसा कि यह होना चाहिए।

देखो मैंने क्या किया है? सभी चीजों को आप अपने स्क्वैश के लिए वर्णन प्रतिबद्ध हैं वहीं मर्ज के साथ --no-ffकरते हैं।

यहाँ समस्या है: मैं विशेष रूप से कमांड लाइन के साथ काम करता हूं, लेकिन मेरी टीम के बाकी लोग GUIS का उपयोग करते हैं।

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

और मुझे पता चला है कि GUIS के पास अन्य शाखाओं से इतिहास प्रदर्शित करने के लिए एक उचित विकल्प नहीं है।

ऐसा इसलिए है क्योंकि आप जो करने की कोशिश कर रहे हैं वह पूरी तरह से की भावना के खिलाफ है gitgitएक "निर्देशित एसाइक्लिक ग्राफ" पर कोर से बनाता है, जिसका अर्थ है, बहुत सारी जानकारी अभिभावकों के बच्चे के संबंध में है। और, मर्ज के लिए, इसका मतलब है कि सही मर्ज दो माता-पिता और एक बच्चे के साथ होता है। जैसे ही आप no-ffमर्ज कमिट का उपयोग करते हैं, वैसे ही आपके सहयोगियों का GUI ठीक हो जाएगा ।

तो अगर आप "यह विकास शाखा XYZ से स्क्वैश" कहते हुए, एक स्क्वैश कमेटी तक पहुँचते हैं, तो यह देखने के लिए एक बड़ा दर्द है कि XYZ में क्या है।

हां, लेकिन यह GUI की समस्या नहीं है, बल्कि स्क्वैश कमिट की है। स्क्वैश का उपयोग करने का मतलब है कि आप फीचर ब्रांच हेड झूलना छोड़ दें, और एक नया कमिट बनाएं master। यह दो स्तरों पर संरचना को तोड़ता है, एक बड़ी गड़बड़ बनाता है।

इसलिए वे चाहते हैं कि ये बड़े, लंबे विकास-साइडब्रांच में विलय हो, हमेशा एक मर्ज कमिट के साथ।

और वे बिल्कुल सही हैं। लेकिन वे "विलय कर दिया नहीं कर रहे हैं में ", वे सिर्फ विलय कर रहे हैं। एक मर्ज वास्तव में संतुलित चीज है, इसका कोई पसंदीदा पक्ष नहीं है जो "अन्य" में विलय हो गया है ( git checkout A ; git merge Bबिल्कुल वैसा ही है जैसे git checkout B ; git merge Aमामूली दृश्य अंतर को छोड़कर, जैसे शाखाओं को चारों ओर स्वैप किया जा रहा है git log)।

वे ऐसा कोई इतिहास नहीं चाहते हैं जो मास्टर शाखा से तुरंत सुलभ न हो।

जो पूरी तरह से सही है। ऐसे समय में जब कोई अनमैरिड फीचर्स नहीं होते हैं, तो आपके पास एक एकल ब्रांच होगी masterजिसमें एक समृद्ध इतिहास होगा, जिसमें सभी फीचर कमिटमेंट्स कभी भी होंगे, git initसमय की शुरुआत से कमिट पर वापस जाएंगे (ध्यान दें कि मैं विशेष रूप से इस शब्द का उपयोग करने से बचता हूं " उस अनुच्छेद के उत्तरार्द्ध में शाखाएं "क्योंकि उस समय का इतिहास अब" शाखाएं "नहीं है, हालांकि प्रतिबद्ध ग्राफ काफी शाखात्मक होगा)।

मुझे उस विचार से नफरत है;

तब आप थोड़े से दर्द में होते हैं, क्योंकि आप जिस उपकरण का उपयोग कर रहे हैं, उसके खिलाफ काम कर रहे हैं। gitदृष्टिकोण विशेष रूप से शाखाओं / विलय क्षेत्र में, बहुत ही सुंदर और शक्तिशाली है; यदि आप इसे सही करते हैं (जैसा कि ऊपर दिया गया है, विशेष रूप से इसके साथ --no-ff) तो यह अन्य दृष्टिकोणों के लिए लीप्स और सीमाएं द्वारा सुपरिउर है (जैसे, शाखाओं के लिए समानांतर निर्देशिका संरचना होने की तोड़फोड़ गड़बड़)।

इसका अर्थ है समानांतर विकास के इतिहास की एक अंतहीन, अनुपयोगी उलझन।

अंतहीन, समानांतर - हाँ।

अवर्णनीय, उलझन - नहीं।

लेकिन मैं यह नहीं देख रहा हूं कि हमारे पास क्या विकल्प है।

क्यों नहीं git, अपने सहयोगियों और दुनिया के बाकी हिस्सों के आविष्कारक की तरह काम करते हैं?

क्या हमारे पास मर्ज-कमिट के साथ लगातार मास्टरबेशन को मर्ज करने के अलावा यहां कोई विकल्प है? या, क्या कोई कारण है कि लगातार मर्ज-कमिट का उपयोग करना उतना बुरा नहीं है जितना मुझे डर है?

कोई अन्य विकल्प नहीं; उतना बुरा नहीं।


10

लंबी अवधि के साइडब्रंच को स्क्वीज़ करने से आपको बहुत सारी जानकारी खोनी पड़ेगी।

मैं मास्टर में साइडब्रांच को मर्ज करने से पहले लंबे समय तक साइडब्रंच में मास्टर को रिबेट करने की कोशिश करूंगा । इस तरह से आप मास्टर को प्रतिबद्ध रखते हैं, जबकि प्रतिबद्ध इतिहास को रैखिक और समझने में आसान बनाते हैं।

अगर मैं ऐसा आसानी से नहीं कर पाऊंगा, तो मैं विकास के संदर्भ को स्पष्ट रखने के लिए इसे गैर-रेखीय होने दूंगा । मेरी राय में, यदि मेरे पास साइडब्रंच में मास्टर के विद्रोह के दौरान समस्याग्रस्त मर्ज है, तो इसका मतलब है कि गैर-रैखिकता का वास्तविक दुनिया में महत्व था। इसका मतलब यह समझना आसान होगा कि इतिहास में खुदाई करने की जरूरत है। मुझे रिबेट न करने का तत्काल लाभ भी मिलता है।


: + उल्लेख करने के लिए rebase। यहां सबसे अच्छा तरीका है या नहीं (मुझे व्यक्तिगत रूप से इसके साथ बहुत अच्छे अनुभव नहीं थे, हालांकि मैंने इसका ज्यादा इस्तेमाल नहीं किया है), यह निश्चित रूप से सबसे नजदीकी चीज है जो ओपी वास्तव में चाहता है - विशेष रूप से, एक एक आउट-ऑफ-ऑर्डर इतिहास के बीच समझौता करना और उस इतिहास को पूरी तरह से छिपाना।
काइल स्ट्रैंड

1

व्यक्तिगत रूप से मैं अपना विकास एक कांटे में करना पसंद करता हूं, फिर प्राथमिक भंडार में विलय करने के अनुरोधों को खींचता हूं।

इसका मतलब है कि अगर मैं अपने बदलावों को मास्टर के शीर्ष पर वापस करना चाहता हूं, या कुछ WIP कमिट करना चाहता हूं, तो मैं पूरी तरह से ऐसा कर सकता हूं। या मैं बस यह निवेदन कर सकता हूं कि मेरा पूरा इतिहास भी इसमें मिला दिया जाए।

मुझे जो करना पसंद है, वह एक शाखा पर मेरा विकास करना है, लेकिन अक्सर मास्टर / देव के खिलाफ विद्रोह करना। इस तरह से मुझे अपनी शाखा में मर्ज का एक समूह होने के बिना , या मर्ज संघर्षों के पूरे भार से निपटने के लिए मास्टर से सबसे हाल के बदलाव मिलते हैं, जब मास्टर में विलय करने का समय होता है।

अपने प्रश्न का स्पष्ट उत्तर देने के लिए:

क्या हमारे पास मर्ज-कमिट के साथ लगातार मास्टरबेशन को मर्ज करने के अलावा यहां कोई विकल्प है?

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


3
मुझे खेद है - मैं भी यही करता हूं, लेकिन मैं यह नहीं देखता कि यह सवाल कैसे जवाब देता है: - /
स्टैंडबैक

2
अपने स्पष्ट प्रश्न का स्पष्ट उत्तर मिला।
वेन वर्नर

तो, यह मेरे अपने काम के लिए ठीक है, लेकिन मैं (और मेरी टीम) हर किसी के काम से निपटूंगा। मेरा अपना इतिहास साफ रखना आसान है; एक गड़बड़ देव इतिहास में काम करना यहाँ मुद्दा है।
स्टैंडबैक

आपका मतलब है कि आप अन्य देवों की आवश्यकता चाहते हैं ... क्या? मर्ज पर छूट और स्क्वैश नहीं? या आप सिर्फ अपने सहकर्मियों के बारे में पकड़ अनुशासन के अभाव में इस सवाल को पोस्ट कर रहे थे?
वेन वर्नर

1
यदि कई डेवलपर्स उस सुविधा शाखा पर काम कर रहे हैं, तो नियमित रूप से रिबासिंग उपयोगी नहीं है।
पाओलो एबरमन

-1

रिवीजन नियंत्रण कचरा-इन कचरा-कचरा है।

समस्या यह है कि सुविधा शाखा में कार्य-प्रगति प्रगति में है "बहुत कोशिश कर सकते हैं ... चलो यह काम नहीं किया, चलो इसे इसके साथ बदलें" और अंतिम को छोड़कर सभी कमिट्स "कि" बस समाप्त बेकार इतिहास को अपवित्र करना।

अंततः, इतिहास को रखा जाना चाहिए (भविष्य में इसका कुछ उपयोग हो सकता है), लेकिन केवल एक "क्लीन कॉपी" का विलय होना चाहिए।

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


1
बस स्पष्ट करने के लिए: आप जो कह रहे हैं वह सुविधा-शाखा के इतिहास (एक प्रति) पर फिर से लिखना है, इसलिए इसे एक छोटा, साफ इतिहास मिल गया है - प्रारंभिक विकास के सभी पीछे-और-दूर। और फिर, फिर से लिखित शाखा को मास्टर में विलय करना सरल और साफ है। क्या मैंने आपको सही तरीके से समझा?
स्टैंडबैक

1
हाँ। और जब आप मास्टर में विलीन हो जाते हैं तो यह सिर्फ एक तेज़ फॉरवर्ड होगा (यह मानकर कि आपने हाल ही में विलय से पहले रिबेड किया है)।
डिप्रैडडैनियल

लेकिन फिर यह इतिहास कैसे रखा गया है? क्या आप मूल सुविधा शाखा के चारों ओर झूठ बोल रहे हैं?
पाओलो एबरमन

@ पाओलोबरमन बिंगो।
डिप्रेस्डडैनियल

खैर, जैसा कि किसी और ने एक टिप्पणी में कहा: शाखाएं इतिहास के ग्राफ में सिर्फ संकेत हैं git, और वे स्थानीय हैं। fooएक रेपो में जो नाम दिया गया है, उसका नाम barअलग हो सकता है । और वे अस्थायी होने के लिए हैं: आप अपने रेपो को हजारों फ़ीचर शाखाओं के साथ बंद नहीं करना चाहते हैं जिन्हें इतिहास को खोने से बचाने के लिए जीवित रखने की आवश्यकता है। और आपको इतिहास को संदर्भ में रखने के लिए उन शाखाओं को रखने की आवश्यकता gitहोगी , क्योंकि अंततः किसी भी शाखा द्वारा पहुंच योग्य किसी भी प्रतिबद्ध को हटा दिया जाएगा।
सेमीस्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.