मुकाबला: Git Rebase के खिलाफ Merge
एक समयरहित सवाल...
मृत्यु मुकाबला: Git Rebase vs. (Squash) Merge!
मैं Rebase करूँ? या Squash Merge करूँ?
- क्या यह व्यक्तिगत पसंद है?
- उत्तर: नहीं, जब एक या अधिक टीमें शामिल हों! दोनों में से एक चयन अन्य की उपयोगिता को प्रभावित करेगा!
क्यों यह विषय धार्मिक उत्साह को जगाता है?
कुछ इंजीनियर git (& टर्मिनल) के ज्ञान का उपयोग अपने सापेक्ष कौशल स्तर के संकेत के रूप में करते हैं। और हमारी पहचान/अहंकार से जुड़ी कोई भी प्रथा निष्पक्ष रूप से विश्लेषित करने के लिए असंभव हो सकती है, न कि बदलने के लिए।
अन्य कारकों में परिचय और सर्वाइवरशिप बायास शामिल हो सकते हैं, जो हमारे स्वयं के आकलन और पूर्वाग्रह को भी गैर-स्पष्ट कर सकते हैं।
मुख्य प्रश्न: गिट कमिट का उद्देश्य क्या है?
-
क्या आप अक्सर शुरुआत में और बार-बार कमिट करते हैं? “चेकपॉइंट” या बैकअप मानसिकता के साथ?
- जहां हर चीज रिकॉर्ड की जाती है, भले ही गलत शुरुआत या प्रयोग हों? (उदाहरण:
git commit -am "Updated deps" && git push, नियमित रूप से दोहराएं) - शायद कमिट संदेश आपके लिए कोड की तुलना में कम महत्वपूर्ण हैं?
- जहां हर चीज रिकॉर्ड की जाती है, भले ही गलत शुरुआत या प्रयोग हों? (उदाहरण:
-
या फिर, आपके कमिट ध्यानपूर्वक चयनित, आकृति-विहीन कला के टुकड़े हैं?
- शायद प्रत्येक कमिट एक स्वतंत्र, परमाणु इकाई कार्य है? (उदाहरण:
git add package.json && git commit -m "Updated deps") - या फिर आपको “बिगड़े हुए” कमिट लॉग से बस नहीं रहता?
- क्या आपकी पीआर रिव्यू में अक्सर कमिट-दर-कमिट रिव्यू शामिल होते हैं?
- शायद प्रत्येक कमिट एक स्वतंत्र, परमाणु इकाई कार्य है? (उदाहरण:
| 💡 अन्य मानसिक मॉडल क्या हैं जो आपको कमिट के बारे में सोचने के तरीके को परिभाषित करते हैं? कृपया मुझे बताएं @justsml!
क्या आप गिट के बारे में ऐसे सोच रहे हैं जो आपके लिए, आपकी टीम के लिए और आपके संगठन के लिए सबसे अधिक मूल्य प्रदान कर रहा है?
यह तय करना कि कमिट रणनीति के आसपास कितने अलग-अलग मानसिक मॉडल हैं, इसलिए गिट का उपयोग करने का “सही” तरीका क्या है इस बारे में इतना भ्रम होना अजीब नहीं है।
परिदृश्य: एक संशोधित रिलीज टैग बनाएं
चलिए इस प्रक्रिया की तुलना करते हैं जिसमें मेन पर कुछ हालिया कमिट्स को छोड़कर एक टैग रिलीज बनाया जाता है।
रीबेस तरीका
मानसिक मॉडल: “मैं एक मौजूदा इतिहास का वैकल्पिक संस्करण बनाना चाहता हूं। (उदाहरण के लिए, मैंने 16 मर्ज के बाद एक गलती की है, और इसे सुधारने के लिए विस्तृत नियंत्रण की आवश्यकता हो सकती है। इसके अलावा, झगड़ा और --continue के दीखने में अनंत चक्र में फंस सकते हैं।)”
- अपडेट:
git checkout main&&git pull - नया ब्रांच बनाएं:
git checkout -b release/hot-newness-and-stuff - इंटरैक्टिव रीबेस शुरू करें और वापस जाने वाले गिट रिफ को शामिल करें।
git rebase -i HEAD~6(नोट:HEAD~6यह6 commits agoके लिएgit refका संक्षिप्त रूप है) - ड्रॉप करने वाले कमिट को
dropप्रीफिक्स के साथ बदलें। एडिटर को सेव और बंद करें। - मर्ज झगड़े को ठीक करें,
git add .&&git rebase --continue(कभी भीgit commitन करें)। - पिछले चरण को दोहराएं जब तक पूरा न हो जाए।
- वर्तमान प्रक्रिया का उपयोग करके टैग/पुश करें। उदाहरण
git tag -a v1.2.3 -m 'Release v1.2.3'&&git push --tags
लाभ
- 🔌 अपने इतिहास को बदलने की पूरी शक्ति।
नुकसान
- 😰 अपने इतिहास को बदलने की पूरी शक्ति। (ओके, एक लाभ और नुकसान…)
- 🔂 आप झगड़ा और
--continueके दीखने वाले अनंत चक्र में फंस सकते हैं। (कभी-कभी यहां तक किgit rerereके साथ भी) - 🙀 महत्वपूर्ण सहयोग विशेषताओं को तोड़ देता है: खोए हुए/अपनाहीन PR टिप्पणियाँ। असभ्य।
- 🖇️ परमानंत लिंक्स वास्तव में इतने परमानंत नहीं रहते।
(स्क्वैश) मर्ज तरीका
--- CHUNK END ---
मानसिक मॉडल: “मैं एक निश्चित बिंदु से शुरू होने वाला एक कस्टम रिलीज चाहता हूँ, और इसमें कोई भी वांछित शाखा (ओं) शामिल होगी।”
- नवीनतम प्राप्त करें:
git checkout main&&git pull - नई शाखा बनाएं:
git checkout -b release/hot-newness-and-stuff - वांछित शाखाओं और/या कमिटों को मर्ज करें:
git merge --no-ff feature/hot-newness bug/fix-123(जहां संभव हो,--no-ffफ्लैग का उपयोग करें।) - मर्ज संघर्ष को ठीक करें (अगर आता है।)
- वर्तमान प्रक्रिया का उपयोग करके टैग/पुश करें। उदाहरण
git tag -a v1.2.3 -m 'Release v1.2.3'&&git push --tags
लाभ
- 💪 कम प्रक्रिया, कम संघर्ष, और मौजूदा गिट कमांड ज्ञान का उपयोग करता है।
- 🚀 आप पीआर/शाखा स्तर पर सोच सकते हैं, कमिट स्तर की विस्तृतता को नजरअंदाज करते हुए (जब तक आवश्यक न हो।)
- 🦺 अपरिवर्तित। आप कभी भी पीछे जा सकते हैं और/या नई शाखाएँ बना सकते हैं।
- 🎥 मौजूदा कमिट और संदेशों को पूर्ण रूप से छोड़ देता है, जिससे ‘ब्लेम’ शोर कम होता है।
नुकसान
- 🔏 कमिट संदेशों को बदलना मुश्किल है।
- 🤐 अपने काम को छिपाना मुश्किल है।
निष्कर्ष
अंत में, एक सरल प्रक्रिया जो कम जोखिम वाली हो, वह जीत जानी चाहिए।
हालांकि रीबेसर्स के पास अपनी समस्याओं को हल करने (या बचने) के तरीके होते हैं, लेकिन वास्तविकता यह है: आपको अंततः गिट फू में काला पट्टा चाहिए। (उदाहरण के लिए, एक सामान्य git push भी अतिरिक्त जटिलता का सामना कर सकता है: क्या यह git push --force या git push --force-with-lease होगा? इसे बिल्कुल क्यों उठाएं?)
एक और वजह है कि रीबेसिंग एक संशोधित इतिहास बनाने में हमेशा git merge ... की तुलना में अवनत होगा। git merge कमांड git CLI को उन्नत एल्गोरिदम लागू करने देता है जो प्रत्येक शाखा के HEAD का विश्लेषण करके असहमति को टालते हैं।
यह बुद्धिमान हो सकता है क्योंकि प्रत्येक मर्ज केवल शाखा की अंतिम स्थिति पर ध्यान केंद्रित करता है। जबकि रीबेसिंग कमिट इतिहास को फिर से खेलना (या छोड़ देना) पड़ता है जैसा कि निर्दिष्ट किया गया है। यह git की अनुकूलन क्षमता को सीमित कर देता है क्योंकि यह एक समय में केवल 2 कमिट्स की तुलना करता है।
अंततः रीबेसिंग का मतलब आपको अप्रासंगिक पुराने कमिट्स और संघर्षों का फिर से अनुभव करना पड़ सकता है - भले ही आप जानते हैं कि उन्हें बाद में हटा दिया गया है या सुलझा लिया गया है।
सारांश
- 💃 उत्तर: एसक्वेश मर्ज करें अपने PR को
mainमें।- आपकी शाखा इतिहास जरूरत पड़ने पर वहां रहेगा, और
mainअपेक्षाकृत “स्वच्छ” रहेगा।
- आपकी शाखा इतिहास जरूरत पड़ने पर वहां रहेगा, और
- 🔤 हमेशा कमिट करते रहें!
-
95% कॉर्पोरेट परियोजनाओं में “बैकअप माइंडसेट” “सुसज्जित कला” माइंडसेट की तुलना में अधिक उपयुक्त होता है। समय के साथ, आपके कमिट संदेशों का अर्थ तेजी से खो जाएगा, जबकि कोड के तर्क और टेस्ट अपना महत्व बनाए रखेंगे।
-
- आप
git checkoutके साथ विशेष--अलगाव का उपयोग कर सकते हैं ताकि निर्दिष्ट फ़ाइलों की प्रतिलिपि बनाते हुए वर्तमान शाखा में रहे। git checkout feature/half-a-feature **--** <folder or file path>- सुनिश्चित करें कि आपने पहले उन सभी परिवर्तनों को कमिट कर दिया है जिन्हें आप बरकरार रखना चाहते हैं, क्योंकि यह कोई भी स्थानीय परिवर्तन ओवरराइट कर देगा।