यदि वर्तमान शाखा में कुछ भी प्रतिबद्ध नहीं है तो कैसे जांचें?


172

लक्ष्य एक अस्पष्ट स्थिति प्राप्त करना है जिसे एक शेल कमांड में मूल्यांकन किया जा सकता है।

मैंने कोशिश की, git statusलेकिन यह हमेशा 0 रिटर्न देता है, भले ही इसके लिए कोई वस्तु हो।

git status
echo $?  #this is always 0

मेरे पास एक विचार है लेकिन मुझे लगता है कि यह एक बुरा विचार है।

if [ git status | grep -i -c "[a-z]"> 2 ];
then
 code for change...
else
  code for nothing change...
fi

कोई अन्य तरीका?


निम्नलिखित समाधान के साथ अपडेट करें, मार्क लॉन्गेयर की पोस्ट देखें

मैंने यह कोशिश की लेकिन यह एक समस्या का कारण बनता है।

if [ -z $(git status --porcelain) ];
then
    echo "IT IS CLEAN"
else
    echo "PLEASE COMMIT YOUR CHANGE FIRST!!!"
    echo git status
fi

मुझे निम्नलिखित त्रुटि मिलती है [: ??: binary operator expected

अब, मैं उस आदमी को देख रहा हूं और कोशिश करता हूं कि वह अंतर को अलग कर दे।

================= मेरी आशा के लिए कोड, और बेहतर जवाब की उम्मीद ======================

#if [ `git status | grep -i -c "$"` -lt 3 ];
# change to below code,although the above code is simple, but I think it is not strict logical
if [ `git diff --cached --exit-code HEAD^ > /dev/null && (git ls-files --other --exclude-standard --directory | grep -c -v '/$')` ];
then
        echo "PLEASE COMMIT YOUR CHANGE FIRST!!!"
    exit 1

else
    exit 0
fi

4
अद्यतन अनुभाग में, यह है कि आप वास्तव में नहीं कर रहे हैं लगता है Eckes में पता चलता है उसके जवाब के रूप में वे कहते हैं, आप के आसपास डबल उद्धरण डाल करने के लिए की जरूरत है - $(git status --porcelain)। इसके अलावा, यदि आप अपने संदेश में विस्मयादिबोधक चिह्न लगाना चाहते हैं, तो आपको दोहरे उद्धरण चिह्नों के बजाय एकल उद्धरणों का उपयोग करने की आवश्यकता होगी - अर्थात इसके echo 'PLEASE COMMIT YOUR CHANGE FIRST!!!'बजाय होना चाहिए
मार्क लॉन्गेयर

4
जैसा कि मार्क कहता है: आपको दोहरे उद्धरण चिह्नों को लगाने की आवश्यकता है$(git status --porcelain) , जैसा कि मैंने आपको बताया था!
Eckes

1
यह प्रश्न बहुत अधिक उपयोगी होगा, यदि इसमें उत्तरों के कुछ हिस्सों को शामिल नहीं किया गया है।
12:58

@ 9nix00 वह करें जो आपको बताया गया है और ऊपर अपनी शेल स्क्रिप्ट में बग को संपादित और ठीक करें: बग: यदि [-z $ (कुछ कमांड)] FIX: यदि [-z "$ (कुछ कमांड)"]
मार्श

जवाबों:


232

परीक्षण का एक विकल्प यह है कि क्या आउटपुट git status --porcelainखाली है प्रत्येक स्थिति का परीक्षण करने के लिए जो आपको अलग से परवाह है। उदाहरण के लिए, कोई भी हमेशा देखभाल नहीं कर सकता है, अगर आउटपुट में अनट्रैक फाइलें हैं git status

उदाहरण के लिए, यह देखने के लिए कि क्या कोई स्थानीय अस्थिर परिवर्तन हैं, आप निम्न रिटर्न कोड देख सकते हैं:

git diff --exit-code

यह जांचने के लिए कि क्या कोई परिवर्तन हैं, जो मंचित हैं, लेकिन प्रतिबद्ध नहीं हैं, आप निम्नलिखित के रिटर्न कोड का उपयोग कर सकते हैं:

git diff --cached --exit-code

अंत में, यदि आप इस बारे में जानना चाहते हैं कि क्या आपके काम करने वाले पेड़ में ऐसी कोई भी फाइल नहीं है जिसे अनदेखा नहीं किया गया है, तो आप यह जांच सकते हैं कि निम्न कमांड का आउटपुट खाली है या नहीं:

git ls-files --other --exclude-standard --directory

अद्यतन: आप नीचे पूछते हैं कि क्या आप आउटपुट में निर्देशिकाओं को बाहर करने के लिए उस कमांड को बदल सकते हैं। आप खाली निर्देशिकाओं को जोड़कर बाहर कर सकते हैं --no-empty-directory, लेकिन उस आउटपुट में सभी निर्देशिकाओं को बाहर करने के लिए मुझे लगता है कि आपको आउटपुट को फ़िल्टर करना होगा, जैसे कि:

git ls-files --other --exclude-standard --directory | egrep -v '/$'

-vकरने के लिए egrepसाधन के लिए एक ही उत्पादन लाइनों है कि पैटर्न से मेल नहीं खाते, और पैटर्न किसी भी लाइन है कि एक साथ समाप्त होता है से मेल खाता है /


मैंने इन युक्तियों को झुकाव दिया है और एक मुद्दा है। अर्थात्, git ls-files --other --exclude-standard --directory का उपयोग करें सूची में निर्देशिका शामिल करें। क्या किसी ने इन निर्देशिका को बाहर रखा है?
9nix00

हां, मैं यही चाहता हूं। और मैं नई स्क्रिप्ट-कोड के लिए अपनी पोस्ट को अपडेट करता हूं। मुझे लगता है कि आपका सुझाव अधिक सख्त तार्किक है, हालांकि अधिक कोड योग्य ... और आशा है कि बेहतर उत्तर दिखाई देंगे।
9nix00

3
@albfan: यह git-diff मैन पेज में है : "प्रोग्राम को कोड (जैसे) में अंतर के साथ बाहर निकलें (1)। अर्थात, यदि अंतर थे तो यह 1 से बाहर निकलता है और यदि कोई अंतर नहीं है।"
मार्क लोंगेयर

बस इंगित करने के लिए, यह कम से कम 2007 13da0fc0 के बाद से है , शेल स्क्रिप्ट के लिए वास्तव में आसान है, और गिट के पुराने संस्करणों के साथ पूरी तरह से संगत है
एल्बफैन

10
--quiet(जिसका तात्पर्य है --exit-code) आउटपुट को चुप करना, जो केवल बाहर निकलने का कोड चाहते हैं।
phs

113

रिटर्न का मूल्य git statusआपको केवल बाहर निकलने का कोड बताता है git status, न कि यदि कोई संशोधन करने के लिए प्रतिबद्ध हैं।

यदि आप git statusआउटपुट का अधिक कंप्यूटर-पढ़ने योग्य संस्करण चाहते हैं , तो प्रयास करें

git status --porcelain

git statusउस बारे में अधिक जानकारी के लिए विवरण देखें ।

नमूना उपयोग (स्क्रिप्ट बस परीक्षण करता है यदि git status --porcelainकोई आउटपुट देता है, कोई पार्सिंग की आवश्यकता नहीं है):

if [ -n "$(git status --porcelain)" ]; then
  echo "there are changes";
else
  echo "no changes";
fi

कृपया ध्यान दें कि आपको परीक्षण करने के लिए स्ट्रिंग को उद्धृत करना होगा, अर्थात का आउटपुट git status --porcelain। परीक्षण निर्माण के बारे में अधिक संकेत के लिए, उन्नत बैश स्क्रिप्टिंग गाइड (अनुभाग स्ट्रिंग तुलना ) देखें।


नमस्ते, आप एक अच्छा सुझाव देते हैं, मैंने इसे आज़माया, लेकिन स्क्रिप्ट में, यह कुछ समस्या का कारण बनता है, मैंने इसे सुधार लिया, अगर हम इसका उपयोग करते हैं अगर [-z $ (git स्टेटस - एम्पोरैमल)]; इसे कुछ त्रुटि मिलेगी, [: ??: बाइनरी ऑपरेटर को उम्मीद है कि मैं मैनुअल खोजता हूं और इसका उपयोग करता हूं यदि [-z $ (गिट स्थिति - शोर्ट)]; यह काम कर सकता है, धन्यवाद!
9nix00

क्षमा करें, अभी भी समस्या का कारण है। जब कमिट साफ हो। चीनी मिट्टी के बरतन और लघु दोनों का उपयोग करें। लेकिन जब प्रतिबद्ध साफ नहीं है। यह त्रुटि का कारण होगा। [: ??] बाइनरी ऑपरेटर की उम्मीद है। मुझे लगता है कि शायद हमें इसे एनकोड करने के लिए बेस 64 का उपयोग करने की कोशिश करनी चाहिए। मुझे कोशिश करने दो! base64 कमांड टूल डाउनलोड करना .... lol
9nix00

जब समस्या साफ न हो तो यह समस्या पैदा करता है।
9nix00

1
महान समाधान। अतिरिक्त मजबूती के लिए आप || echo noकमांड प्रतिस्थापन के लिए अपील कर सकते हैं ताकि कार्यक्षेत्र गलती से साफ न git statusहो जाए अगर बुनियादी रूप से विफल हो। इसके अलावा, आपका कोड (सराहनीय रूप से) POSIX- आज्ञाकारी है, लेकिन चूंकि आप एक bash गाइड से लिंक करते हैं, इसलिए मुझे यह जोड़ना चाहिए कि यदि आप [[ ... ]]POSIX- संगत के बजाय bash का उपयोग [ ... ]करते हैं, तो आपको कमांड प्रतिस्थापन को डबल-कोट करने की आवश्यकता नहीं है (हालांकि यह है) कोई नुकसान नहीं करता है) [[ -z $(git status --porcelain) ]]:।
mklement0

@ कुछ दिन पहले मैंने एक नया रेपो शुरू किया था, मैंने एक कमेंट जोड़ा, मैंने कुछ प्री-कमिट-हुक लिखने और यह जांचने की कोशिश की कि क्या प्रतिबद्ध होना है और आपने जो कहा वह मेरे केस पर काम नहीं किया।
अलिनोसार

33

यदि आप मेरे जैसे हैं, तो आप जानना चाहते हैं कि क्या हैं:

1) मौजूदा फ़ाइलों में परिवर्तन 2) नई गयी फाइलें 3) हटाई गई फाइलें

और विशेष रूप से 4) के बारे में जानना नहीं चाहता है।

यह करना चाहिए:

git status --untracked-files=no --porcelain

अगर रेपो साफ है तो स्क्रिप्ट से बाहर निकलने के लिए मेरा बैश कोड है। यह अनट्रैक फाइल्स विकल्प के लघु संस्करण का उपयोग करता है:

[[ -z $(git status -uno --porcelain) ]] && echo "this branch is clean, no need to push..." && kill -SIGINT $$;

4
+1 के लिए —untracked-files=no; मुझे लगता है कि आपके परीक्षण को सरल बनाया जा सकता है [[ -z $(git status --untracked-files=no --porcelain) ]]git statusजब तक कुछ मौलिक गलत हो जाता है, stderr पर लिख नहीं चाहिए - और फिर आप करते हैं कि उत्पादन देखना चाहते हैं। (यदि आप उस घटना में अधिक मजबूत व्यवहार चाहते थे, || echo noतो कमांड प्रतिस्थापन के लिए आवेदन करें ताकि स्वच्छता के लिए परीक्षण अभी भी विफल हो जाए)। स्ट्रिंग तुलना / -zऑपरेटर मल्टी-लाइन स्ट्रिंग्स से निपट सकते हैं - जिसकी कोई आवश्यकता नहीं है tail
mklement0

2
धन्यवाद @ mklement0, यहां तक ​​कि थोड़ा छोटा:[[ -z $(git status -u no --porcelain) ]]
मूडबूम

1
सुधार: मेरा छोटा संस्करण वास्तव में "नहीं" नामक फ़ाइल की स्थिति की जांच करता है! Bzzt। होना चाहिए: [[ -z $(git status -uno --porcelain) ]]
मूडबूम

2
मैं अनुवर्ती की सराहना करता हूं; यह एक सूक्ष्म बग है - सबक यह है कि वैकल्पिक तर्कों के साथ छोटे विकल्पों में तर्क को सीधे जोड़ा जाना चाहिए , बीच में कोई व्हाट्सएप नहीं है। सीधे अपने उत्तर में सही लघु संस्करण को शामिल करने के बारे में कैसे?
mklement0

9

परीक्षण करने के लिए git status --porcelainएक सरल के साथ संयोजन करना संभव है grep

if git status --porcelain | grep .; then
    echo Repo is dirty
else
    echo Repo is clean
fi

मैं इसे कभी-कभी एक साधारण लाइनर के रूप में उपयोग करता हूं:

# pull from origin if our repo is clean
git status --porcelain | grep . || git pull origin master

-qsइसे चुप करने के लिए अपने grep कमांड में जोड़ें ।


2
लालित्य के लिए +1; मामूली कैविएट: git statusमोटे तौर पर विफल होना चाहिए (जैसे, एक भ्रष्ट रेपो), आपका परीक्षण गलती से एक साफ कार्यक्षेत्र की रिपोर्ट करेगा । एक विकल्प का उपयोग करना है git status --porcelain 2>&1, लेकिन अगर आपने grep का उपयोग किया है तो यह त्रुटि संदेश 'खाएगा' -q। (है कि लेनदेन के साथ लालित्य खो देगा: (git status --porcelain || echo err) | grep -q .)
mklement0

वैकल्पिक रूप से, कोई भी लिख सकता है:test -z "$(git status --porcelain)" || git pull origin master
VasiliNovikov

5

Git source कोड से एक sh स्क्रिप्ट आती है जिसमें निम्नलिखित शामिल हैं।

require_clean_work_tree () {
    git rev-parse --verify HEAD >/dev/null || exit 1
    git update-index -q --ignore-submodules --refresh
    err=0

    if ! git diff-files --quiet --ignore-submodules
    then
        echo >&2 "Cannot $1: You have unstaged changes."
        err=1
    fi

    if ! git diff-index --cached --quiet --ignore-submodules HEAD --
    then
        if [ $err = 0 ]
        then
            echo >&2 "Cannot $1: Your index contains uncommitted changes."
        else
            echo >&2 "Additionally, your index contains uncommitted changes."
        fi
        err=1
    fi

    if [ $err = 1 ]
    then
        test -n "$2" && echo >&2 "$2"
        exit 1
    fi
}

यह स्निपलेट दिखाता है कि इसका उपयोग कैसे संभव है git diff-filesऔर git diff-indexयह पता लगाने के लिए कि क्या पहले से ज्ञात फ़ाइलों में कोई परिवर्तन हैं। हालांकि यह आपको यह पता लगाने की अनुमति नहीं देता है कि क्या काम करने वाले पेड़ में एक नई अज्ञात फ़ाइल जोड़ी गई है।


यह नई फ़ाइलों को छोड़कर ठीक काम करता है। हम इसे जोड़ सकते हैं। अगर ! git ls-files --other --exclude-standard --directory | grep -c -v '/' $ 'तो बाहर निकलें 0 इको "कृपया अपनी नई फ़ाइल करें, यदि आप इसे नहीं जोड़ना चाहते हैं, तो कृपया इसे git-ign फ़ाइल में जोड़ें।" बाहर निकलें 1 Fi
9nix00

बस if [ -n "$(git ls-files --others --exclude-standard)" ]बिना किसी अतिरिक्त पाइपिंग या ग्रेपिंग के, अनट्रैक फ़ाइलों का पता लगाने के लिए पर्याप्त होना चाहिए।
एरोमास्टर

5

मैं इस पर एक परीक्षण करूँगा:

git diff --quiet --cached

या यह स्पष्ट हो:

git diff --quiet --exit-code --cached

कहाँ पे:

--exit-कोड

(1) के समान कोड के साथ प्रोग्राम से बाहर निकलें। यही है, अगर यह अंतर था तो 1 के साथ बाहर निकलता है और 0 का मतलब कोई मतभेद नहीं है।

--चुप

कार्यक्रम के सभी आउटपुट को अक्षम करें। इंप्लाइज - नेट-कोड


3

मैं चर्चा में थोड़ा देर से हूँ, लेकिन अगर यह केवल है कि आपको 0 से बाहर निकलें कोड की आवश्यकता है यदि git status --porcelainरिटर्न कुछ भी नहीं है और! = 0 और, यह कोशिश करें:

exit $( git status --porcelain | wc -l )

यह 255 से अधिक लाइनों के होने पर समस्या होने के जोखिम पर लाइनों की संख्या को बाहर निकलने का कोड बना देगा। इसलिए

exit $( git status --porcelain | head -255 | wc -l )

उस के लिए खाता होगा;)


1
यह मूल रूप से अपरिभाषित होगा यदि आउटपुट की 255 से अधिक लाइनें हैं।
ट्रिपलआई

अच्छी तरह से देखा, धन्यवाद!
Skeeve

2

मैं एक स्क्रिप्ट में इस का उपयोग कर रहा हूँ:

  • 0 जब सब कुछ साफ हो
  • 1 जब एक अलग या अनट्रैक फ़ाइलें होती हैं

    [-z "$ (गिट स्थिति - चीनी मिट्टी के बरतन)"]


का उपयोग कर if ! git diff --quiet; thenक्लीनर और अधिक प्रदर्शन (मुझे लगता है) है। दूसरे शब्दों में, बाहर निकलने के कोड का उपयोग करें, न कि स्टडआउट का।
अलेक्जेंडर मिल्स

1
@AlexanderMills git diff --quietgit status --porcelain कैश्ड परिवर्तनों के लिए अलग व्यवहार करता है ।
मार्टिन वॉन विटिच

0

सुंदर नहीं है, लेकिन काम करता है:

git status | grep -qF 'working directory clean' || echo "DIRTY"

यह सुनिश्चित नहीं है कि संदेश स्थानीय निर्भर है, इसलिए शायद LANG=Cसामने रखा जाए ।

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