(यह एक डुप्लिकेट प्रश्न के उत्तर के रूप में शुरू हुआ था। मैंने इसे साफ करने के लिए हल्का संपादन किया है।)
Git के सभी आंतरिक तीर एक तरफ़ा हैं, जो पीछे की ओर इशारा करते हैं। इसलिए आगे बढ़ने के लिए कोई छोटा सुविधाजनक वाक्यविन्यास नहीं है: यह सिर्फ संभव नहीं है।
यह है अगर आप इसे से पहले बाद में नहीं देखा है, और फिर स्पष्ट "तीर के खिलाफ कदम" है, लेकिन जिस तरह से यह आश्चर्य की बात है क्या करने के लिए करने के लिए संभव। मान लें कि हमारे पास है:
A <-B <-C <-D <-E <-- last
^
|
\--------- middle
पीछे middle~2
से दो बार तीरों का उपयोग करना । तो हम से कैसे ले जाऊं करने के लिए ? जवाब है: हम पर शुरू , नाम का उपयोग कर , और काम पीछे की ओर जब तक हम करने के लिए मिल , अंक हम रास्ते को रिकॉर्ड । फिर हम केवल उसी दिशा में आगे बढ़ते हैं, जिस दिशा में हम चाहते हैं : एक-एक कदम , या दो से ।C
A
C
D
E
last
middle
last
D
E
जब हमारे पास शाखाएँ हों तो यह विशेष रूप से महत्वपूर्ण है:
D--E <-- feature1
/
...--B--C <-- master
\
F--G <-- feature2
एक कदम के बाद कौन सा प्रतिबद्ध है C
? जब तक आप सवाल नहीं जोड़ते हैं, तब तक कोई सही उत्तर नहीं है: feature___ (रिक्त स्थान भरें) की दिशा में ।
स्वयं C
(और छोड़कर C
) के बीच के कमिट्स की गणना करने के लिए G
, हम उपयोग करते हैं:
git rev-list --topo-order --ancestry-path master..feature2
यह --topo-order
सुनिश्चित करता है कि जटिल ब्रांचिंग-एंड-मर्जिंग की उपस्थिति में भी, कम्यूट टोपोलॉजिकली-सॉर्ट किए गए क्रम में निकलते हैं। यह केवल तभी आवश्यक है जब श्रृंखला रैखिक न हो। --ancestry-path
बाधा साधन जब हम से पीछे की ओर काम करते हैं कि feature2
, है कि हम केवल सूची प्रतिबद्ध प्रतिबद्ध C
अपने स्वयं के पूर्वजों में से एक के रूप में। यह है, अगर ग्राफ - या प्रासंगिक हिस्सा वैसे भी - वास्तव में इस तरह दिखता है:
A--B--C <-- master
\ \
\ F--G--J <-- feature2
\ /
H-------I <-- feature3
फार्म की एक साधारण अनुरोध feature2..master
करता विश्लेषण करता है J
, G
और I
, और F
और H
किसी क्रम में। साथ --ancestry-path
हम बाहर दस्तक H
और I
वे के वंशज नहीं हैं C
केवल की, A
। साथ --topo-order
हम चाहते हैं कि वास्तविक गणना आदेश है यह सुनिश्चित कर लें J
, तो G
, तो F
।
git rev-list
आदेश अपने मानक उत्पादन, प्रति पंक्ति एक पर बाहर इन हैश आईडी फैल। की दिशा में एक कदम आगे बढ़ने के लिए feature2
, फिर, हम केवल अंतिम पंक्ति चाहते हैं ।
इसे जोड़ना संभव है (और लुभाना और उपयोगी हो सकता है) --reverse
ताकि git rev-list
उन्हें उत्पन्न करने के बाद उल्टे क्रम में कमेंट प्रिंट किया जा सके। यह काम करता है, लेकिन अगर आप इसे इस तरह से पाइपलाइन में उपयोग करते हैं:
git rev-list --topo-order --ancestry-path --reverse <id1>...<id2> | head -1
बस "id2 की दिशा में अगली प्रतिबद्धता" प्राप्त करने के लिए, और आवागमन की एक बहुत लंबी सूची है, git rev-list
कमांड को एक टूटी हुई पाइप मिल सकती है जब वह लिखने की कोशिश करता है head
जिससे उसका इनपुट पढ़ना बंद हो जाता है और बाहर निकल जाता है। चूंकि टूटी-पाइप त्रुटियों को आमतौर पर शेल द्वारा अनदेखा किया जाता है, यह ज्यादातर काम करता है। बस सुनिश्चित करें कि वे आपके उपयोग में नजरअंदाज कर रहे हैं ।
यह कमांड के साथ जोड़ने के -n 1
लिए भी आकर्षक है । यह मत करो! यह एक कदम पीछे चलने के बाद रुक जाता है , और फिर आने वाले आवागमन की सूची (एक-प्रविष्टि) को उल्टा कर देता है। तो यह सिर्फ हर बार पैदा करता है।git rev-list
--reverse
git rev-list
<id2>
महत्वपूर्ण पक्ष नोट
ध्यान दें कि "डायमंड" या "बेंजीन रिंग" ग्राफ के टुकड़े के साथ:
I--J
/ \
...--H M--... <-- last
\ /
K--L
चलती एक "आगे" से प्रतिबद्ध H
के प्रति last
आप मिल जाएगा या तो I
या K
। आप इसके बारे में कुछ भी नहीं कर सकते हैं: दोनों कमिट एक कदम आगे हैं! यदि आप फिर परिणामी कमिट से शुरू करते हैं और एक और कदम बढ़ाते हैं, तो आप अब आपके द्वारा शुरू किए गए पथ को पूरा करने के लिए प्रतिबद्ध हैं।
इसका इलाज यह है कि एक समय में एक कदम आगे बढ़ने से बचें और पथ-निर्भर श्रृंखलाओं में बंद हो जाएं। इसके बजाय, यदि आप कुछ और करने से पहले पूरी वंशावली-पथ श्रृंखला पर जाने की योजना बनाते हैं, तो श्रृंखला में सभी कमिट की पूरी सूची बनाएं :
git rev-list --topo-order --reverse --ancestry-path A..B > /tmp/list-of-commits
फिर, इस सूची में प्रत्येक कमिट पर जाएँ, एक बार में, और आपको पूरी श्रृंखला मिल जाएगी। यह --topo-order
सुनिश्चित करेगा कि आप हिट- I
और J
उस क्रम में, और- K
और- L
उस क्रम में (हालांकि यह अनुमान लगाने का कोई आसान तरीका नहीं है कि आप केएल जोड़ी से पहले या बाद में IJ जोड़ी करेंगे या नहीं)।