28 पॉइंट द्वारा GN⁺ 2023-11-24 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • बहुत से लोगों को लगता है कि Git branch जिस तरह काम करती है, वह सहज नहीं है
  • यह Git branch के बारे में सामान्य सहज मॉडल और Git के अंदर branch वास्तव में कैसे दर्शाई जाती है, इनके बीच के अंतर को समझाता है
  • यह दिखाता है कि सहज मॉडल और Git के वास्तविक काम करने के तरीके के बीच वास्तव में बहुत करीबी संबंध है
  • यह सहज मॉडल की सीमाओं और यह क्यों समस्याएँ पैदा कर सकता है, इस पर चर्चा करता है

सहज ब्रांच मॉडल

  • बहुत से लोग branch को 'सेब के पेड़ की शाखा' जैसी उपमा से समझते हैं।
  • Git में branch के लिए 'parent' जैसी कोई अवधारणा नहीं होती, इसलिए इसे main से निकली हुई चीज़ मानना पूरी तरह सही नहीं है।

Git में branch पूरा history होती है

  • Git में branch सिर्फ अलग हुई commits का समूह नहीं है, बल्कि उसमें उससे पहले की पूरी history शामिल होती है।
  • उदाहरण repository के माध्यम से यह दिखाया गया है कि main और mybranch दोनों में 4 commits हैं।

branch commit ID के रूप में संग्रहीत होती है

  • Git के अंदर branch एक छोटी text file के रूप में संग्रहीत होती है, जिसमें commit ID होती है।
  • हर branch की सबसे नई commit उस file में दर्ज होती है।
  • commits के बीच parent-child संबंध branch स्तर पर नहीं होने के कारण, Git branches के बीच के संबंध को नहीं जानता।

लोगों का अंतर्ज्ञान आम तौर पर इतना गलत नहीं होता

  • लोगों के Git संबंधी अंतर्ज्ञान को 'गलत' कहना कुछ हद तक मूर्खतापूर्ण है।
  • 'गलत' मॉडल भी वास्तव में उपयोगी हो सकता है।

rebase 'सहज' branch अवधारणा का उपयोग करता है

  • rebase केवल 'सहज' branch की commits को main पर फिर से लागू करता है।
  • rebase का परिणाम सहज मॉडल से मेल खाता है।

merge भी 'सहज' branch अवधारणा का उपयोग करता है

  • merge commits को कॉपी नहीं करता, लेकिन उसे साझा base commit की ज़रूरत होती है।
  • merge base सहज मॉडल के आधार पर वह commit ढूँढता है जहाँ branch अलग हुई थी।

GitHub pull request भी सहज विचार का उपयोग करता है

  • GitHub में जब mybranch को main में merge करने के लिए pull request बनाया जाता है, तो वह केवल सहज branch की commits दिखाता है।

अंतर्ज्ञान अच्छा है, लेकिन इसकी सीमाएँ हैं

  • सहज branch की परिभाषा वास्तविक Git कार्यप्रणाली से अच्छी तरह मेल खाती है, लेकिन Git main और उससे अलग हुई branch को अलग तरह से पहचान नहीं पाता।

trunk और अलग हुई branches

  • लोग main और mybranch को अलग तरह से देखते हैं, और इसका असर Git इस्तेमाल करने के तरीके पर पड़ता है।
  • Git यह भेद नहीं करता कि कोई branch दूसरी branch से 'निकली' हुई है या नहीं।

Git rebase को 'उल्टी दिशा' में भी कर सकता है

  • Git यह नहीं बताता कि कौन-सी branch किस branch से निकली है, इसलिए कब और किस branch को rebase करना है, यह उपयोगकर्ता को खुद जानना पड़ता है।
  • git rebase main और उल्टी दिशा वाला rebase git rebase mybranch दोनों संभव हैं। merge के साथ भी यही बात लागू होती है

Git branches के बीच hierarchy का न होना कुछ अजीब है

  • main branch के विशेष न होने की बात इसलिए आती है क्योंकि Git branches के बीच संबंधों को पहचान नहीं पाता।
  • branches के बीच संबंध तो होते हैं, लेकिन Git को उनके बारे में कुछ पता नहीं होता

Git branch UI भी अजीब है

  • जब आप केवल 'अलग हुई' commits देखना चाहते हैं, तो git log और git diff का उपयोग करने का तरीका अलग होता है।

GitHub में default branch विशेष होती है

  • GitHub में एक 'default branch' होती है, जिसकी एक विशेष भूमिका होती है।

GN⁺ की राय

इस लेख की सबसे महत्वपूर्ण बात यह है कि Git branch को लेकर लोगों की सहज समझ और Git के वास्तविक काम करने के तरीके के बीच के अंतर को समझा जाए। यह लेख शुरुआती software engineers को Git branch की अवधारणा को बेहतर समझने और उसे अधिक प्रभावी ढंग से उपयोग करने में मदद करेगा। Git branch के सहज मॉडल का वास्तविक काम से कैसे मेल बैठता है, और Git branches के बीच संबंधों को कैसे नहीं संभालता, यह समझना रोचक और उपयोगी है।

1 टिप्पणियां

 
GN⁺ 2023-11-24
Hacker News राय
  • ब्रांच एक pointer होता है जो commit को दिखाता है, और हर नए commit के बनने पर यह pointer अपडेट हो जाता है। ब्रांच को tag की तरह घूमता-फिरता नाम भी माना जा सकता है। क्योंकि commit खुद अपने parent commit को दिखाता है, इसलिए ब्रांच दरअसल संबंधित commits की एक chain होती है, जिसका एक named entry point होता है। ब्रांच को delete करने पर वह named label हट जाता है, और फिर सिर्फ संबंधित commits की chain बचती है।
  • Commit की lineage को 'आगे' नहीं बल्कि 'पीछे' की ओर इशारा करने वाले pointer की तरह सोचें तो समझना आसान होता है। ब्रांच एक commit ID है, इसलिए parent links को पीछे की ओर follow करने पर उस ब्रांच का पूरा इतिहास मिल जाता है। 'ब्रांच पॉइंट' वह जगह है जहाँ दो commit chains मिलती हैं, और merge commit खास होता है क्योंकि वह दिखाता है कि दो histories एक में मिल गई हैं।
  • पर्सनल प्रोजेक्ट्स में मैं git reset --hard और git stash का इस्तेमाल करके changes और branch pointers को manipulate करता हूँ, और मेरे दोस्त यह देखकर अक्सर नाराज़ हो जाते हैं। गलत merge को undo करने के लिए git reset --hard <merge से पहले का आख़िरी commit> का इस्तेमाल करता हूँ, और local branch के छोटे changes को main branch पर लागू करने के लिए पहले git stash करता हूँ, फिर main branch पर checkout करके git stash apply चलाता हूँ।
  • Git में 'main special है' जैसी कोई अवधारणा नहीं है, लेकिन GitLab जैसे tools protected branch फीचर देते हैं जिससे गलतियाँ कम हो सकती हैं। 'parent' और 'child' branch की अवधारणा वास्तव में दिलचस्प हो सकती है, और long-term support branches के लिए कई 'parent' branches को support करना चाहिए।
  • Merge, rebase, और pull request करते समय दूसरी branch को साफ़ तौर पर specify करना पड़ता है। Git को यह नहीं पता होता कि आप किस branch को base मान रहे हैं। कभी-कभी आप एक feature branch को दूसरी feature branch में merge करना चाह सकते हैं, इसलिए यह स्पष्ट रूप से बताना ज़रूरी है कि कौन-सी branch किस branch में merge हो रही है।
  • लोगों की intuition तकनीकी रूप से आंशिक रूप से गलत हो सकती है, फिर भी उनके पास ऐसी intuition होने की ठोस वजह होती है।
  • git add और git commit का इस्तेमाल जानने वालों के लिए एक dynamic tutorial है। यह tutorial branches को visualize करता है और पढ़ते समय समझने में मदद करता है।
  • अगर आप याद रखें कि Git command चलाते समय 'हमेशा' current branch ही modify होती है, तो Git का syntax 'आसानी' से समझ में आता है। उदाहरण के लिए, git merge my-branch current branch में my-branch को merge करता है, और git rebase my-branch current branch को my-branch के ऊपर rebase करता है।
  • अच्छा होगा अगर branch (head) के पास एक 'tail' भी हो जो उस base commit को दिखाए जहाँ से वह branch शुरू हुई थी। Branches अक्सर rebase होती रहती हैं, इसलिए कभी-कभी यह सोचना पड़ता है कि वे शुरू कहाँ से हुई थीं। अगर Git यह बता दे कि base commit main से संबंधित है, तो यह और सुविधाजनक होगा।
  • Mailing list पर 'patch' भेजते समय वैकल्पिक रूप से base commit शामिल किया जा सकता है। इसकी वजह यह है कि यह हमेशा साफ़ नहीं होता कि changes latest release, main development branch, या integration branch में से किस पर आधारित हैं। git range-diff इस्तेमाल करते समय भी base को ध्यान में रखना पड़ता है। यह tool main..previous और main..current जैसी दो ranges की तुलना करता है।
  • ब्रांच पर अपने निजी विचारों को फिर से पढ़ते हुए मैंने कुछ ऐसी बातें दोबारा सीखीं जिन्हें मैं भूल चुका था।