2009-10-20 4 views
34

एक यूनिक्स या जीएनयू पटकथा माहौल में क्या है (उदाहरण के लिए एक Linux distro, Cygwin, OSX), क्या यह निर्धारित करने के लिए सबसे अच्छा तरीका है वर्तमान चेकआउट एक गिट टैग है। यदि यह एक टैग है, तो मैं टैग नाम कैसे निर्धारित कर सकता हूं? इस तकनीक काकैसे प्रोग्राम के रूप में निर्धारित करने के लिए Git चेकआउट एक टैग है और यदि ऐसा है तो, टैग नाम

एक प्रयोग स्वचालित रूप से एक रिलीज (जैसे svnversion सबवर्सन के साथ क्या होता है) लेबलिंग होगा।

मेरी संबंधित सवाल के बारे में programmatically detecting the Git branch देखें।

+0

का एहसास नहीं किया जा सकता GIT-संस्करण-GEN स्क्रिप्ट पर एक नजर डालें (और में इसके उपयोग makefile) Git भंडार में: http://git.kernel.org/?p=git/git.git;a=blob;f=GIT-VERSION-GEN;hb=HEAD –

+0

@jhs: मैं upvoted है ग्रेग Hewgill जवाब । मैंने 'git name-rev' के आधार पर उत्तर कम कर दिया है क्योंकि यह वापस कर सकता है उदा। 'कुछ टैग ~ 5', और 'गिट लॉग' और 'गिट टैग -एल' के संयोजन के आधार पर उत्तर क्योंकि यह बदसूरत और अक्षम है। –

उत्तर

36

समाधान अपने सवाल को

git describe --exact-match HEAD 

उपयोग करने के लिए है (जो केवल एनोटेट टैग पर विचार करेंगे, लेकिन आप एनोटेट उपयोग करना चाहिए और शायद भी रिलीज टैगिंग के लिए हस्ताक्षर किए टैग)।

आप सभी टैग, यह भी हल्के टैग (जो आमतौर पर स्थानीय टैगिंग के लिए उपयोग किया जाता है) पर विचार करना चाहते हैं, तो आप --tags विकल्प का उपयोग कर सकते हैं:

git describe --exact-match --tags HEAD 

लेकिन मुझे लगता है तुम हो " XY problem "यहां, आप समस्या के बारे में प्रश्न पूछने के बजाय समस्या के संभावित समाधान के बारे में सवाल पूछ रहे हैं ... जिसमें बेहतर समाधान हो सकता है।

समाधान अपने समस्या को देखने के लिए कैसे Git GIT-VERSION-GEN लिपि में यह करता है, और यह कैसे अपने Makefile में इसे इस्तेमाल करता है।

+2

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

+0

दुर्भाग्यवश, आपका समाधान मेरे लिए काम नहीं करता है। 'गिट वर्णन - सटीक मिलान HEAD' => घातक: कोई टैग बिल्कुल मेल नहीं खाता '...'। मेरा मानना ​​है कि आपको पैरामीटर में '--tags' जोड़ने की आवश्यकता है। – JasonSmith

+0

@jhs: Wbout '' Git बनाम Git --exact मैचों की HEAD' का वर्णन का वर्णन --exact मैचों की --tags HEAD': '--tags' विकल्प की जरूरत होगी केवल यदि आप हल्के टैग का उपयोग। टैग रिलीज करने के लिए हस्ताक्षरित टैग (जो एनोटेटेड टैग, यानी टैग ऑब्जेक्ट्स हैं) का उपयोग करने की अनुशंसा की जाती है। –

-2

यहाँ एक संक्षिप्त खोल स्क्रिप्ट (बैश में परीक्षण किया गया है, अगर यह आदि राख पर काम करता है, इस बात की पुष्टि नहीं) है। यह वर्तमान में जांचा-आउट टैग के नाम के git_tag चर सेट, या उसे खाली छोड़ करता है, तो चेकआउट टैग नहीं किया गया होगा।

git_tag='' 
this_commit=`git log --pretty=format:%H%n HEAD^..` 

for tag in `git tag -l`; do 
    tag_commit=`git log --pretty=format:%H%n tags/$tag^..tags/$tag` 
    if [ "$this_commit" = "$tag_commit" ]; then 
    # This is a tagged commit, so use the tag. 
    git_tag="$tag" 
    fi 
done 

टिप्पणी जेकब Narębski द्वारा:

यह समाधान सभी टैग से अधिक पाशन, और यह जांच अगर वे corrent को इंगित प्रतिबद्ध है, यानी वस्तु प्रमुख द्वारा बताया करने के लिए कम कर देता है। पाइपलाइन आदेश, अर्थात आदेशों पटकथा के लिए उपयोग करना, यह लिखा जा सकता है के रूप में:

this_commit=$(git rev-parse --verify HEAD) 
git for-each-ref --format="%(*objectname) %(refname:short)" refs/tags/ | 
while read tagged_object tagname 
do 
    if test "$this_commit" = "$tagged_object" 
    then 
     echo $tagname 
    fi 
done 

यह सभी टैग है कि मौजूदा प्रतिबद्ध को इंगित प्रिंट होगा।

+0

उपयोग "Git रेव-पार्स HEAD" SHA-1 वर्तमान के लिए प्रतिबद्ध प्राप्त करने के लिए, Git-लॉग के साथ जटिल समाधान के लिए कोई जरूरत नहीं। "गिट टैग-एल" और "गिट लॉग" (और यहां तक ​​कि "गिट शो" भी नहीं) के जटिल समाधान के बजाय गिट-फॉर-रेफरी का उपयोग करें। मूल प्रश्न का उत्तर देने के लिए "गिट वर्णन" का प्रयोग करें। समस्या को हल करने के लिए जीआईटी-संस्करण-जीएन का प्रयोग करें। –

2

(अन्य सवाल में ग्रेग Hewgill के जवाब से) एक बेहतर समाधान हो जाएगा:

git name-rev --name-only --tags HEAD 

यदि यह रिटर्न "अनिर्धारित" तो आप एक टैग पर नहीं हैं। अन्यथा यह टैग नाम देता है। तो एक एक लाइनर करने के लिए मेरे दूसरे सवाल का जवाब कुछ इस तरह होगा:

git_tag=`git name-rev --name-only --tags HEAD | sed 's/^undefined$//'` 

यह कैसे काम करता की इंटरएक्टिव खोल उदाहरण:

$ git checkout master 
Already on "master" 
$ git name-rev --name-only --tags HEAD 
undefined 
$ git checkout some-tag 
Note: moving to "some-tag" which isnt a local branch 
If you want to create a new branch from this checkout, you may do so 
(now or later) by using -b with the checkout command again. Example: 
    git checkout -b <new_branch_name> 
HEAD is now at 1234567... Some comment blah blah 
$ git name-rev --name-only --tags HEAD 
some-tag 
+2

यह ** टैग से (कुछ अन्य शाखा है जो पहले से है वर्तमान में शाखा की जाँच करने के लिए के माध्यम से जैसे) सही ढंग से काम नहीं करता है, तो सिर है ** से पहुंचा जा सकता है, लेकिन यह एक टैग पर ही नहीं है। "कुछ-टैग ~ 3" –

+0

इसके अलावा, nitpicky होने के लिए, वहाँ नामित 'अनिर्धारित' ... –

5

यह करने के लिए सबसे अच्छा तरीका है git describe आदेश का उपयोग करने के लिए है:

Git-वर्णन - सबसे हाल ही टैग है कि एक से पहुंचा जा सकता है दिखाएँ प्रतिबद्ध

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

+0

धन्यवाद एक टैग हो सकता है: आप की तरह परिणाम मिलेगा। गिट-नेम-रेव की तुलना में इस विशिष्ट उद्देश्य के लिए गिट-वर्णन शेल स्क्रिप्ट में उपयोग करना उतना आसान नहीं लगता है। – JasonSmith

+0

मैं कहता हूं कि, क्योंकि किसी भी तर्क के साथ शाखा पर चलने पर पहली बार गिट-वर्णन त्रुटियां होती हैं। क्या आप 'git-description --tags' की अनुशंसा करेंगे? लेकिन अधिक महत्वपूर्ण बात यह बताने में तुच्छ नहीं है कि आप उचित टैग पर हैं या नहीं। आपको आउटपुट को पार्स करना होगा और हाइफ़न की तलाश करनी होगी। लेकिन क्या होगा अगर टैग नाम में हाइपेन्स हो? यही वजह है कि मैं पसंद 'Git नाम-रेफरी --name-केवल --tags HEAD' – JasonSmith

+0

पर्याप्त मेला, मुझे लगता है सबसे अच्छा विकल्प अपने विशेष आवेदन पर निर्भर करता है। मैंने रिलीज को स्वचालित रूप से लेबल करने के लिए अतीत में 'गिट वर्णन' का उपयोग किया है। –

4

Git-नाम-राजस्व का प्रयोग, स्क्रिप्ट के लिए पसंद किया जाता है क्योंकि यह Git पाइपलाइन का हिस्सा है जबकि Git-वर्णनचीनी मिट्टी के बरतन का हिस्सा है।

टैग के नाम को मुद्रित करने के लिए इस आदेश का उपयोग करें यदि हेड पॉइंट एक है, अन्यथा कुछ भी नहीं।

git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null | sed -n 's/^\([^^~]\{1,\}\)\(\^0\)\{0,1\}$/\1/p' 

नोट stderr के पुनर्निर्देशन/dev/बातिल के लिए - अन्यथा आपको एक त्रुटि संदेश मिल जाएगा कह रही:

fatal: cannot describe 'SOMESHA'" 

संपादित करें: sed में regex फिक्स्ड दोनों lighweight और एनोटेट समर्थन करने के लिए/हस्ताक्षरित टैग।

2

आप यह निर्धारित नहीं कर सकते कि वर्तमान चेकआउट "टैग है"। आप केवल यह निर्धारित कर सकते हैं कि वर्तमान चेकआउट एक प्रतिबद्ध था जिसमें टैग हैं।

अंतर यह है: यदि को इंगित करने वाले कई टैग हैं, तो गिट आपको यह नहीं बता सकता कि आपने चेकआउट के लिए उपयोग किया था, और न ही यदि आप वास्तव में वहां पहुंचने के लिए उपयोग करते हैं।

Jakub’s answer here पर git describe --exact-match (--tags) आधारित आप देता है सब (एनोटेट) टैग की "प्रथम"

और git describe इस तरह से उन्हें सॉर्ट करता:

  • एनोटेट टैग पहले
    • अनुसार क्रमबद्ध सबसे कम उम्र के पहले
  • हल्के टैग बाद में आ
    • द्विआधारी टैग नाम के अनुसार क्रमबद्ध (कि इसका अर्थ है वर्णानुक्रम में अगर यह अंग्रेजी एन्कोड किया गया है ASCII)
    • Git हल्के टैग के साथ मेटा डेटा की दुकान नहीं है, तो "सबसे कम उम्र के पहले"