उन पर जिस शाखा का निर्माण हुआ, उसका नाम क्यों नहीं है?


20

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

उदाहरण:

मान लीजिए कि सुविधा शाखा / मेक-कॉफी की सुविधा थी , और फीचर शाखा के समानांतर मास्टर पर बगफिक्सिंग जारी थी ।

इतिहास इस तरह दिख सकता है:

*     merge feature/make-coffee
|\
| *   small bugfix
| |
* |    fix bug #1234
| |
| *    add milk and sugar
| |
* |    improve comments
| |
* |    fix bug #9434
| |
| *    make coffe (without milk or sugar)
| |
* |    improve comments
|/
*

मुसीबत

पहली नज़र में, मुझे यह बताना मुश्किल है कि फ़ीचर ब्रांच किस तरफ है। मुझे आमतौर पर यह जानने के लिए दोनों पक्षों पर कई टिप्पणियों को ब्राउज़ करने की आवश्यकता है कि कौन सा है। यह अधिक जटिल हो जाता है यदि समानांतर में कई फीचर शाखाएं होती हैं (विशेषकर यदि वे निकट संबंधी सुविधाओं के लिए हैं), या यदि सुविधा शाखा और मास्टर दोनों के बीच निर्देशन में विलय हो रहा था।

इसके विपरीत, तोड़फोड़ में, यह काफी आसान है क्योंकि शाखा का नाम इतिहास का हिस्सा है - इसलिए मैं तुरंत बता सकता हूं कि मूल रूप से "सुविधा / मेक-कॉफ़ी" पर एक प्रतिबद्धता बनाई गई थी।

Git कमिट मेटाडेटा में वर्तमान शाखा का नाम शामिल करते समय (लेखक, तिथि आदि के साथ) बनाते हुए इसे आसान बना सकता है । हालाँकि, git ऐसा नहीं करता है।

क्या ऐसा न करने का कोई मौलिक कारण है? या यह सिर्फ इतना है कि कोई भी सुविधा नहीं चाहता था? यदि यह बाद की बात है, तो क्या बिना नाम देखे ऐतिहासिक शाखाओं के उद्देश्य को समझने के अन्य तरीके हैं?


1
संबंधित प्रश्न: यह पता लगाना कि कौन सी शाखा से आया है । यह इस जानकारी को खोजने के बारे में है कि इस तथ्य के बावजूद कि गिट इसे स्पष्ट रूप से रिकॉर्ड नहीं करता है।
सलेस्के

1
आत्म करने के लिए नोट: दिलचस्प है, मर्क्युरियल में प्रतिबद्ध है शाखा का नाम होते हैं। तो ऐसा लगता है कि मर्क्यूरियल देवों ने गिट देवों की तुलना में एक अलग डिजाइन निर्णय लिया। विवरण के लिए देखें felipec.wordpress.com/2012/05/26/…
साल्स्के

जवाबों:


14

शायद इसलिए कि शाखा के नाम केवल एक भंडार के भीतर ही सार्थक हैं। यदि मैं make-coffeeटीम में हूं और एक गेटकीपर के माध्यम से अपने सभी परिवर्तन प्रस्तुत करता हूं, तो मेरी masterशाखा गेटकीपर की make-coffee-guiशाखा में खींची जा सकती है , जिसे वह अपनी make-coffee-backendशाखा के साथ विलय कर देगा, जो make-coffeeकि एक शाखा के पुन: विलय से पहले केंद्रीय masterशाखा में विलय हो जाएगी ।

यहां तक ​​कि एक रिपॉजिटरी के भीतर भी, आपके वर्कफ़्लो के विकसित होते ही शाखा नाम बदल सकते हैं और कर सकते हैं। उदाहरण के लिए, masterबाद में बुलाया जा सकता है development

CodeGnome के रूप में alluded, git के पास डेटा की ज़रूरत नहीं होने पर डेटा में कुछ नहीं पकाने का एक मजबूत डिज़ाइन दर्शन है। उपयोगकर्ता में विकल्पों का उपयोग होने की संभावना है git logऔर git diffउनके इस तथ्य के बाद पसंद करने के लिए डेटा उत्पादन करने के लिए। मेरा सुझाव है कि जब तक आपको एक प्रारूप न मिल जाए, जो आपके लिए बेहतर हो। git log --first-parent, उदाहरण के लिए, एक शाखा से मर्ज किए जाने को नहीं दिखाएगा।


2
यह ध्यान दिया जाना चाहिए कि पहला अभिभावक आमतौर पर गलत है। क्योंकि आमतौर पर कोई भी मास्टर को काम में लगाता है और जो भी काम करता है उसे पहले माता-पिता और दूसरे को मास्टर बनाने पर जोर देता है।
Jan Hudec

1
@ जानहुडेक: वास्तव में, यह :-) पर निर्भर करता है। यदि कार्य करने वाला व्यक्ति इसमें विलीन हो जाता है, तो हाँ। यदि मर्ज बाद में होता है, हो सकता है कि एक समीक्षा के बाद, तो यह अधिक संभावना है कि समीक्षक ने मास्टर की जाँच की है और फीचर शाखा को मास्टर में विलय कर दिया है, इसका परीक्षण करता है और धक्का देता है।
१५:४४

5

ट्रैक ब्रांच हिस्ट्री साथ --no-ff

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

Git इतिहास की जानकारी के लिए आवश्यक नहीं होने के कारण शाखा जानकारी नहीं लेती है। हालांकि, विलय जो तेजी से आगे नहीं हैं, निश्चित रूप से अतिरिक्त जानकारी ले सकते हैं कि किस शाखा का विलय किया गया था। आप यह सुनिश्चित कर सकते हैं कि आपके इतिहास में हमेशा यह जानकारी शामिल --no-ffहो कि ध्वज आपके मर्जों से गुजर रहा है । गिट-मर्ज (1) कहता है:

   --no-ff
       Create a merge commit even when the merge resolves as a
       fast-forward. This is the default behaviour when merging an
       annotated (and possibly signed) tag.

यह आम तौर पर के समान एक मर्ज संदेश बनाएगा Merge branch 'foo', इसलिए आप आम तौर पर निम्नलिखित के समान एक पंक्ति के साथ "पूर्वज शाखाओं" के बारे में जानकारी पा सकते हैं:

$ git log --regexp-ignore-case --grep 'merge branch'

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

1
@ मुझे लगता है कि मेरा उत्तर उत्तरदायी था: गिट इसे ट्रैक नहीं करता है क्योंकि गिट इतिहास को इसकी आवश्यकता नहीं है; मुझे नहीं लगता कि यह उससे ज्यादा मौलिक है। आपको बारीकियों के लिए स्रोत को देखना होगा, लेकिन इतिहास को वर्तमान शाखा की नोक से पीछे की ओर प्रभावी ढंग से गणना की जाती है। आप हमेशा कुछ अन्य डीवीसीएस के साथ तुलना कर सकते हैं जो शाखाओं को प्रथम श्रेणी की वस्तुओं के रूप में मानते हैं और देखें कि क्या आप उस डिज़ाइन दर्शन को बेहतर पसंद करते हैं। YMMV।
कोडगोम सेप

1
वह आखिरी होना चाहिए git log --merges
डैन

3

सबसे सरल उत्तर यह है कि शाखाओं के नाम पंचांग हैं। क्या होगा यदि आप कहते हैं, एक शाखा का नाम बदलें ( git branch -m <oldname> <newname>)? उस शाखा के विरुद्ध सभी कमिटों का क्या होगा? या क्या होगा यदि दो लोगों की शाखाएं हैं जिनका अलग-अलग स्थानीय रिपॉजिटरी पर एक ही नाम है?

केवल एक चीज जो git में अर्थ रखती है वह है कमिटमेंट का चेकसम। यह ट्रैकिंग की मूल इकाई है।

जानकारी वहाँ है, आप बस इसके लिए नहीं पूछ रहे हैं, और इसके बिल्कुल नहीं हैं

Git प्रत्येक शाखा के प्रमुख के चेकसम को संग्रहीत करता है .git/refs/heads। उदाहरण के लिए:

... / / git / refs / सिर $ ls परीक्षण 
-rw-rw-r-- 1 मिचेल्ट मिचेल्ट 41 सितंबर 30 11:50 परीक्षण
... / / git / refs / सिर $ बिल्ली परीक्षण 
87111111111111111111111111111111111111d4

(हाँ, मैं अपने git चेकसम को क्लोब कर रहा हूं, यह विशेष नहीं है, लेकिन वे निजी रिपोजिटरी हैं जो मैं उस क्षण को देख रहा हूं जिसे कुछ भी लीक होने की आवश्यकता नहीं है)।

इसे देखकर और माता-पिता, या माता-पिता माता-पिता या माता-पिता माता-पिता के रूप में ऐसा करने वाले हर कमिटमेंट को ट्रैक करके ... आप जान सकते हैं कि किसी दिए गए वचन में कौन सी शाखाएँ हैं। यह रेंडर करने के लिए एक बड़ा ग्राफ है।

स्टोरिंग जहां विशेष रूप से एक शाखा का नाम (जो ऊपर बताए अनुसार बदल सकता है) एक कमिट में ही है, इस पर अतिरिक्त ओवरहेड है जो इसकी मदद नहीं करता है। प्रतिबद्ध के माता-पिता और उसके अच्छे को स्टोर करें।

आप उपयुक्त ध्वज के साथ git लॉग कमांड चलाकर शाखाओं को देख सकते हैं।

git log --branches --source --pretty = oneline --graph
git log --all --source --pretty = oneline --graph

इसके लिए जो आप चाहते हैं, उसे लेने के कई अलग-अलग तरीके हैं - गिट लॉग डॉक्यूमेंटेशन - -allअनुभाग और कुछ विकल्पों का अनुसरण करें।

* 8711111111111111111111111111111111111111d4 परीक्षण में मर्ज शाखा 'test1'
| \  
| * 421111111111111111111111111111111111111188 test1 अद्यतन: सामान जोड़ें
* dd1111111111111111111111111111111111111159 परीक्षण में मिलाएं 'टेस्ट 3' शाखा
| \ \  

वह 'परीक्षण', 'परीक्षण 1' और 'परीक्षण 2' वे शाखाएं हैं जिनके लिए ये प्रतिबद्ध थे।

ध्यान दें कि गिट लॉग डॉक्यूमेंट बहुत बड़ा है और इसमें से लगभग किसी भी चीज को प्राप्त करना संभव है।


3

Git के कमिट में उस शाखा का नाम क्यों नहीं है जिसे उन्होंने बनाया था?

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

BitKeeper आपदा के बाद Linus Torvalds ने लिनक्स कर्नेल विकास प्रक्रिया से मेल खाने के लिए git विकसित किया। वहां, जब तक एक पैच स्वीकार नहीं किया जाता है, तब तक इसे संशोधित किया जाता है, संपादित किया जाता है, कई बार पॉलिश किया जाता है (सभी मेल के माध्यम से), हस्ताक्षरित-बंद (= एक प्रतिबद्ध संपादन), चेरी-उठाया, लेफ्टिनेंट की शाखाओं के लिए भटकते हुए शायद अक्सर विद्रोह, अधिक हिट, चेरी -पिक्स वगैरह जब तक वे अंत में लिनुस द्वारा ऊपर की ओर विलय कर देते हैं।

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

हो सकता है कि डिजाइन का निर्णय सिर्फ संयोग से हुआ हो, लेकिन यह लिनक्स कर्नेल विकास प्रक्रिया से बिल्कुल मेल खाता है।


2

क्योंकि Git में "मेक कॉफ़ी" जैसे फीचर शाखा में विलय होने पर दोनों शाखाओं का हिस्सा माना जाता है। वहाँ भी एक आदेश की जाँच करने के लिए है कि:

% git branch --contains @
  feature/make-coffee
  master

इसके अलावा, शाखाएँ सस्ती, स्थानीय और ईथर हैं; सर्वर से उन्हें आसानी से जोड़ा जा सकता है, हटाया जा सकता है, नाम बदला जा सकता है, धक्का दिया जा सकता है और हटाया जा सकता है।

Git उस सिद्धांत का पालन करता है जो सब कुछ किया जा सकता है, जिसके कारण आप आसानी से एक दूरस्थ सर्वर से एक शाखा निकाल सकते हैं, और आप आसानी से इतिहास को फिर से लिख सकते हैं।

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

मर्क्यूरियल विपरीत है; यह चीजों को बदलना नहीं चाहता है। शाखाएं स्थायी हैं, इतिहास को फिर से लिखा गया है, आप सर्वर से एक शाखा को हटा नहीं सकते हैं।

संक्षेप में: Git आपको सब कुछ करने की अनुमति देता है, मर्क्यूरियल चीजों को आसान बनाना चाहता है (और इससे आपको जो करना चाहते हैं उसे करने में वास्तव में मुश्किल होती है)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.