संशोधन संख्या के लिए Git क्या है?


244

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

मान लें कि हम संस्करण 3.0.8 पर काम करते हैं और हर बग फिक्स का अपना संशोधन नंबर होता है जिसका उपयोग हम इस बग फिक्स के बारे में बात करते समय कर सकते हैं। इसलिए यदि मैं Git में कोड को 3.0.8 में टैग करता हूं तो मैं एक संशोधन संख्या या कुछ अन्य विस्तृत प्रकार की पहचान के रूप में क्या उपयोग कर सकता हूं? मुझे लगता है कि हैश इंसानों के लिए इतना अनुकूल नहीं है।



वहाँ एक है लेख संभव समाधान में से एक के लिए। यह थोड़ा भारी लग सकता है, लेकिन "git लॉग" आउटपुट में इंटरग्रेट किया गया है और इसके लिए "git push / pull / fetch" के अलावा कोई अतिरिक्त कमांड की आवश्यकता नहीं है।
दिमित्री पावेलेंको

दुर्भाग्य से @DmitryPavlenko से जुड़ा लेख एक मृत डोमेन पर है: gitsvn.x10.mx विषय का कोई संकेत नहीं होने से, किसी के लिए भी इसे अन्यत्र खोजना मुश्किल होगा।
माइकल डोनोह्यू

नोट: git वर्णन के साथ और अधिक संक्षिप्त विवरण की आवश्यकता नहीं: देखें stackoverflow.com/a/41308073/6309
VonC

1
नहीं, लारेंस गोंसाल्वेस, यह "कैसे कमिट गिनती प्राप्त करने के लिए?" - यह संस्करण संख्या के बारे में है, और भले ही कम से कम एक जैसे दिखने के लिए कमिट
फ़िड को फ़िडेल

जवाबों:


149

आपके लिए अच्छी या बुरी खबर, वह है संशोधन संख्या है। मुझे इस बात से भी परेशानी हुई जब मैंने SVN से git में स्विच किया।

आप एक विशेष संस्करण के लिए "रिलीज़" के रूप में एक निश्चित संशोधन को टैग करने के लिए गिट में "टैगिंग" का उपयोग कर सकते हैं, जिससे उस संशोधन को संदर्भित करना आसान हो जाता है। इस ब्लॉग पोस्ट को देखें

समझने की महत्वपूर्ण बात यह है कि git में संशोधन संख्याएँ नहीं हो सकती हैं - विकेंद्रीकृत प्रकृति के बारे में सोचें। यदि उपयोगकर्ता A और B दोनों अपनी स्थानीय रिपॉजिटरी के लिए प्रतिबद्ध हैं, तो कैसे क्रमिक संशोधन संख्या को यथोचित रूप से निर्दिष्ट कर सकते हैं? A को एक दूसरे के परिवर्तनों को धकेलने / खींचने से पहले B का कोई ज्ञान नहीं है।

बगफिक्स शाखाओं के लिए सरलीकृत शाखाओं में बँधने वाली एक और चीज़ देखने को मिलती है:

एक रिलीज के साथ शुरू करें: 3.0.8। फिर, उस रिलीज के बाद, यह करें:

git branch bugfixes308

यह बगफिक्स के लिए एक शाखा बनाएगा। शाखा की जाँच करें:

git checkout bugfixes308

अब आप जो भी बदलाव चाहते हैं, उसे सुधारें।

git commit -a

उन्हें प्रतिबद्ध करें, और मास्टर शाखा पर वापस जाएँ:

git checkout master

फिर दूसरी शाखा से उन परिवर्तनों में शामिल हों:

git merge bugfixes308

इस तरह, आपके पास एक अलग रिलीज़-विशिष्ट बगफ़िक्स शाखा है, लेकिन आप अभी भी बगफ़िक्स परिवर्तनों को अपने मुख्य देव ट्रंक में खींच रहे हैं।


11
मैं समझ गया कि हैश रिवीजन नंबर है, लेकिन मुझे उम्मीद है कि यह :-) नहीं था)) बहुत अच्छी व्याख्या के लिए धन्यवाद और इससे निपटने के लिए अब सुझाव के लिए।
राडेक

3
आपका स्वागत है। मैं git से बहुत निराश था जब मैंने पहली बार इसे SVN से उठाया था, लेकिन अब मैं दूसरे तरीके से स्विंग करता हूं ...
22

4
ALSO, जब से मैंने इसे पोस्ट किया है, तब से थोड़ी देर हो गई है, लेकिन याद रखें कि आप "git checkout -b new_branch_name" करने के लिए "git Branch foo" और "git checkout foo" को वन-लाइनर के रूप में भी कर सकते हैं।
मकदाद

1
क्या मैं सही हूं कि हैश "सच" हैश है, और दूरस्थ रूप से अनुक्रमिक भी नहीं? तो, महत्वपूर्ण बात, अगर बग डेटाबेस कहता है fixed in 547cc3e..c4b2eba, और आपके पास कुछ अन्य संशोधन हैं, तो आपको पता नहीं है कि क्या आपके कोड को ठीक करने वाला है या नहीं ?! निश्चित रूप से गिट-सेंट्रल के गेट्स के पास इसके लिए एक समाधान है?!?!
ओली

3
एसवीएन में, तथ्य यह है कि एक बग को r42 में तय किया गया है, आपको इस बारे में नहीं बताता है कि क्या यह वास्तव में जैसे ही आप शाखाओं के रूप में r43 में तय किया गया है।
मैथ्यू मोय

186

आधुनिक गिट के साथ (मेरे मामले में 1.8.3.4) और उन शाखाओं का उपयोग न करना जो आप कर सकते हैं:

$ git rev-list --count HEAD
68

22
उपयोग करने पर विचार करेंgit rev-list --count --first-parent HEAD
फ्लिम

8
इस जानकारी (संख्या 68) को देखते हुए, क्या कोड को फिर से प्राप्त करने के लिए संशोधन का निर्धारण करने का एक तरीका है? मान लीजिए कि "संशोधन 68" एक परीक्षण वातावरण में जारी किया गया है, विकास जारी है, और बाद में एक डेवलपर को स्रोत नियंत्रण से "संशोधन 68" को फिर से प्राप्त करने की आवश्यकता है। वह क्लोन करने के लिए विशिष्ट संस्करण को कैसे लक्षित करेगा? या मैं Git के बारे में कुछ याद कर रहा हूँ जो इसे अनावश्यक बनाता है?
डेविड

9
ध्यान रखें कि यह समाधान विभिन्न डेवलपर्स के लिए अलग-अलग परिणाम देगा। इसके अलावा, "काउंट" से कमिट की ओर पीछे की गणना करने पर अलग-अलग डेवलपर्स के लिए अलग-अलग कमेंट्स आएंगे !! यह Git की वितरित प्रकृति की वजह से है और यह एक ही समय के दौरान अलग-अलग रिपॉजिटरी में घटित होता है, लेकिन git rev-list --count HEADअंतिम पुश और पुल कब बनाए गए थे , इस पर निर्भर नहीं किया जा सकता है।
जेसन

2
@ जेसन, डेविड की टिप्पणी से --first-parentआपकी चिंता दूर होती है? मैं एक दुर्लभ किनारे मामले की वजह से एक प्रतीत होता है सबसे सरल समाधान से बचने के लिए नफरत करता हूँ अगर वहाँ एक समान रूप से सरल समाधान या अधिक मजबूत बनाने के लिए रास्ता है।
21

4
@ मार्खू, --first-parentमदद करता है। जब तक कोई रिबासिंग नहीं किया जाता है और एक ही शाखा का उपयोग हमेशा रिलीज बनाने के लिए किया जाता है (और इस रिलीज संख्या की गणना करना, निश्चित रूप से), मुझे लगता है कि इसका उपयोग किया जा सकता है। हालांकि, मैं अभी भी अनिश्चित हूं कि यह हमेशा उस प्रतिबद्ध की पहचान करेगा जो रिलीज से आया था। ऐसी बहुत सी चीजें हैं जो यहां गलत हो सकती हैं ... लेकिन फिलहाल मैं ऐसा कुछ नहीं सोच सकता जो निश्चित रूप से इसे तोड़ देगा (मेरे ऊपर "जब तक" कथन)। git describeविधि एक और जवाब में उल्लेख किया जाने का रास्ता है। यदि आप मानव पठनीय कुछ चाहते हैं तो एक टैग बनाएं।
जेसन

104

git describeआदेश में एक से थोड़ा अधिक मानव पठनीय नाम है जो किसी विशिष्ट प्रतिबद्ध करने के लिए संदर्भित करता है बनाता है। उदाहरण के लिए, प्रलेखन से:

Git.git के वर्तमान पेड़ की तरह कुछ के साथ, मुझे मिलता है:

[torvalds@g5 git]$ git describe parent
v1.0.4-14-g2414721

यानी मेरी "पैरेंट" शाखा का वर्तमान प्रमुख v1.0.4 पर आधारित है, लेकिन चूंकि इसमें कुछ शीर्ष हैं, इसलिए वर्णन में अतिरिक्त कमिट की संख्या ("14") और एक संक्षिप्त वस्तु का नाम शामिल है। अंत में खुद ("2414721")।

जब तक आप विशेष रूप से रिलीज़ को टैग करने के लिए समझदारी से नामित टैग का उपयोग करते हैं, तब तक यह लगभग एक SVN "संशोधन संख्या" के बराबर माना जा सकता है।


7
मैं यह नोट करना चाहूंगा कि यह तभी काम करता है जब आपके gitभंडार में पहले से ही टैग हों; यदि ऐसा नहीं होता है, तो आपको "घातक: कोई नाम नहीं मिला है, कुछ भी वर्णन नहीं कर सकता है" - ढेर अतिप्रवाह ; इसका मतलब है कि आपको खुद को टैग सेट करना होगा।
सादाउ

14
@ सादाऊ: यदि आप इसका उपयोग किसी स्क्रिप्ट या किसी चीज़ में कर रहे हैं git describeऔर कभी असफल नहीं होना चाहते हैं, तो git describe --alwaysविकल्प का उपयोग करें ।
ग्रेग हेवगिल

क्या git describeस्रोत को खोजने के लिए आउटपुट का उपयोग किया जा सकता है, किसी तरह? लघु रूप से गिनती की लघु लॉग में करता है, मेरा मतलब है।
Lii

@ एलआईआई: "सोर्स कमेट" से आपका क्या तात्पर्य है? दोनों निकटतम टैग ( v1.0.4) और सबसे हालिया आईडी ( 2414721) पहले से ही git वर्णन आउटपुट का हिस्सा हैं।
ग्रेग हेवगिल

@GregHewgill: हां, धन्यवाद, जब मैंने सवाल पूछा तो मुझे महसूस नहीं हुआ कि "संक्षिप्त वस्तु का नाम" एक मूल्य है जिसका उपयोग कमिटमेंट की पहचान करने के लिए किया जा सकता है। ये तो बहुत खूब है!
Lii

67

अन्य पोस्टर सही हैं, कोई "संशोधन-संख्या" नहीं है।

मुझे लगता है कि "रिलीज़" के लिए टैग का उपयोग करने का सबसे अच्छा तरीका है!

लेकिन मैंने निम्नलिखित का उपयोग नकली संशोधन संख्याओं में किया (सिर्फ ग्राहकों को संशोधन और प्रगति देखने के लिए, क्योंकि वे जीआईटी से उतने ही बढ़ते संशोधन चाहते थे जितना कि वे तोड़फोड़ द्वारा उपयोग करते हैं)।

"HEAD" का "वर्तमान संशोधन" दिखाएं इसे प्रयोग करके नकली बनाया गया है:

git rev-list HEAD | wc -l

लेकिन क्या होगा अगर क्लाइंट मुझे बताता है कि 1302 "संशोधन" में एक बग है?

इसके लिए मैंने निम्नलिखित को अपने ~ / .gitconfig के [उपनाम] अनुभाग में जोड़ा:

show-rev-number = !sh -c 'git rev-list --reverse HEAD | nl | awk \"{ if(\\$1 == "$0") { print \\$2 }}\"'

का उपयोग करते हुए git show-rev-number 1302 बाद हैश प्रिंट होगा "संशोधन" के लिए :)

मैंने कुछ समय पहले उस "तकनीक" के बारे में एक ब्लॉग पोस्ट (जर्मन में) बनाया था।


@Radek - "कभी-कभी यह जानने की आवश्यकता होती है कि 'कोड परिवर्तन = प्रतिबद्ध' कुछ निश्चित किया गया है" - तब git bisect(लिंक) यह पहचानने के लिए उपयुक्त उपकरण है कि कौन कब क्या बदल गया।
माइकल

@ रादेक हाँ यह एक बढ़ती हुई संख्या है। यह सिर्फ HEAD में आपके द्वारा चेक किए गए संशोधनों को गिनाता है। इसलिए हर प्रतिबद्ध एक नया संशोधन है। यह विभिन्न शाखाओं के लिए काम नहीं करेगा।
ओडरवेट

1
मुझे आपका हल पसंद है। कृपया ध्यान दें कि आप इसे सरल कर सकते हैं: शो-रेव-नंबर =! Sh -c 'git रिव-लिस्ट --reverse HEAD | awk एनआर == $ 0 '
Avner

@avner धन्यवाद! मैंने अपने जीवन में बहुत अधिक
जाग का

3
मुझे उपयोग करना थाgit rev-list --reverse HEAD | awk "{ print NR }" | tail -n 1
गेरी

27

गिट में संशोधन की संख्या की एक जैसी अवधारणा नहीं है। इसके बजाय एक कमिट के साथ दिए गए प्रत्येक स्नैपशॉट को SHA1 चेकसम द्वारा टैग किया गया है। क्यों? एक वितरित संस्करण नियंत्रण प्रणाली में चल रहे रेवनो के साथ कई समस्याएं हैं:

पहला, चूंकि विकास बिल्कुल रैखिक नहीं है, एक संख्या का लगाव एक समस्या के रूप में हल करना मुश्किल है, जो एक प्रोग्रामर के रूप में आपकी आवश्यकता को पूरा करेगा। एक संख्या जोड़कर इसे ठीक करने की कोशिश करना जल्दी समस्याग्रस्त हो सकता है जब संख्या आपकी अपेक्षा के अनुरूप व्यवहार नहीं करती है।

दूसरा, विभिन्न मशीनों पर संशोधन संख्या उत्पन्न की जा सकती है। इससे संख्याओं का सिंक्रनाइज़ेशन बहुत कठिन हो जाता है - विशेषकर चूंकि कनेक्टिविटी एक तरफ़ा है; आपके पास उन सभी मशीनों तक पहुंच भी नहीं हो सकती है जिनमें भंडार है।

तीसरा, जीआईटी में, जो अब डिफंक्शन ओपनसीएम प्रणाली द्वारा कुछ हद तक अग्रणी है, एक कमिट की पहचान (कमिट क्या है) इसके नाम (एसएचए आईडी) के बराबर है । यह नामकरण = पहचान अवधारणा बहुत मजबूत है। जब आप हाथ में एक प्रतिबद्ध नाम के साथ बैठते हैं तो यह एक अक्षम्य तरीके से प्रतिबद्ध की पहचान भी करता है। यह बदले में, आप भ्रष्टाचार के लिए पहले प्रारंभिक एक पर वापस आने के लिए अपने सभी आवागमन की जाँच कर सकते हैंgit fsck कमांड के ।

अब, क्योंकि हमारे पास संशोधनों का एक डीएजी (डायरेक्टेड एसाइक्लिक ग्राफ) है और ये वर्तमान पेड़ का गठन करते हैं, हमें आपकी समस्या को हल करने के लिए कुछ उपकरणों की आवश्यकता है: हम विभिन्न संस्करणों में कैसे भेदभाव करते हैं। सबसे पहले, यदि आप दिए गए उपसर्ग, 1516bd हैश का हिस्सा छोड़ सकते हैं कहता है, विशिष्ट रूप से आपकी प्रतिबद्धता की पहचान करता है। लेकिन यह भी बल्कि विरोधाभास है। इसके बजाय, ट्रिक टैग और या शाखाओं का उपयोग करना है। एक टैग या शाखा "पीले स्टिक इट नोट" के समान है, जिसे आप किसी दिए गए प्रतिबद्ध SHA1-id से जोड़ते हैं। टैग, संक्षेप में, गैर-गतिशील होने के लिए हैं, जबकि एक शाखा तब आगे बढ़ेगी जब उसके HEAD में नए कमिट किए जाएंगे। टैग या शाखा के चारों ओर एक कमिट को संदर्भित करने के तरीके हैं, git-Rev-parse का मैन पेज देखें।

आमतौर पर, यदि आपको किसी विशिष्ट कोड कोड पर काम करने की आवश्यकता है, तो वह टुकड़ा परिवर्तन के दौर से गुजर रहा है और ऐसा होना चाहिए जैसे कि किसी विषय नाम के साथ एक शाखा हो। बहुत सारी शाखाएँ बनाना (20-30 प्रति प्रोग्रामर अनसुना नहीं है, कुछ 4-5 के लिए दूसरों को काम करने के लिए प्रकाशित किया गया है) प्रभावी पकड़ के लिए चाल है। काम का हर टुकड़ा अपनी शाखा के रूप में शुरू होना चाहिए और फिर जब यह परीक्षण किया जाता है तो विलय कर दिया जाना चाहिए। अप्रकाशित शाखाओं को पूरी तरह से फिर से लिखा जा सकता है और इतिहास को नष्ट करने का यह एक हिस्सा है।

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


18

यदि आप रुचि रखते हैं, तो मैंने प्रारूप के तहत यहां संस्करण संख्याओं को स्वचालित रूप से प्रबंधित किया है

<major>.<minor>.<patch>-b<build>

जहां बिल्ड कमिट की कुल संख्या है। आप में दिलचस्प कोड देखेंगे Makefile। यहाँ संस्करण संख्या के विभिन्न भाग तक पहुँचने के लिए प्रासंगिक हिस्सा है:

LAST_TAG_COMMIT = $(shell git rev-list --tags --max-count=1)
LAST_TAG = $(shell git describe --tags $(LAST_TAG_COMMIT) )
TAG_PREFIX = "latex-tutorial-v"

VERSION  = $(shell head VERSION)
# OR try to guess directly from the last git tag
#VERSION    = $(shell  git describe --tags $(LAST_TAG_COMMIT) | sed "s/^$(TAG_PREFIX)//")
MAJOR      = $(shell echo $(VERSION) | sed "s/^\([0-9]*\).*/\1/")
MINOR      = $(shell echo $(VERSION) | sed "s/[0-9]*\.\([0-9]*\).*/\1/")
PATCH      = $(shell echo $(VERSION) | sed "s/[0-9]*\.[0-9]*\.\([0-9]*\).*/\1/")
# total number of commits       
BUILD      = $(shell git log --oneline | wc -l | sed -e "s/[ \t]*//g")

#REVISION   = $(shell git rev-list $(LAST_TAG).. --count)
#ROOTDIR    = $(shell git rev-parse --show-toplevel)
NEXT_MAJOR_VERSION = $(shell expr $(MAJOR) + 1).0.0-b$(BUILD)
NEXT_MINOR_VERSION = $(MAJOR).$(shell expr $(MINOR) + 1).0-b$(BUILD)
NEXT_PATCH_VERSION = $(MAJOR).$(MINOR).$(shell expr $(PATCH) + 1)-b$(BUILD)

9

एक बैश फ़ंक्शन:

git_rev ()
{
    d=`date +%Y%m%d`
    c=`git rev-list --full-history --all --abbrev-commit | wc -l | sed -e 's/^ *//'`
    h=`git rev-list --full-history --all --abbrev-commit | head -1`
    echo ${c}:${h}:${d}
}

कुछ इस तरह का उत्पादन

$ git_rev
2:0f8e14e:20130220

अर्थात्

commit_count:last_abbrev_commit:date_YYmmdd

इस तरह की बात उपयोगी हो सकती है, लेकिन अगर कोई वृद्धिशील संस्करण संख्याओं में रुचि रखता है, तो वे फील्ड पदों को स्वैप करेंगे (गैर-वृद्धि) हैश अंतिम है।
मार्क

8

प्रतिबद्ध के SHA1 हैश एक सबवर्सन संशोधन संख्या के बराबर है।


7
दुर्भाग्य से इसमें एक संशोधन संख्या से काफी भिन्न गुण हैं। यह लंबे समय तक है, और यह नीरसता में वृद्धि नहीं करता है। लगता है कि वितरण के लिए भुगतान करने की कीमत है ...
संहिताओं InChaos

1
@CodeInChaos: मुझे पता है कि आपको क्या मिल रहा है, लेकिन आम तौर पर हैश कोड के केवल पहले 6 या 8 अक्षरों के साथ कमिट्स को संदर्भित करना संभव है।
क्रिस पिटमैन

5
@ रेकडेक: वे अद्वितीय गारंटी नहीं हैं (हालांकि यदि आप टकराव पाते हैं तो आप कुछ छोटी मात्रा में सेलिब्रिटी जीत सकते हैं)।
Slartibartfast

8
@Radek en.wikipedia.org/wiki/Collision_attack के अनुसार , हैश के 4 वर्णों के साथ आपके पास 16 बिट आईडी है, जिसका अर्थ है कि एक रेपो में 256 (= 2 ^ (16/2) के साथ कमिट करता है, एक 50 है % मौका है कि दो कमिट में एक ही चार-चार-उपसर्ग है (और 65536 के साथ यह निश्चित है, तब से 4-चार Ids की सीमा समाप्त हो गई है)। जब आप एक चार को जोड़ते हैं, तो आपके पास 20 बिट आईडी होती है, जिसका मतलब है कि 50% सीमा 1024 कमिट पर है। लेकिन चूंकि यह एक सांख्यिकीय पैरामीटर है, कुछ भी गारंटी नहीं देता है कि इस तरह के टकराव पहले नहीं होते हैं।
रूडी

2
चूंकि हैश सामग्री पर आधारित है, यह अभी भी एक संभावना है कि क्या दो कमिट में एक ही हैश उपसर्ग है, निश्चितता नहीं। 65536 में यह बहुत संभावना है कि दो में एक ही चार-चार उपसर्ग होगा, लेकिन यह अभी भी निश्चित नहीं है। एक तरफ के रूप में, पूर्ण हैश में अभी तक कोई टक्कर नहीं है, लेकिन गिट इस पर काम कर रहा है :) stackoverflow.com/questions/3475648/…
goodeye

6

यही मैंने दूसरों के समाधानों के आधार पर अपने मेकफाइल में किया। नोट न केवल यह आपके कोड को एक संशोधन संख्या देता है, यह हैश भी जोड़ता है जो आपको रिलीज को फिर से बनाने की अनुमति देता है।

# Set the source control revision similar to subversion to use in 'c'
# files as a define.
# You must build in the master branch otherwise the build branch will
# be prepended to the revision and/or "dirty" appended. This is to
# clearly ID developer builds.
REPO_REVISION_:=$(shell git rev-list HEAD --count)
BUILD_BRANCH:=$(shell git rev-parse --abbrev-ref HEAD)
BUILD_REV_ID:=$(shell git rev-parse HEAD)
BUILD_REV_ID_SHORT:=$(shell git describe --long --tags --dirty --always)
ifeq ($(BUILD_BRANCH), master)
REPO_REVISION:=$(REPO_REVISION_)_g$(BUILD_REV_ID_SHORT)
else
REPO_REVISION:=$(BUILD_BRANCH)_$(REPO_REVISION_)_r$(BUILD_REV_ID_SHORT)
endif
export REPO_REVISION
export BUILD_BRANCH
export BUILD_REV_ID

3
यह git-describeत्रुटियों से बचने के लिए उपयोग करने का सबसे सुरक्षित तरीका लगता है , git describe --always --dirty --long --tagsजिसके साथ उन सभी मामलों में काम करता है जिनके बारे में मैं सोच सकता हूं।
मार्कहु 19

5

बिल्ड नंबर के रूप में git हैश का उपयोग करने में समस्या यह है कि यह एकतरफा नहीं बढ़ रहा है। ओएसजीआई बिल्ड नंबर के लिए टाइम-स्टैम्प का उपयोग करने का सुझाव देता है। ऐसा लगता है कि शाखा में आने वाले की संख्या का उपयोग तोड़फोड़ या परिधि परिवर्तन संख्या के स्थान पर किया जा सकता है।


5

मैंने Git से संस्करण की जानकारी प्राप्त करने और टैगिंग को सरल बनाने के लिए कुछ PowerShell उपयोगिताओं को लिखा

फ़ंक्शंस: गेट-लास्टवर्जन, गेट-रिविजन, गेट-नेक्स्टमजोरवर्सन, गेट-नेक्स्टमिनॉर विसर्जन, टैगनजमाजोरवर्सन, टैगनैनमोरवर्सन

# Returns the last version by analysing existing tags,
# assumes an initial tag is present, and
# assumes tags are named v{major}.{minor}.[{revision}]
#
function Get-LastVersion(){
  $lastTagCommit = git rev-list --tags --max-count=1
  $lastTag = git describe --tags $lastTagCommit
  $tagPrefix = "v"
  $versionString = $lastTag -replace "$tagPrefix", ""
  Write-Host -NoNewline "last tagged commit "
  Write-Host -NoNewline -ForegroundColor "yellow" $lastTag
  Write-Host -NoNewline " revision "
  Write-Host -ForegroundColor "yellow" "$lastTagCommit"
  [reflection.assembly]::LoadWithPartialName("System.Version")

  $version = New-Object System.Version($versionString)
  return $version;
}

# Returns current revision by counting the number of commits to HEAD
function Get-Revision(){
   $lastTagCommit = git rev-list HEAD
   $revs  = git rev-list $lastTagCommit |  Measure-Object -Line
   return $revs.Lines
}

# Returns the next major version {major}.{minor}.{revision}
function Get-NextMajorVersion(){
    $version = Get-LastVersion;
    [reflection.assembly]::LoadWithPartialName("System.Version")
    [int] $major = $version.Major+1;
    $rev = Get-Revision
    $nextMajor = New-Object System.Version($major, 0, $rev);
    return $nextMajor;
}

# Returns the next minor version {major}.{minor}.{revision}
function Get-NextMinorVersion(){
    $version = Get-LastVersion;
    [reflection.assembly]::LoadWithPartialName("System.Version")
    [int] $minor = $version.Minor+1;
    $rev = Get-Revision
    $next = New-Object System.Version($version.Major, $minor, $rev);
    return $next;
}

# Creates a tag with the next minor version
function TagNextMinorVersion($tagMessage){
    $version = Get-NextMinorVersion;
    $tagName = "v{0}" -f "$version".Trim();
    Write-Host -NoNewline "Tagging next minor version to ";
    Write-Host -ForegroundColor DarkYellow "$tagName";
    git tag -a $tagName -m $tagMessage
}

# Creates a tag with the next major version (minor version starts again at 0)
function TagNextMajorVersion($tagMessage){
    $version = Get-NextMajorVersion;
    $tagName = "v{0}" -f "$version".Trim();
    Write-Host -NoNewline "Tagging next majo version to ";
    Write-Host -ForegroundColor DarkYellow "$tagName";
    git tag -a $tagName -m $tagMessage
}

4

प्रत्येक प्रतिबद्ध में एक अद्वितीय हैश होता है। इसके अलावा गिट में कोई संशोधन संख्या नहीं हैं। यदि आप अधिक उपयोगकर्ता-मित्रता चाहते हैं तो आपको स्वयं को टैग करना होगा।


3

मैं सिर्फ एक और संभावित दृष्टिकोण को नोट करना चाहूंगा - और यह है कि git git-notes (1) का उपयोग करके , v 1.6.6 के बाद से अस्तित्व में है ( नोट टू सेल्फ - गिट ) (मैं gitसंस्करण 1.7.9.5 का उपयोग कर रहा हूं )।

मूल रूप से, मैं git svnरैखिक इतिहास (कोई मानक लेआउट, कोई शाखाएं, कोई टैग नहीं) के साथ एक SVN रिपॉजिटरी को क्लोन करता था, और मैं क्लोन gitरिपॉजिटरी में संशोधन संख्या की तुलना करना चाहता था । इस git क्लोन में डिफ़ॉल्ट रूप से टैग नहीं हैं, इसलिए मैं इसका उपयोग नहीं कर सकता git describe। यहां संभावना है कि रणनीति केवल रैखिक इतिहास के लिए काम करेगी - सुनिश्चित नहीं है कि यह मर्ज आदि के साथ कैसे बदल जाएगा; लेकिन यहां मूल रणनीति है:

  • git rev-listसभी प्रतिबद्ध इतिहास की सूची के लिए पूछें
    • चूंकि rev-list"रिवर्स कालानुक्रमिक क्रम" में डिफ़ॉल्ट रूप से है, इसलिए हम इसके --reverseस्विच का उपयोग सबसे पहले पहले किए गए कमिट की सूची प्राप्त करने के लिए करेंगे
  • उपयोग bashकरने के लिए खोल
    • संशोधन काउंटर के रूप में प्रत्येक प्रतिबद्ध पर एक काउंटर चर बढ़ाएँ,
    • प्रत्येक कमिट के लिए "अस्थायी" गिट नोट जनरेट करें और जोड़ें
  • फिर, का उपयोग करके लॉग ब्राउज़ git logसाथ--notes है, जो भी एक प्रतिबद्ध के नोट, जो इस मामले में "संशोधन संख्या" होगा डंप हो जाएगा
  • जब किया जाता है, तो अस्थायी नोट मिटा दें ( NB: मुझे यकीन नहीं है कि ये नोट प्रतिबद्ध हैं या नहीं; वे वास्तव में नहीं दिखाते हैंgit status )

पहले, आइए ध्यान दें कि gitनोटों का एक डिफ़ॉल्ट स्थान है - लेकिन आप refनोटों के लिए (एरेन्स) भी निर्दिष्ट कर सकते हैं - जो उन्हें एक अलग निर्देशिका में संग्रहीत करेगा .git; उदाहरण के लिए, gitरेपो फोल्डर में रहते हुए , आप यह git notes get-refदेखने के लिए कॉल कर सकते हैं कि कौन सी डायरेक्टरी होगी:

$ git notes get-ref
refs/notes/commits
$ git notes --ref=whatever get-ref
refs/notes/whatever

ध्यान देने वाली बात यह है कि यदि आप notes addए के साथ हैं --ref, तो आपको बाद में भी उस संदर्भ का फिर से उपयोग करना होगा - अन्यथा आपको " XXX के लिए कोई नोट नहीं मिला " जैसी त्रुटियां मिल सकती हैं ... " ।

इस उदाहरण के लिए, मैंने ref"लाइनरेव" (रैखिक संशोधन के लिए) नोटों को कॉल करने के लिए चुना है - इसका मतलब यह भी है कि यह संभावना नहीं है कि प्रक्रिया पहले से मौजूद नोटों के साथ हस्तक्षेप करेगी। मैं भी --git-dirस्विच का उपयोग कर gitरहा हूं, नौसिखिया होने के बाद से , मुझे इसे समझने में कुछ समस्याएं थीं - इसलिए मैं "बाद में याद रखना" चाहूंगा :); और मैं भी उपयोग करते समय --no-pagerस्पॉनिंग को दबाने के लिए उपयोग करता हूं ।lessgit log

इसलिए, आप एक निर्देशिका में हैं, एक सबफ़ोल्डर के साथ myrepo_gitजो एक gitभंडार है; कोई भी ऐसा कर सकता है:

### check for already existing notes:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.

### iterate through rev-list three, oldest first,
### create a cmdline adding a revision count as note to each revision

$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
  TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
  TCMD="$TCMD add $ih -m \"(r$((++ix)))\""; \
  echo "$TCMD"; \
  eval "$TCMD"; \
done

# git --git-dir=./myrepo_git/.git notes --ref linrev add 6886bbb7be18e63fc4be68ba41917b48f02e09d7 -m "(r1)"
# git --git-dir=./myrepo_git/.git notes --ref linrev add f34910dbeeee33a40806d29dd956062d6ab3ad97 -m "(r2)"
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev add 04051f98ece25cff67e62d13c548dacbee6c1e33 -m "(r15)"

### check status - adding notes seem to not affect it:

$ cd myrepo_git/
$ git status
# # On branch master
# nothing to commit (working directory clean)
$ cd ../

### check notes again:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# (r15)

### note is saved - now let's issue a `git log` command, using a format string and notes:

$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)
# 77f3902: _user_: Sun Apr 21 18:29:00 2013 +0000:  >>test message 14<< (r14)
# ...
# 6886bbb: _user_: Sun Apr 21 17:11:52 2013 +0000:  >>initial test message 1<< (r1)

### test git log with range:

$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)

### erase notes - again must iterate through rev-list

$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
  TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
  TCMD="$TCMD remove $ih"; \
  echo "$TCMD"; \
  eval "$TCMD"; \
done
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# Removing note for object 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# git --git-dir=./myrepo_git/.git notes --ref linrev remove f34910dbeeee33a40806d29dd956062d6ab3ad97
# Removing note for object f34910dbeeee33a40806d29dd956062d6ab3ad97
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 04051f98ece25cff67e62d13c548dacbee6c1e33
# Removing note for object 04051f98ece25cff67e62d13c548dacbee6c1e33

### check notes again:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.

तो, कम से कम मेरे विशिष्ट मामले में पूरी तरह से रैखिक इतिहास में बिना शाखाओं के, संशोधन संख्या इस दृष्टिकोण के साथ मेल खाती है - और इसके अलावा, ऐसा लगता है कि यह दृष्टिकोण का उपयोग करने की अनुमति देगा git log संशोधन श्रेणियों के साथ , जबकि अभी भी सही संशोधन संख्या मिल रही है - YMMV एक अलग संदर्भ के साथ, हालांकि ...

आशा है कि यह किसी की मदद करता है,
चीयर्स!


संपादित करें: ठीक है, यहाँ यह gitउपरोक्त छोरों के लिए उपनाम के साथ थोड़ा आसान है, कहा जाता है setlinrevऔर unsetlinrev; जब आपके git रिपॉजिटरी फ़ोल्डर में, करते हैं ( नोट bashभागने से बचने के लिए, # 16136745 भी देखें - एक अर्ध जोड़ें जिसमें अर्धविराम वाला एक git उपनाम शामिल हो ):

cat >> .git/config <<"EOF"
[alias]
  setlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
      TCMD=\"git notes --ref linrev\"; \n\
      TCMD=\"$TCMD add $ih -m \\\"(r\\$((++ix)))\\\"\"; \n\
      #echo \"$TCMD\"; \n\
      eval \"$TCMD\"; \n\
    done; \n\
    echo \"Linear revision notes are set.\" '"

  unsetlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
      TCMD=\"git notes --ref linrev\"; \n\
      TCMD=\"$TCMD remove $ih\"; \n\
      #echo \"$TCMD\"; \n\
      eval \"$TCMD 2>/dev/null\"; \n\
    done; \n\
    echo \"Linear revision notes are unset.\" '"
EOF

... तो आप बस git setlinrevरैखिक संशोधन नोटों को शामिल करने की कोशिश करने से पहले आह्वान कर सकते हैं; और git unsetlinrevउन नोटों को हटाने के लिए जब आप कर रहे हैं; गिट रेपो निर्देशिका के अंदर से एक उदाहरण:

$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 <<

$ git setlinrev
Linear revision notes are set.
$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)
$ git unsetlinrev
Linear revision notes are unset.

$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 <<

इन उपनामों को पूरा करने में जो समय लगेगा, वह भंडार इतिहास के आकार पर निर्भर करेगा।


2

जिन लोगों के पास चींटी निर्माण प्रक्रिया है, आप इस लक्ष्य के साथ गिट पर एक परियोजना के लिए एक संस्करण संख्या उत्पन्न कर सकते हैं:

<target name="generate-version">

    <exec executable="git" outputproperty="version.revisions">
        <arg value="log"/>
        <arg value="--oneline"/>
    </exec>

    <resourcecount property="version.revision" count="0" when="eq">
        <tokens>
            <concat>
                <filterchain>
                    <tokenfilter>
                        <stringtokenizer delims="\r" />
                    </tokenfilter>
                </filterchain>
            <propertyresource name="version.revisions" />
            </concat>
        </tokens>
    </resourcecount>
    <echo>Revision : ${version.revision}</echo>

    <exec executable="git" outputproperty="version.hash">
        <arg value="rev-parse"/>
        <arg value="--short"/>
        <arg value="HEAD"/>
    </exec>
    <echo>Hash : ${version.hash}</echo>


    <exec executable="git" outputproperty="version.branch">
        <arg value="rev-parse"/>
        <arg value="--abbrev-ref"/>
        <arg value="HEAD"/>
    </exec>
    <echo>Branch : ${version.branch}</echo>

    <exec executable="git" outputproperty="version.diff">
        <arg value="diff"/>
    </exec>

    <condition property="version.dirty" value="" else="-dirty">
        <equals arg1="${version.diff}" arg2=""/>
    </condition>

    <tstamp>
        <format property="version.date" pattern="yyyy-mm-dd.HH:mm:ss" locale="en,US"/>
    </tstamp>
    <echo>Date : ${version.date}</echo>

    <property name="version" value="${version.revision}.${version.hash}.${version.branch}${version.dirty}.${version.date}" />

    <echo>Version : ${version}</echo>

    <echo file="version.properties" append="false">version = ${version}</echo>

</target>

परिणाम इस तरह दिखता है:

generate-version:
    [echo] Generate version
    [echo] Revision : 47
    [echo] Hash : 2af0b99
    [echo] Branch : master
    [echo] Date : 2015-04-20.15:04:03
    [echo] Version : 47.2af0b99.master-dirty.2015-04-20.15:04:03

गंदा झंडा यहाँ तब है जब आपके पास फ़ाइल (नों) है जब आप संस्करण संख्या उत्पन्न नहीं करते हैं। क्योंकि आमतौर पर, जब आप अपने एप्लिकेशन का निर्माण / पैकेज करते हैं, तो प्रत्येक कोड संशोधन को रिपॉजिटरी में होना चाहिए।


1

कम्‍पनी के SHA-1 आईडी के साथ, सर्वर समय की तारीख और समय में मदद मिली होगी?

कुछ इस तरह:

19 अगस्त 2013 को 11:30:25 बजे हुआ और 6886bb7be18e63fc4be68ba41917b48f02e09d7_19aug2013_113025 के रूप में दिखाया जाएगा


1

Git मैनुअल से, टैग इस मुद्दे का एक शानदार उत्तर हैं:

Git में एक एनोटेट टैग बनाना सरल है। निर्दिष्ट करने का सबसे आसान तरीका है-जब आप टैग कमांड चलाते हैं:

$ git tag -a v1.4 -m 'my version 1.4'

$ git tag
v0.1
v1.3
v1.4

2.6 बेसिक्स की जाँच करें - टैगिंग


बहुत बुरा आपको चूक को बदलने के लिए हुप्स के माध्यम से कूदना होगा:By default, the git push command doesn’t transfer tags to remote servers.
मार्कहु

1

हम इस आदेश का उपयोग संस्करण और गिट से संशोधन प्राप्त करने के लिए कर रहे हैं :

git describe --always --tags --dirty

यह लौट आता है

  • संशोधन के रूप में हैश प्रतिबद्ध है जब कोई टैगिंग प्रयोग किया जाता है (उदाहरण के लिए gcc7b71f)
  • टैग पर संस्करण के रूप में नाम टैग (उदाहरण के लिए) v2.1.0 , रिलीज़ के लिए उपयोग किया जाता है)
  • टैग का नाम, अंतिम टैग के बाद से संशोधन संख्या और टैग के बाद हैश करना (जैसे v5.3.0-88-gcc7b71f )
  • ऊपर के रूप में एक "गंदा" टैग के रूप में अगर काम कर रहे पेड़ स्थानीय संशोधनों (जैसे) है v5.3.0-88-gcc7b71f-dirty ) है

इसे भी देखें: https://www.git-scm.com/docs/git-describe#Documentation/git-describe.txt


0

विजुअल स्टूडियो के लिए पोस्ट बिल्ड इवेंट

echo  >RevisionNumber.cs static class Git { public static int RevisionNumber =
git  >>RevisionNumber.cs rev-list --count HEAD
echo >>RevisionNumber.cs ; }

-1

उपयोग करने पर विचार करें

git-rev-label

जैसे प्रारूप में गिट रिपॉजिटरी संशोधन के बारे में जानकारी देता है master-c73-gabc6bec। टेम्पलेट स्ट्रिंग या पर्यावरण चर और Git से जानकारी के साथ फाइल कर सकते हैं। कार्यक्रम के संस्करण के बारे में जानकारी प्रदान करने के लिए उपयोगी: शाखा, टैग, कमिट हैश, गिनती, गंदी स्थिति, दिनांक और समय। सबसे उपयोगी चीजों में से एक कमिट्स की गणना है, विलय वाली शाखाओं में नहीं लेना - केवल पहले माता-पिता।

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