यह निर्धारित करें कि क्या Git वर्किंग डायरेक्टरी स्क्रिप्ट से क्लीन है


82

मेरे पास एक स्क्रिप्ट है जो rsyncगंतव्य के रूप में गिट वर्किंग डायरेक्टरी के साथ चलती है। मैं चाहता हूं कि स्क्रिप्ट अलग-अलग व्यवहार के आधार पर हो अगर काम करने वाली निर्देशिका साफ है (प्रतिबद्ध करने के लिए कोई परिवर्तन नहीं), या नहीं। उदाहरण के लिए, यदि आउटपुट git statusनीचे है, तो मैं चाहता हूं कि स्क्रिप्ट बाहर निकले:

git status
Already up-to-date.
# On branch master
nothing to commit (working directory clean)
Everything up-to-date

यदि निर्देशिका साफ नहीं है, तो मैं चाहूंगा कि यह कुछ और आदेशों को निष्पादित करे।

मैं शेल स्क्रिप्ट में उपरोक्त की तरह आउटपुट की जांच कैसे कर सकता हूं?


क्या यहां अंतिम कमांड मदद से स्थिति की जांच होगी? ($?)
यूवीवी

क्या आप अधिक जानकारी दे सकते हैं? आपकी स्क्रिप्ट के लिए मुख्य विचार क्या है?
ताछोमी

@tachomi I ने संदर्भ को संपादित किया
brentwpeterson

आप यह मान सकते हैं कि यह साफ नहीं है और git reset --hard origin/branchयदि आप ऐसा करने जा रहे हैं, तो ऐसा करें ... जैसे कि आप किसी चीज को संकलित करने के बाद सफाई करने की कोशिश कर रहे हैं, आदि
स्नेकडॉक

1
@SnakeDoc आप कर सकते हैं, लेकिन मुझे लगता है कि उलटा मामला अधिक सामान्य होगा, अर्थात यदि स्थानीय निर्देशिका में बदलाव से बचने के लिए कार्यशील निर्देशिका गंदा है तो बाहर निकलें। दोनों मामलों पर विचार करने से भविष्य के पाठकों के लिए प्रश्न अधिक उपयोगी होगा।
थॉमस न्यूमैन

जवाबों:


133

आउटपुट को पार्स करना git statusएक बुरा विचार है क्योंकि आउटपुट का उद्देश्य मानव पठनीय है, मशीन-पठनीय नहीं। इस बात की कोई गारंटी नहीं है कि उत्पादन Git के भविष्य के संस्करणों में या अलग-अलग कॉन्फ़िगर किए गए वातावरणों में समान रहेगा।

UVVs की टिप्पणी सही रास्ते पर है, लेकिन दुर्भाग्य से बदले हुए कोड में git statusपरिवर्तन नहीं होने पर वापसी नहीं होती है। हालांकि, यह --porcelainविकल्प प्रदान करता है, जो आउटपुट को git status --porcelainस्क्रिप्ट के लिए एक आसान-से-पार्स स्वरूप में स्वरूपित करने का कारण बनता है , और गिट संस्करणों में और उपयोगकर्ता कॉन्फ़िगरेशन की परवाह किए बिना स्थिर रहेगा।

हम git status --porcelainएक संकेतक के रूप में खाली आउटपुट का उपयोग कर सकते हैं कि इसमें कोई बदलाव नहीं होना चाहिए:

if [ -z "$(git status --porcelain)" ]; then 
  # Working directory clean
else 
  # Uncommitted changes
fi

यदि हम कार्यशील निर्देशिका में अनियोजित फ़ाइलों के बारे में परवाह नहीं करते हैं, तो हम --untracked-files=noउन विकल्पों की उपेक्षा करने के विकल्प का उपयोग कर सकते हैं :

if [ -z "$(git status --untracked-files=no --porcelain)" ]; then 
  # Working directory clean excluding untracked files
else 
  # Uncommitted changes in tracked files
fi

उन स्थितियों के खिलाफ इसे और अधिक मजबूत बनाने के लिए जो वास्तव मेंgit status उत्पादन के बिना विफल होने का कारण बनती हैं stdout, हम चेक को परिष्कृत कर सकते हैं:

if output=$(git status --porcelain) && [ -z "$output" ]; then
  # Working directory clean
else 
  # Uncommitted changes
fi

यह भी ध्यान देने योग्य है कि, हालांकि git statusअर्थिंग एग्जिट कोड नहीं देता है जब वर्किंग डायरेक्टरी अस्वच्छ होती है, git diffतो --exit-codeविकल्प प्रदान करता है , जो इसे डिफरेंट यूटिलिटी के समान व्यवहार करता है , यानी 1मतभेद होने पर स्टेटस से बाहर निकलता है और 0जब कोई नहीं मिला।

इसका उपयोग करके, हम इसके साथ अस्थिर परिवर्तनों की जांच कर सकते हैं:

git diff --exit-code

और मंचन किया गया, लेकिन इसके साथ परिवर्तन नहीं किए गए:

git diff --cached --exit-code

यद्यपि git diffउपयुक्त तर्कों के माध्यम से सबमॉडल्स में अनट्रैक फाइल्स पर रिपोर्ट की जा सकती है --ignore-submodules, दुर्भाग्य से ऐसा लगता है कि वास्तविक वर्किंग डायरेक्टरी में अनट्रैक फाइल्स पर रिपोर्ट करने का कोई तरीका नहीं है। यदि कार्यशील निर्देशिका में अनट्रैक की गई फाइलें प्रासंगिक हैं, git status --porcelainतो संभवतः सबसे अच्छी शर्त है।


4
uhhh git status --porcelainकोड 0 के साथ बाहर निकल जाएगा, भले ही वहाँ प्रतिबद्ध और अनकही फ़ाइलों के लिए मंचन न किए गए परिवर्तन हों।
अलेक्जेंडर मिल्स

मुझे समय से पहले यह निर्धारित करने में दिलचस्पी थी कि git stashक्या कुछ होगा (यह उपयोगी रिटर्न कोड का उत्पादन नहीं करता है)। मुझे इसके साथ जोड़ना होगा, --ignore-submodulesअन्यथा git statusसबमॉडल परिवर्तनों को इंगित करेगा जो git stashअनदेखा करता है।
डेविन लेन

1
@AlexanderMills: मैंने वही देखा। लेकिन फिर जाँच की कि क्या if [ -zकर रहा था। इसका -zमतलब यह है कि अगर निम्नलिखित स्ट्रिंग खाली है, अगर मूल्यांकन करता है true। दूसरे शब्दों में, यदि इसका git status --porcelainकोई परिणाम नहीं है, तो रेपो साफ है। यदि नहीं, तो यह संशोधित / जोड़ी / हटा दी गई फ़ाइलों को सूचीबद्ध करता है और अब खाली स्ट्रिंग नहीं है। ifतब का मूल्यांकन false
Adeynack

19

उपयोग:

git diff-index --quiet HEAD

रिटर्न कोड कामकाजी निर्देशिका की स्थिति (0 = साफ, 1 = गंदा) को दर्शाता है। अनट्रैक की गई फ़ाइलों को अनदेखा कर दिया जाता है।


6
वर्तमान निर्देशिका में अनट्रेक्ट की गई फ़ाइलें 0 देता है।
एडम पार्किं

2
फ़ाइलें / छुआ गया था तो ओवरराइट लेकिन अन्यथा सूचकांक के समान हैं, आप पहली बार चलाने की जरूरत है git update-index --refreshइससे पहले कि git diff-index HEAD। अधिक जानकारी: stackoverflow.com/q/34807971/1407170
sffc

@AdamParkin मैं git add .इसे जारी करने से पहले सभी फाइलों को जोड़ देता हूं । आमतौर पर यह एक स्क्रिप्ट में इसका उपयोग करने का तरीका है
Ceztko

यह भी खूब रही। ध्यान दें कि गैर-शून्य का एक रिटर्न / एक्जिट कोड भी एक 'त्रुटि' के रूप में व्याख्या किया गया है, जो यदि आप सेट -ई के साथ एक स्क्रिप्ट में हैं तो आपकी स्क्रिप्ट 'गंदे' से बाहर निकल जाएगी। set +eकॉल करने से पहले git, और set -eआपके मूल्यांकन के बाद फिर से जोड़ने से इसे टाला जा सकता है $?
ओरियन एल्जेनिल

1

आंद्रे के उत्कृष्ट जवाब के लिए मामूली विस्तार ।

यह परिणामों का मूल्यांकन करने का एक तरीका है और यदि आप एक स्क्रिप्ट में हैं, जो पहले सेट -ई जारी की गई है, तो भी नुकसान से बचें ।

अनट्रैक की गई फ़ाइलों को अनदेखा कर दिया जाता है।

set +e
git diff-index --quiet HEAD

if [ $? == 1 ] ; then
  set -e
  GIT_MODS="dirty"
else
  set -e
  GIT_MODS="clean"
fi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.