मैं कैसे बता सकता हूं कि एक प्रतिबद्ध दूसरे प्रतिबद्ध का वंशज है?


146

Git के साथ, मैं कैसे बता सकता हूं कि मेरी शाखा में एक प्रतिबद्ध दूसरे प्रतिबद्ध का वंशज है?


2
एक ही सवाल के विपरीत पूछा: stackoverflow.com/questions/18345157/…
क्रिस क्लीलैंड

11
क्या आप अपना स्वीकृत उत्तर बदल सकते हैं? बहुमत --is-ancestorसमाधान पसंद करता है।
रॉबर्ट सिएमर

जवाबों:


51

यदि आप इस प्रोग्राम की जाँच करना चाहते हैं (जैसे स्क्रिप्ट में), तो आप जाँच सकते हैं कि git merge-base A Bक्या बराबर है git rev-parse --verify A(तब A, B से उपलब्ध है) या यदि ऐसा है git rev-parse --verify B(तब B A से उपलब्ध है)। git rev-parseयहाँ SHA-1 / प्रतिबद्ध आईडी करने के लिए प्रतिबद्ध नाम से परिवर्तित करने की आवश्यकता है।

VonC उत्तर कीgit rev-list तरह उपयोग करना भी संभावना है।

संपादित करें: आधुनिक गिट में इस क्वेरी के रूप में स्पष्ट समर्थन है git merge-base --is-ancestor


यदि आप जिन कमिट्स के बारे में पूछ रहे हैं , वह एक ब्रांच टिप है , तो बेहतर हो सकता है git branch --contains <commit>या git branch --merged <commit>नॉन-प्रोग्रामेटिक सॉल्यूशन।


1
संभवतः सबसे तेज़ तरीका होगा git checkout -b quickcheck <more-recent-commit-ID>और फिर git branch --contains <older-commit-ID>(और फिर git branch -D quickcheckअस्थायी शाखा से छुटकारा पाने के लिए)।
clee

2
दो संभव दृष्टिकोण, दोनों ही @ मैटर के उत्तर में एक से भी बदतर हैं।
12

6
@jwg: मैटर का उत्तर बेहतर है, लेकिन यह उत्तर (और शायद इसे स्वीकार किया जा रहा है) git 1.8.0 और git merge-base --is-ancestor2 साल से पहले का है।
जकुब नारबस्की

@ JakubNar Jakbski फेयर काफी, सॉरी।
14:24 बजे jwg

2
बड़े भंडार (2 मिलियन कमिट) में, मैंने की गति की तुलना की git branch --contains <commit>और git merge-base --is-ancestor ...: 3m40s बनाम 0.14s
हैगेलो

259

Git 1.8.0 से, यह एक विकल्प के रूप में समर्थित है merge-base:

git merge-base --is-ancestor <maybe-ancestor-commit> <descendant-commit>

आदमी पृष्ठ से:

--is-पूर्वज

जांचें कि क्या पहला दूसरे का पूर्वज है, और स्थिति 0 के साथ बाहर निकलें यदि सही है, या स्थिति 1 के साथ यदि नहीं। त्रुटियों को गैर-शून्य स्थिति से संकेत दिया जाता है जो कि 1 नहीं है।

उदाहरण के लिए:

git merge-base --is-ancestor origin/master master; echo $?

4
अच्छा! यहाँ एक शेल स्क्रिप्ट है जो मानव-पुन: प्रयोज्य
साइमन व्हिटेकर

1
दूसरे शब्दों में: git merge-base THING --is-ancestor OF_THING && echo yes || echo noजैसे:git merge-base my-feature-branch --is-ancestor master && echo yes || echo no
user1735594

2
@smarber git merge-base --is-ancestor -- commit commitमेरी तरफ से git2.1.4 (Debian / Devuan 7.10 jessie) और 1.9.1 (Ubuntu 14.04 भरोसेमंद) के साथ हैश के लिए काम करता है जो अब प्राचीन नहीं हैं। यह डेबियन मट्ठा के लिए भी काम करता है, यदि आप करते हैं sudo apt-get install git/wheezy-backports
टीनो

15

इस तरह के ऑपरेशन एसओ प्रश्न में विस्तृत संशोधनों की श्रेणी की धारणा पर निर्भर करते हैं : " गिट लॉग मूल / मास्टर 'बनाम' गेट लॉग मूल / मास्टर .. 'में अंतर "।

git rev-list वापस आने तक एक कमिट से वापस चलने में सक्षम होना चाहिए।

तो मैं कोशिश करूँगा:

git rev-list --boundary 85e54e2408..0815fcf18a
0815fcf18a19441c1c26fc3495c4047cf59a06b9
8a1658147a460a0230fb1990f0bc61130ab624b2
-85e54e240836e6efb46978e4a1780f0b45516b20

(सीमा के साथ उपसर्ग कर रहे हैं -)

अगर अंतिम कमिटमेंट git rev-listकमांड में पहले कमिट के समान है , तो यह दूसरी कमिट से आने वाली कमिटमेंट है।

यदि पहली प्रतिबद्ध दूसरे से पहुंच योग्य नहीं है, तो git rev-listकुछ भी नहीं लौटाना चाहिए।

git rev-list --boundary A..B

द्वारा पहुंच से बाहर होने पर A, समाप्त होगा । यह इस प्रकार है:AB

git rev-list --boundary B --not A

, के साथ Bएक सकारात्मक संदर्भ , और Aएक नकारात्मक संदर्भ
यह तब से शुरू होगा Bऔर ग्राफ़ के माध्यम से वापस चलेगा जब तक कि यह एक संशोधन का सामना नहीं करता है जो इससे उपलब्ध है A
मैं यह तर्क दूंगा कि यदि Aसीधे से पहुंच योग्य है B, तो यह मुठभेड़ (और प्रदर्शन, --boundaryविकल्प के कारण) Aही होगा।


यह एक सामान्य-पर्याप्त उपयोग-मामला जैसा लगता है कि मुझे आश्चर्य है कि गिट ने अभी तक एक "पोर्सिलेन" कमांड प्रकाशित नहीं किया है जो वास्तव में ऐसा करता है।
लॉरेंस आई। सिडेन

1
@lsiden: सच। साइड-नोट: यह मत भूलो कि किसी प्रोग्राम को जाँचने के लिए , आपको पोर्सिलेन कमांड का उपयोग नहीं करना चाहिए, (जैसा कि stackoverflow.com/questions/6976473/… ), लेकिन प्लंबिंग कमांड (जैसा कि stackoverflow.com/questions में चित्रित किया गया है) / 3878624 / ... )
VonC

ओह, यार, ऐसा लग रहा है कि मुझे वापस जाना है और अपने शेल स्क्रिप्टिंग चॉप्स पर काम करना है!
लॉरेंस आई।

1
प्रश्न: -85e54e2...स्निपेट में माइनस क्यों होता है ? यह भी एक संभावित टाइपो: "... पहली प्रतिबद्ध की तुलना में एक ही है ..."
sadaau

1
@ सादाऊ का -अर्थ है, यह एक सीमाबद्ध प्रतिबद्धता है। मैंने उस स्पष्ट बनाने के लिए, साथ ही साथ डॉक्स लिंक को ताज़ा करने और इस 5 साल पुराने उत्तर के लिए टाइपो को ठीक करने के लिए उत्तर को संपादित किया है।
VonC

11

एक और तरीका होगा उपयोग git logऔर grep

git log --pretty=format:%H abc123 | grep def456

यह आउटपुट की एक लाइन का उत्पादन करेगा यदि प्रतिबद्ध डी 456 प्रतिबद्ध एबीसी का पूर्वज है, या अन्यथा कोई आउटपुट नहीं।

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


मुझे उम्मीद है कि यह समाधान धीमा होगा, लेकिन यह वास्तव में काफी तेज है, यहां तक ​​कि 20k + कमिट के साथ एक परियोजना के लिए
रेनैटो ज़नॉन

2
इसके बजाय --prettyमैं का उपयोग करें - ऑनलाइन: git log --oneline ce2ee3d | grep ec219ccमहान काम करता है
जेन्स

3

https://stackoverflow.com/a/13526591/895245 इसका उल्लेख करते हैं, अब इसे और अधिक मानवीय अनुकूल बनाने के लिए:

git-is-ancestor() (
  if git merge-base --is-ancestor "$1" "$2"; then
      echo 'ancestor'
  elif git merge-base --is-ancestor "$2" "$1"; then
      echo 'descendant'
  else
      echo 'unrelated'
  fi
)
alias giia='git-is-ancestor'

यह 'असंबंधित' वापस आ जाएगा यदि दोनों पैरामीटर एक ही प्रतिबद्ध के लिए इंगित करते हैं
15

1

git show- Branch Branch-sha1 कमिट-शा 1

कहाँ पे:

  • शाखा-शा 1: जिस शाखा में आप जाँच करना चाहते हैं वह शा 1 है
  • प्रतिबद्ध- sha1: आप जिस कमिटमेंट के खिलाफ जांच करना चाहते हैं, उसका sha1

0

यदि आप उपयोग कर रहे हैं git merge-base --is-ancestor, तो Git 2.28 (Q3 2020) का उपयोग करना सुनिश्चित करें

Git 2.28 (Q3 2020) के साथ, " struct commit" में मौजूद कुछ क्षेत्रों को हमेशा स्लैब बनाने के लिए स्थानांतरित नहीं किया जाता है।

देखें प्रतिबद्ध c752ad0 , प्रतिबद्ध c49c82a , 4844812 प्रतिबद्ध , 6da43d9 (17 जून 2020) अभिषेक कुमार ( abhishekkumar2718) द्वारा
(द्वारा विलय Junio सी Hamano - gitster- में प्रतिबद्ध d80bea4 , 06 जुला 2020)

commit-graph: परिचय commit_graph_data_slab

साइन-ऑफ-बाय: अभिषेक कुमार

कई संदर्भों में संरचनात्मक प्रतिबद्ध का उपयोग किया जाता है। हालांकि, सदस्यों generationऔर graph_posकेवल प्रतिबद्ध-ग्राफ़ से संबंधित संचालन के लिए उपयोग किया जाता है और अन्यथा मेमोरी बर्बाद हो जाती है।

यह अपव्यय अधिक स्पष्ट होगा क्योंकि हम पीढ़ी संख्या v2 में संक्रमण करते हैं, जो वर्तमान 32-बिट्स के बजाय 64-बिट पीढ़ी संख्या का उपयोग करता है।

जैसा कि वे अक्सर एक साथ पहुंचते हैं, चलो संरचना शुरू करते हैं commit_graph_dataऔर उन्हें एक commit_graph_dataस्लैब में स्थानांतरित करते हैं ।

जबकि समग्र परीक्षण सूट बस के रूप में तेजी से चलता है master, (श्रृंखला: 26m48s master: 27m34s, तेजी से 2.87%), कुछ आज्ञाओं की तरह git merge-base --is-ancestor40% द्वारा धीमा कर दिया गया था जैसा कि Szeder Gábor द्वारा खोजा गया था
कम-स्लैब पहुंच को कम करने के बाद, धीमा धीमा बना रहता है लेकिन 20% के करीब है।

डेरिक स्टोले का मानना ​​है कि धीमे-धीमे कमिट-स्लैब एक्सेस की सुस्ती के बजाय अंतर्निहित एल्गोरिथ्म के लिए जिम्मेदार है और हम बाद की श्रृंखला में अनुवर्ती करेंगे।


-1

यदि आप रिपॉजिटरी में सभी टैग के लिए ऐसा करना चाहते हैं, तो इटब के उत्तर पर बिल्डिंग करना:

for i in `git tag` ; do echo -ne $i "\t" ; git log --pretty=format:%H $i | (grep <commit to find> || echo ""); done
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.