Git का उपयोग करना, एक ही विशिष्ट शाखा पर * केवल * मौजूद सभी कमिटों को दिखाते हैं, न कि किसी * * अन्य को


86

एक शाखा को देखते हुए, मैं उन शाखाओं की सूची देखना चाहता हूं जो केवल उस शाखा पर मौजूद हैं । में इस सवाल का हम जो प्रतिबद्ध एक शाखा पर हैं, लेकिन नहीं एक या अधिक अन्य शाखाओं निर्दिष्ट देखने के लिए तरीके पर चर्चा।

यह थोड़ा अलग है। मैं देखना चाहता हूं कि कौन सी शाखाएं एक शाखा पर हैं लेकिन किसी अन्य शाखा पर नहीं ।

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

संपादित करें: नीचे परीक्षण करने के लिए एक डमी गिट रेपो स्थापित करने के लिए कदम हैं:

git init
echo foo1 >> foo.txt
git add foo.txt
git commit -am "initial valid commit"
git checkout -b merge-only
echo bar >> bar.txt
git add bar.txt
git commit -am "bad commit directly on merge-only"
git checkout master
echo foo2 >> foo.txt 
git commit -am "2nd valid commit on master"
git checkout merge-only 
git merge master

केवल संदेश "केवल मर्ज-ओनली पर खराब प्रतिबद्ध" के साथ प्रतिबद्ध, जो सीधे मर्ज-ओनली शाखा पर बनाया गया था, को दिखाना चाहिए।


1
यह प्रश्न मानता है कि सभी मर्ज किए गए ब्रांच वर्तमान में रेपो पर उपलब्ध हैं, एक बार पूरी तरह से मर्ज हो जाने के बाद कभी डिलीट नहीं किए जाते हैं, और शायद कभी फास्ट-फॉरवर्ड में विलय नहीं किया जाता है। मुझे बताएं कि क्या मुझे कुछ याद आ रहा है, लेकिन ऐसा लगता है कि यह केवल अनुमति वाले मर्ज से शाखाओं के अपेक्षाकृत छोटे सेट के लिए काम करने योग्य है, इसलिए सिर्फ git log ^branch1 ^branch2 merge-only-branchवाक्यविन्यास का उपयोग क्यों न करें ?
कार्ल बेवेलफेल्ट

1
git log ^branch1 ^branch2 merge-only-branchहर एक शाखा को सूचीबद्ध करने की आवश्यकता है। बैश / grep के कुछ चतुर उपयोग से बचा जा सकता है (नीचे मेरा उत्तर देखें), लेकिन मुझे उम्मीद है कि git के पास इसके लिए कुछ अंतर्निहित समर्थन है। आप सही हैं कि यह माना जाता है कि सभी मर्ज-से शाखाएं दूरस्थ हैं (स्थानीय केवल अन्य देवों के लिए गैर-अस्तित्व के रूप में अच्छे हैं)। --no-mergesकिसी भी ऐसे कमिट का उपयोग करना, जो इसमें मिला दिया गया था और फिर उनकी मूल मर्ज-ब्रांच को हटा दिया गया था, इसलिए यह मर्ज-से-शाखाओं को तब तक इधर-उधर रखा जाता है, जब तक कि उन्हें एक मर्ज-ओनली-ब्रांच (यानी मास्टर) में विलय नहीं कर दिया जाता।
जिमीमोर

जवाबों:


75

हमें बस यह सुरुचिपूर्ण समाधान मिला

git log --first-parent --no-merges

आपके उदाहरण में, प्रारंभिक प्रतिबद्धता अभी भी दिखाई देती है।

यह उत्तर वास्तव में प्रश्न का उत्तर नहीं देता है, क्योंकि प्रारंभिक प्रतिबद्ध अभी भी दिखाता है। दूसरी ओर यहां आने वाले कई लोगों को लगता है कि वे जिस उत्तर की तलाश कर रहे हैं।


1
सरल, प्रभावी, सर्वश्रेष्ठ।
ज़ब्बा

1
चूंकि मास्टर पर प्रारंभिक प्रतिबद्धता अभी भी दिखाई देती है, इसलिए यह सवाल का जवाब नहीं देता है।
jimmyorr

6
यह अकेले "उस शाखा पर मौजूद है" स्थिति को संतुष्ट नहीं करता है - यह दिखाता है initial valid commit, जो दोनों merge-onlyऔर masterशाखाओं का हिस्सा है । हालाँकि, अगर कोई पुटीन के प्रयास से होकर गुजरता है, तो उसके बाद के शाखा नाम को ^ -प्रक्षिप्त शाखा नाम (s) है, जो जानता है कि वर्तमान शाखा को बंद कर दिया गया है, यह आधी समस्याओं को हल करता है (विलय की गई चीजों को छोड़कर)। Ex:git log --first-parent --no-merges merge-only ^master
स्लिप डी। थॉम्पसन

13
मुझे यकीन नहीं है कि यह इतना क्यों उखाड़ा गया है, यह बिल्कुल भी सवाल का जवाब नहीं देता है। यह निश्चित रूप से जानकारी प्रदान नहीं करता है कि पोस्टर की तलाश थी।
क्रिस राइस

2
यह जवाब शायद सही नहीं होगा। लेकिन यह सरल है और निश्चित रूप से कुछ विस्तार के लिए काम करता है। मुझे शाखा का नाम जोड़ने के लिए उपयोगी लगता है - अर्थात फ़िल्टर किए गए सभी git log --first-parent --no-merges | grep <branch_name>
कमेंट्स

29

मेरे प्रिय मित्र रेडमुम्बा के सौजन्य से :

git log --no-merges origin/merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/remotes/origin |
    grep -Fv refs/remotes/origin/merge-only)

... जहाँ origin/merge-onlyआपका दूरस्थ मर्ज-केवल शाखा का नाम है। यदि एक स्थानीय-केवल Git रेपो, विकल्प पर काम कर refs/remotes/originके साथ refs/heads, और स्थानापन्न दूरस्थ शाखा का नाम origin/merge-onlyस्थानीय शाखा नाम के साथ merge-only, अर्थात्:

git log --no-merges merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/heads |
    grep -Fv refs/heads/merge-only)

2
मुझे उम्मीद है कि कोई और केवल git का उपयोग करके एक grep- कम समाधान प्रदान कर सकता है, लेकिन यदि नहीं, तो यह बहुत सुंदर लगता है।
जिमीमोर

1
हाँ, सुरुचिपूर्ण। git for-each-refमूल में प्रत्येक रेफरी नाम को सूचीबद्ध करने के लिए और grep -vमर्ज-ओनली शाखा को छोड़ने के लिए उपयोग करें । git logएक --notविकल्प लेता है , जिसमें हम अपनी सभी सूची (मर्ज-केवल शाखा को छोड़कर) पास करते हैं। यदि आपके पास समस्या का अधिक सुरुचिपूर्ण उत्तर है, तो इसे सुनें।
जिमीमोर

2
ओह, मुझे यकीन है कि यह सबसे सुंदर जवाब है। मैं केवल यह तर्क दे रहा हूं कि यह सच्ची शान के लिए थोड़ा "चिंताजनक / जटिल" है। :-) अपने दृष्टिकोण को नापसंद करने का मतलब नहीं था, सर!
क्रिस के

1
आदेशों /*में अनुगामी git for-each-refsकुछ मौजूदा फ़ाइल से मेल नहीं खाने और सेट failglobया nullglobसेट ( बैश विकल्प, अन्य गोले अलग-अलग नहीं) पर निर्भर करती है । आपको या तो तारांकन से बचना चाहिए या केवल अनुगामी /*को छोड़ना चाहिए ( git for-each-refपैटर्न शुरू से "एक स्लैश तक" से मेल खा सकता है)। हो सकता है कि अधिक सख्त होने के लिए उपयोग grep -Fv refs/remotes/origin/foo( refs/heads/foo) का उपयोग किया जाए।
क्रिस जॉन्सन

3
इसे सरल बनाया जा सकता है यदि आप केवल एक शाखा में मौजूद कमिट्स को देखना चाहते हैं और दूसरी में नहीं:, git log --no-merges B1 --not B2जहां बी 1 वह शाखा है जिसमें आप रुचि रखते हैं, और बी 2 वह शाखा है जिसकी आप बी 1 से तुलना करना चाहते हैं। बी 1 और बी 2 दोनों स्थानीय या दूरस्थ शाखाएं हो सकती हैं, इस प्रकार आप निर्दिष्ट कर सकते हैंgit log --no-merges master --not origin/master , दो दूरस्थ शाखाओं को निर्दिष्ट या ।
mr.b

21
git log origin/dev..HEAD

यह आपको आपकी शाखा में किए गए सभी आवागमन दिखाएगा।


2
@ प्रकाश origin/branchNameसुदूर शाखा के प्रमुख HEADको इंगित करेगा और उस शाखा में अंतिम स्थानीय प्रतिबद्ध के प्रति इंगित करेगा। तो यह तब काम नहीं करेगा जब आपने गिट पुश का उपयोग किया हो।
Bharat

आप किसी अन्य स्थानीय शाखा की तुलना करने के लिए इसका उपयोग कर सकते हैं। ओनो के मूल प्रश्न को संबोधित करने के लिए --no- मर्ज ध्वज भी उपयोगी हो सकता है।
पॉल व्हिप

15

@ प्रकाश जवाब काम करता है। सिर्फ स्पष्टता के लिए ...

git checkout feature-branch
git log master..HEAD

फीचर-शाखा पर कमिट्स को सूचीबद्ध करता है लेकिन अपस्ट्रीम शाखा (आमतौर पर आपके मास्टर) को नहीं।


12

शायद यह मदद कर सकता है:

git शो-शाखा


2
जब भी यह सैद्धांतिक रूप से प्रश्न का उत्तर दे सकता है, तो उत्तर के आवश्यक भागों को शामिल करना और संदर्भ के लिए लिंक प्रदान करना बेहतर होगा
व्लादिमीर पेंटेलेव

यह वास्तव में काफी मददगार है। अधिक विस्तृत उदाहरण और कुछ संबंधित उत्तरों के लिए stackoverflow.com/a/7623339/874188 देखें ।
ट्रिपलए

7

इसे इस्तेमाल करे:

git rev-list --all --not $(git rev-list --all ^branch)

मूल रूप git rev-list --all ^branchसे सभी संशोधन शाखा में नहीं मिलते हैं और फिर आप सभी संशोधन रेपो में करते हैं और पिछली सूची को हटाते हैं जो केवल संशोधन हैं शाखा में ।

@ ब्रायन की टिप्पणियों के बाद:

Git रि-लिस्ट के प्रलेखन से:

List commits that are reachable by following the parent links from the given commit(s)

इसलिए git rev-list Aजहां कमांड ए है वहां कमिटमेंट लिस्ट होगी, जो ए के समावेशी से उपलब्ध हैं।

मन में उसके साथ, कुछ इस तरह

git rev-list --all ^A

सूची ए से नहीं पहुंच सकने वाली सूची बनाती है

तो git rev-list --all ^branchशाखा की नोक से नहीं आने वाले सभी कमिट्स को सूचीबद्ध करेगा। जो शाखा में सभी कमिट्स को हटा देगा, या दूसरे शब्दों में कमिट करता है जो केवल अन्य शाखाओं में हैं।

अब चलो git rev-list --all --not $(git rev-list --all ^branch)

यह जैसा होगा git rev-list --all --not {commits only in other branches}

इसलिए हम ऐसी सूची बनाना चाहते allहैं जो इससे उपलब्ध नहीं हैंall commits only in other branches

जो कमिट का सेट है जो केवल ब्रांच में है। आइए एक सरल उदाहरण लेते हैं:

             master

             |

A------------B

  \

   \

    C--------D--------E

                      |

                      branch

यहाँ लक्ष्य डी और ई प्राप्त करना है, किसी अन्य शाखा में नहीं।

git rev-list --all ^branch केवल बी दे

अब, git rev-list --all --not Bक्या हम नीचे आते हैं। जो भी है git rev-list -all ^B- हम चाहते हैं कि सभी बी से पहुंच न सकें। हमारे मामले में यह डी और ई है। जो हम चाहते हैं।

आशा है कि यह बताता है कि कमांड कैसे सही तरीके से काम करता है।

टिप्पणी के बाद संपादित करें:

git init
echo foo1 >> foo.txt
git add foo.txt
git commit -am "initial valid commit"
git checkout -b merge-only
echo bar >> bar.txt
git add bar.txt
git commit -am "bad commit directly on merge-only"
git checkout master
echo foo2 >> foo.txt 
git commit -am "2nd valid commit on master"

उपरोक्त चरणों के बाद, यदि आप करते हैं तो आपको git rev-list --all --not $(git rev-list --all ^merge-only)वह कमिटमेंट मिल जाएगा जिसकी आपको तलाश थी - "bad commit directly on merge-only"एक।

लेकिन एक बार जब आप अपने चरणों में अंतिम चरण करते हैं git merge masterतो कमांड अपेक्षित आउटपुट नहीं देगा। क्योंकि अब तक ऐसा कोई कमिट नहीं है जो केवल मर्ज में ही नहीं है क्योंकि मास्टर में एक एक्स्ट्रा कमिट को भी मर्ज-ओनली कर दिया गया है। इसलिए git rev-list --all ^branchखाली परिणाम देता है और इसलिए मर्ज में ही सभी कमिट git rev-list -all --not $(git rev-list --all ^branch)दे देंगे ।


1
हम्म ... यकीन नहीं क्यों, लेकिन यह काफी काम नहीं करता है। अपनी कमांड के आउटपुट को ढेर करना xargs -L 1 -t git branch -a --containsझूठी सकारात्मकता को दर्शाता है (यह कहता है कि वास्तव में अन्य शाखाओं पर हैं)। मैंने साथ और बिना कोशिश की --no-merges। हालांकि जवाब देने के लिए धन्यवाद!
jimmyorr

जहाँ तक मैं एक डमी गिट रेपो में देख सकता हूँ, मेरे लिए ठीक काम करता है।
मनोजों

मैंने आपके उत्तर के साथ समस्या को प्रदर्शित करने में मदद करने के लिए डमी गिट रेपो बनाने के लिए कदम जोड़े हैं।
जिमीमोर

आह, वूप्स। इससे पहले कि मैं यह सब कुछ के माध्यम से सोचा था कि ऊपर उठाया। git rev-list --all ^branchआप सभी करता है कि नहीं कर रहे हैं दे देंगे branch। फिर आप उस सूची से घटा रहे हैं जो अंदर है branch; लेकिन परिभाषा के अनुसार, सभी ऐसे हैं जो अंदर नहीं branchहैं branch, इसलिए आप कुछ भी घटा नहीं रहे हैं। जिमीमोर किस चीज की तलाश कर रहे हैं, यह उन लोगों के लिए है जो branchmasterतो हैं और न ही किसी अन्य शाखा में। आप उन कमिट्स को घटाना नहीं चाहते जो अंदर नहीं हैं branch; आप उन कमिटों को घटाना चाहते हैं जो किसी अन्य शाखा में हैं।
ब्रायन कैंपबेल

1
@manojisions "(सभी संशोधन) - (शाखा में सभी संशोधन नहीं) = शाखा में संशोधन।" हां, यह सभी संशोधनों को प्राप्त करने के लिए काम करता है branch, लेकिन ऐसा करता है git rev-list branch। आप git rev-list branchअधिक जटिल (और धीमे) तरीके से लिख रहे हैं । यह उस सवाल का जवाब देने के लिए काम नहीं करता है, जो यह बताता है कि सभी कमिट्स branch किसी अन्य शाखा में नहीं हैं
ब्रायन कैंपबेल

2

के साथ उपयोग करने के लिए स्वीकृत उत्तरों की एक और भिन्नता master

git log origin/master --not $(git branch -a | grep -Fv master)

सभी कमानों को फ़िल्टर करें जो मास्टर के अलावा किसी भी शाखा में होते हैं।


0

यह वास्तव में एक वास्तविक जवाब नहीं है, लेकिन मुझे स्वरूपण, और बहुत सारे स्थान तक पहुंच की आवश्यकता है। मैं दो सबसे अच्छे उत्तरों पर विचार करने के पीछे के सिद्धांत का वर्णन करने की कोशिश करूँगा: स्वीकार किए गए एक और (कम से कम वर्तमान में) शीर्ष क्रम वाले । लेकिन वास्तव में, वे विभिन्न सवालों के जवाब देते हैं ।

एक समय में एक से अधिक शाखा में "कम ऑन द गिट" बहुत बार होता है। वास्तव में, यह बहुत है कि सवाल क्या है। दिया हुआ:

...--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आदेश पंक्ति तर्क के लिए उपसर्ग, के रूप में स्वीकार किए जाते हैं जवाब में इस्तेमाल किया, दबा कभी जाकर सब पर ग्राफ के कुछ भागों, शुरू से ही।

इन विशेषताओं का उपयोग करके हमें दो अलग-अलग प्रश्नों के उत्तर पसंद आते हैं।

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