यह वास्तव में एक वास्तविक जवाब नहीं है, लेकिन मुझे स्वरूपण, और बहुत सारे स्थान तक पहुंच की आवश्यकता है। मैं दो सबसे अच्छे उत्तरों पर विचार करने के पीछे के सिद्धांत का वर्णन करने की कोशिश करूँगा: स्वीकार किए गए एक और (कम से कम वर्तमान में) शीर्ष क्रम वाले । लेकिन वास्तव में, वे विभिन्न सवालों के जवाब देते हैं ।
एक समय में एक से अधिक शाखा में "कम ऑन द गिट" बहुत बार होता है। वास्तव में, यह बहुत है कि सवाल क्या है। दिया हुआ:
...--F--G--H <-- master
\
I--J <-- develop
जहाँ अपरकेस अक्षर वास्तविक Git हैश ID के लिए खड़े होते हैं, हम अक्सर केवल कमिटH या केवलI-J हमारे git logआउटपुट में ही काम करते हैं। अप करता है के माध्यम से Gकर रहे हैं दोनों शाखाओं, इसलिए हम उन्हें बहिष्कृत करना चाहते हैं।
(ध्यान दें कि इस तरह तैयार रेखांकन में, नए प्रतिबद्ध सही दिशा में हैं। नामों एकल सबसे-दाएं कि लाइन पर प्रतिबद्ध चयन उन प्रतिबद्ध से प्रत्येक एक माता पिता के लिए प्रतिबद्ध है, जो उनके बाएँ करने के लिए प्रतिबद्ध है:। की मूल Hहै G, और की मूल Jहै Iकी मूल। Iहै Gफिर से की मूल। Gहै F, और Fयह का हिस्सा: एक माता पिता कि बस यहाँ नहीं दिखाया जाता है ...अनुभाग)।
इस विशेष रूप से सरल मामले के लिए, हम उपयोग कर सकते हैं:
git log master..develop # note: two dots
देखने के लिए I-J, या:
git log develop..master # note: two dots
Hकेवल देखने के लिए । राइट-साइड नाम, दो डॉट्स के बाद, गिट को बताता है: हां, ये कमिट करता है । बाईं ओर का नाम, दो बिंदुओं से पहले, Git को बताता है: नहीं, ये कमिट नहीं हैं । Git अंत में शुरू होता है - प्रतिबद्ध Hया प्रतिबद्ध J- और पीछे की ओर काम करता है । इस बारे में (अधिक) के लिए, थिंक लाइक (ए) गिट देखें ।
जिस तरह से मूल प्रश्न phrased है, इच्छा करता है कि कर रहे हैं मिल रहा है से प्राप्त किए एक विशेष नाम है, लेकिन से नहीं किसी अन्य नाम है कि एक ही सामान्य श्रेणी में। यदि हमारे पास एक और अधिक जटिल ग्राफ है:
O--P <-- name5
/
N <-- name4
/
...--F--G--H--I---M <-- name1
\ /
J-----K <-- name2
\
L <-- name3
हम इनमें से किसी एक नाम को चुन सकते हैं, जैसे कि name4या name3, और पूछें: जो कमिट उस नाम से पाया जा सकता है, लेकिन किसी अन्य नाम से नहीं? अगर हम उठाते हैं name3तो उत्तर दिया जाता है L। अगर हम उठाते हैं name4, तो जवाब बिल्कुल भी कमिट नहीं होता है: कमिट जो कि name4नाम है, Nलेकिन कमिट Nशुरू करने name5और पीछे की ओर काम करने से मिल सकती है ।
स्वीकृत उत्तर शाखा के नामों के बजाय रिमोट-ट्रैकिंग नामों के साथ काम करता है, और आपको एक को नामित करने की अनुमति देता है origin/merge-only- एक चयनित नाम को वर्तनी देता है और उस नाम स्थान के अन्य सभी नामों को देखता है। यह मर्ज दिखाने से भी बचता है: यदि हम name1"दिलचस्प नाम" के रूप में चुनते हैं , और कहते हैं कि मुझे दिखाते हैं कि जो name1किसी अन्य नाम से नहीं बल्कि किसी और नाम से उपलब्ध हैं , तो हम मर्ज कमिट के Mसाथ-साथ नियमित रूप से भी देखेंगे I।
सबसे लोकप्रिय जवाब काफी अलग है। यह traversing ग्राफ प्रतिबद्ध बारे में सब है बिना निम्नलिखित दोनों पैर , और किसी मर्ज को बिना दिखाए प्रतिबद्ध है कि के किसी भी कर रहे हैं आपस में विलय। name1उदाहरण के लिए, अगर हम शुरुआत करते हैं , तो हम नहीं दिखाएंगे M(यह एक मर्ज है), लेकिन यह मानते हुए कि मर्ज का पहला अभिभावक Mप्रतिबद्ध है I, हम कमिट्स भी नहीं देखेंगे Jऔर K। हम प्रतिबद्ध को दिखाई देंगे I, और भी करता है H, G, F, और इतने पर-कोई भी इनमें से मर्ज प्रतिबद्ध हैं और सभी से शुरुआत करते हुए पहुंचा जा सकता है Mऔर पीछे की ओर काम कर रहा है, केवल जाकर पहले प्रत्येक मर्ज करने की मूल।
सबसे लोकप्रिय जवाब बहुत अच्छी तरह से अनुकूल है, उदाहरण के लिए, masterजब masterमर्ज-ओनली ब्रांच होने का इरादा होता है। यदि सभी "वास्तविक कार्य" साइड शाखाओं पर किए गए थे जो बाद में विलय कर दिए गए थे master, तो हमारे पास इस तरह एक पैटर्न होगा:
I---------M---------N <-- master
\ / \ /
o--o--o o--o--o
जहाँ सभी गैर-अक्षर वाले oकमिट साधारण (नॉन-मर्ज) कमिट होते हैं Mऔर Nमर्ज कमिट होते हैं। कमिट Iप्रारंभिक प्रतिबद्धता है: बहुत पहले की गई पहली प्रतिबद्धता, और एकमात्र ऐसा मास्टर होना चाहिए जो मर्ज कमिट नहीं है। अगर इसके अलावा git log --first-parent --no-merges masterकोई और दिखावा करता है I , तो हमारे पास ऐसी स्थिति है:
I---------M----*----N <-- master
\ / \ /
o--o--o o--o--o
जहाँ हम कुछ फ़ीचर ब्रांच को मर्ज करके नहीं, बल्कि *सीधे तौर पर बनाया गया देखना चाहते हैं master।
संक्षेप में, लोकप्रिय जवाब यह देखने के लिए बहुत अच्छा है कि masterकब masterकेवल मर्ज किया जाना है, लेकिन अन्य स्थितियों के लिए उतना महान नहीं है। इन अन्य स्थितियों के लिए स्वीकृत उत्तर काम करता है।
क्या रिमोट-ट्रैकिंग नाम origin/master शाखा नामों की तरह हैं ?
Git के कुछ हिस्से कहते हैं कि वे नहीं हैं:
git checkout master
...
git status
कहते हैं on branch master, लेकिन:
git checkout origin/master
...
git status
कहता है HEAD detached at origin/master। मैं इससे सहमत होना पसंद करता हूंgit checkout / git switch: origin/masterएक शाखा का नाम नहीं है क्योंकि आप इसे "चालू" नहीं कर सकते।
स्वीकृत उत्तर रिमोट-ट्रैकिंग नामों का उपयोग origin/*"शाखा नामों" के रूप में करता है:
git log --no-merges origin/merge-only \
--not $(git for-each-ref --format="%(refname)" refs/remotes/origin |
grep -Fv refs/remotes/origin/merge-only)
मध्य रेखा, जो आह्वान करती है git for-each-ref, दूरस्थ नाम के लिए रिमोट-ट्रैकिंग नामों पर पुनरावृति करती है origin।
कारण इस मूल समस्या के लिए एक अच्छा समाधान है कि हम में यहाँ रुचि रखते हैं है किसी और के बजाय, शाखा के नाम हमारे शाखा के नाम। लेकिन इसका मतलब है कि हमने शाखा को परिभाषित किया है को अपनी शाखा नामों के अलावा कुछ और के रूप में । यह ठीक है: बस जागरूक रहें कि आप ऐसा कर रहे हैं, जब आप इसे करते हैं।
git log कमोडिटी ग्राफ के कुछ भाग का पता लगाता है
हम यहां जो खोज रहे हैं, वह श्रृंखला है जिसे मैंने डैगलेट्स कहा है : देखें कि "शाखा" से हमारा वास्तव में क्या मतलब है? यही है, हम समग्र प्रतिबद्ध ग्राफ़ के कुछ सबसेट के भीतर अंशों की तलाश कर रहे हैं ।
जब भी हम Git को एक शाखा के नाम की तरह देखते हैं master, जैसे एक टैग नाम v2.1, या रिमोट-ट्रैकिंग नाम जैसेorigin/master , , हम चाहते हैं कि Git हमें उस कमिट के बारे में बताए और हर उस प्रतिबद्धता के बारे में बताए जो हम उस कमिट से प्राप्त कर सकते हैं: वहां से शुरू करना , और पीछे की ओर काम कर रहा है।
गणित में, इसे ग्राफ के रूप में जाना जाता है । Git का कमिट ग्राफ एक डायरेक्टेड एसाइक्लिक ग्राफ या DAG है , और इस तरह का ग्राफ विशेष रूप से चलने के लिए अनुकूल है। जब इस तरह के एक ग्राफ घूमना, एक-एक ग्राफ शिखर कि है का दौरा करेंगे पहुंच योग्य के माध्यम से पथ इस्तेमाल किया जा रहा। गिट ग्राफ़ में कोने कमिट होते हैं, जिसमें किनारों को आर्क्स-वन-वे लिंक होते हैं - प्रत्येक बच्चे से प्रत्येक माता-पिता के लिए जा रहे हैं। (यह वह जगह है जहां थिंक लाइक (ए) गिट आती है। आर्क्स की एकतरफा प्रकृति का मतलब है कि गिट को बच्चे से माता-पिता तक पीछे की ओर काम करना चाहिए।
ग्राफ-वॉकिंग के लिए दो मुख्य Git कमांड हैं git logऔर git rev-list। ये कमांड बेहद समान हैं- वास्तव में वे ज्यादातर एक ही स्रोत फ़ाइलों से निर्मित होते हैं - लेकिन उनका आउटपुट अलग होता है: git logमनुष्य को पढ़ने के git rev-listलिए आउटपुट उत्पन्न करता है , जबकि उत्पादन अन्य जीआईटी कार्यक्रमों को पढ़ने के लिए होता है। 1 दोनों कमांड इस तरह का ग्राफ-वॉक करते हैं।
ग्राफ वॉक वे विशेष रूप से करते हैं: शुरुआती बिंदु वाले कमिट्स के कुछ सेट (शायद सिर्फ एक कमिट, शायद हैश आईडी का एक गुच्छा, शायद नाम का एक गुच्छा जो हैश आईडी का समाधान करते हैं) को देखते हुए, ग्राफ़ पर जाएं, कमिट पर जाकर । विशेष निर्देश, जैसे कि --notया उपसर्ग ^, या --ancestry-path, किसी तरह --first-parentसे ग्राफ चलना को संशोधित करें ।
जैसा कि वे ग्राफ वॉक करते हैं, वे प्रत्येक कमिट पर जाते हैं। लेकिन वे केवल वॉक किए गए कमिट के कुछ चुनिंदा सबसेट को प्रिंट करते हैं। जैसे निर्देशों या ग्राफ-पैदल कोड है जो करने के लिए प्रतिबद्ध बता मुद्रित ।--no-merges--before <date>
यह दौरा करने के लिए, एक समय में एक प्रतिबद्ध, ये दोनों कमांड प्राथमिकता कतार का उपयोग करते हैं । आप चलाते हैं git logया git rev-listइसे कुछ शुरुआती बिंदु देते हैं। उन्होंने उन कामों को प्राथमिकता कतार में रखा। उदाहरण के लिए, एक सरल:
git log master
नाम masterको कच्ची हैश आईडी में बदल देता है और उस एक हैश आईडी को कतार में रख देता है। या:
git log master develop
दोनों नामों को हैश आईडी में बदल देता है और मान लेता है कि ये दो अलग-अलग हैश आईडी हैं- दोनों को कतार में खड़ा करता है।
इस कतार में कमिट की प्राथमिकता अभी भी अधिक तर्कों द्वारा निर्धारित की जाती है। उदाहरण के लिए, तर्क कमेंटस्टैम्प के बजाय लेखक टाइमस्टैम्प का उपयोग करता --author-date-orderहै git logया बताता है । डिफ़ॉल्ट कम्यूटर टाइमस्टैम्प का उपयोग करना और नवीनतम-दर-तारीख प्रतिबद्ध चुनना है: उच्चतम संख्यात्मक तारीख के साथ। इसलिए , दो अलग-अलग हिट्स के लिए इन संकल्पों को संभालने के बाद, जो भी बाद में आएगा, Git दिखाएगाgit rev-listmaster develop , पहले , क्योंकि यह कतार के सामने होगा।
किसी भी मामले में, संशोधन चलना कोड अब एक लूप में चलता है:
- जबकि कतार में हैं:
- पहली कतार प्रविष्टि निकालें।
- तय करें कि क्या यह कमिट छापना है। उदाहरण के लिए
--no-merges: यदि यह एक मर्ज कमिट है तो कुछ भी न छापें; --before: यदि निर्धारित तिथि से पहले इसकी तारीख नहीं आती है तो कुछ भी न छापें। यदि मुद्रण को दबाया नहीं गया है, तो कमेंट प्रिंट करें: इसके लिए git log, अपना लॉग दिखाएं; के लिए git rev-list, इसकी हैश आईडी प्रिंट करें।
- इस कमेट के माता-पिता में से कुछ या सभी को कतार में लगाओ (जब तक यह वहां नहीं है, और पहले से ही 2 पर नहीं गए हैं )। सामान्य डिफ़ॉल्ट सभी माता-पिता में रखना है। का उपयोग करते हुए
--first-parentसभी लेकिन दबा पहले प्रत्येक मर्ज की मूल।
(दोनों git logऔर git rev-listक्या कर सकते हैं इतिहास सरलीकरण के साथ या बिना माता पिता के नए सिरे से लिखना इस बिंदु पर साथ ही, लेकिन हम यहाँ है कि छोड़ देंगे।)
एक साधारण श्रृंखला के लिए, जैसे शुरू में HEADऔर पीछे की ओर काम करते हैं जब कोई मर्ज नहीं होता है, तो कतार हमेशा लूप के शीर्ष पर एक प्रतिबद्ध होती है। एक प्रतिबद्ध है, इसलिए हम इसे बंद करते हैं और इसे प्रिंट करते हैं और अपने (एकल) माता-पिता को कतार में डालते हैं और फिर से घूमते हैं, और हम श्रृंखला का अनुसरण करते हैं जब तक कि हम बहुत पहले कमिट तक नहीं पहुंचते, या उपयोगकर्ता git logआउटपुट और क्विट्स से थक जाता है कार्यक्रम। इस मामले में, कोई भी आदेश देने वाला विकल्प मायने नहीं रखता है: दिखाने के लिए केवल एक ही प्रतिबद्ध है।
जब मर्ज होते हैं और हम माता-पिता दोनों का अनुसरण करते हैं - मर्ज के दोनों "पैर" - या जब आप देते हैं git logयाgit rev-list एक से अधिक शुरुआती प्रतिबद्ध होते हैं, तो छंटनी विकल्प मायने रखता है।
अंतिम, कमिटमेंट के सामने --notया उसके प्रभाव पर विचार करें ^। इन्हें लिखने के कई तरीके हैं:
git log master --not develop
या:
git log ^develop master
या:
git log develop..master
सभी का मतलब एक ही है। --notउपसर्ग की तरह है ^, सिवाय इसके कि यह एक से अधिक नाम पर लागू होने वाला:
git log ^branch1 ^branch2 branch3
शाखा 1 का अर्थ नहीं, शाखा 2 नहीं, हां शाखा 3; परंतु:
git log --not branch1 branch2 branch3
इसका मतलब शाखा 1 नहीं, शाखा 2 नहीं, शाखा 3 नहीं है, और --notइसे बंद करने के लिए आपको एक दूसरे का उपयोग करना होगा:
git log --not branch1 branch2 --not branch3
जो थोड़ा अजीब है। दो "नहीं" निर्देशों को XOR के माध्यम से जोड़ा जाता है, इसलिए यदि आप वास्तव में चाहते हैं, तो आप लिख सकते हैं:
git log --not branch1 branch2 ^branch3
मतलब Branch1 नहीं, नहीं Branch2, हाँ branch3 , आप करना चाहते हैं तो अंधेरा ।
ये सभी ग्राफ वॉक को प्रभावित करके काम करते हैं। जैसा कि git logया git rev-listग्राफ चलता है, यह सुनिश्चित करता है कि किसी भी नकारात्मक संदर्भों से उपलब्ध होने वाले किसी भी प्रतिबद्ध को प्राथमिकता कतार में न डालें । (वास्तव में, वे शुरुआती सेटअप को भी प्रभावित करते हैं: कमिटेड कमांड लाइन से प्राथमिकता कतार में नहीं जा सकते, इसलिए उदाहरण के लिए कुछ भी नहीं दिखाता है।)git log master ^master
Gitrevisions प्रलेखन में वर्णित फैंसी सिंटैक्स के सभी इसका उपयोग करते हैं, और आप इसे एक साधारण कॉल के साथ उजागर कर सकते हैं git rev-parse। उदाहरण के लिए:
$ git rev-parse origin/pu...origin/master # note: three dots
b34789c0b0d3b137f0bb516b417bd8d75e0cb306
fc307aa3771ece59e174157510c6db6f0d4b40ec
^b34789c0b0d3b137f0bb516b417bd8d75e0cb306
थ्री-डॉट सिंटैक्स का अर्थ है, बाईं या दाईं ओर से पहुंच योग्य है, लेकिन दोनों में से पहुंचने योग्य आवागमन को छोड़कर । इस मामले में origin/masterप्रतिबद्ध, b34789c0bस्वयं से पहुंच योग्य है origin/pu( fc307aa37...) इसलिए origin/masterहैश दो बार दिखाई देता है, एक बार नकार के साथ, लेकिन वास्तव में Git तीन पॉजिटिव सिंटैक्स को दो सकारात्मक संदर्भों में डालकर प्राप्त करता है- दो गैर-नकारात्मक हैश आईडी और एक नकारात्मक एक, ^उपसर्ग द्वारा प्रतिनिधित्व किया ।
Simiarly:
$ git rev-parse master^^@
2c42fb76531f4565b5434e46102e6d85a0861738
2f0a093dd640e0dad0b261dae2427f2541b5426c
^@वाक्य रचना का मतलब है सभी को देखते हुए माता-पिता के लिए प्रतिबद्ध है, और master^खुद-की शाखा-नाम से चयनित प्रतिबद्ध पहले माता-पिता master-is किसी मर्ज के लिए प्रतिबद्ध है, इसलिए इसे दो माता-पिता है। ये दो माता-पिता हैं। तथा:
$ git rev-parse master^^!
0b07eecf6ed9334f09d6624732a4af2da03e38eb
^2c42fb76531f4565b5434e46102e6d85a0861738
^2f0a093dd640e0dad0b261dae2427f2541b5426c
^!प्रत्यय साधन ही प्रतिबद्ध है, लेकिन इसके माता-पिता में से कोई भी । इस मामले में, master^है 0b07eecf6...। हमने पहले ही दोनों माता-पिता को ^@प्रत्यय के साथ देखा था ; यहाँ वे फिर से हैं, लेकिन इस बार, नकारात्मक।
1 कई गिट कार्यक्रम वस्तुतः git rev-listविभिन्न विकल्पों के साथ चलते हैं, और इसके आउटपुट को पढ़ते हैं, यह जानने के लिए कि कौन सी वस्तु और / या अन्य Git वस्तुओं का उपयोग करना है।
2 क्योंकि ग्राफ एक प्रकार का पौधा है , इसलिए यह गारंटी देना संभव है कि कोई भी पहले से ही नहीं आया है, अगर हम जोड़ते हैं कि बाधा अपने माता-पिता को अपने सभी बच्चों को प्राथमिकता दिखाने से पहले कभी नहीं दिखाती है । --date-order, --author-date-orderऔर --topo-orderइस बाधा को जोड़ें। डिफ़ॉल्ट सॉर्ट क्रम - जिसका कोई नाम नहीं है - नहीं है। यदि प्रतिबद्ध टाइमस्टैम्प खराब हैं - उदाहरण के लिए अगर कुछ कम्यूटर "भविष्य में" एक कंप्यूटर द्वारा बनाए गए थे जिसकी घड़ी बंद थी - तो कुछ मामलों में यह अजीब दिखने वाले आउटपुट को जन्म दे सकता है।
यदि आपने इसे अभी तक बनाया है, तो अब आप इसके बारे में बहुत कुछ जानते हैं git log
सारांश:
git log ग्राफ़ के कुछ या कुछ हिस्से को चलते समय कुछ चयनित कमिट दिखाने के बारे में है।
--no-mergesतर्क, दोनों में स्वीकार किए जाते हैं और वर्तमान में-शीर्ष क्रम के जवाब मिल गया है, कुछ करता है कि दिखा दबा कर रहे हैं चला गया।
--first-parentतर्क, वर्तमान-शीर्ष क्रम के जवाब से, दबा चलने ग्राफ के कुछ भागों, के दौरान ही ग्राफ-चलते हैं।
--notआदेश पंक्ति तर्क के लिए उपसर्ग, के रूप में स्वीकार किए जाते हैं जवाब में इस्तेमाल किया, दबा कभी जाकर सब पर ग्राफ के कुछ भागों, शुरू से ही।
इन विशेषताओं का उपयोग करके हमें दो अलग-अलग प्रश्नों के उत्तर पसंद आते हैं।
git log ^branch1 ^branch2 merge-only-branchवाक्यविन्यास का उपयोग क्यों न करें ?