जाँच करें कि क्या वर्तमान निर्देशिका एक गिट रिपॉजिटरी है


197

मैं zsh में गिट प्रबंधन के लिए पटकथा लिख ​​रहा हूं।

यदि वर्तमान निर्देशिका Git रिपॉजिटरी है, तो मैं कैसे जांच करूं? (जब मैं Git रेपो में नहीं होता, तो मैं आदेशों का एक गुच्छा निष्पादित नहीं करना चाहता और fatal: Not a git repositoryप्रतिक्रियाओं का एक गुच्छा प्राप्त करता हूं )।


क्या आपने प्रेरणा के लिए bash पूर्ण फ़ाइल (contrib / पूर्ण / git-complete.bash में) देखी है? मैं अपने bash प्रॉम्प्ट के हिस्से के रूप में __git_ps1 कमांड का उपयोग करता हूं। वास्तव में इसका अधिकांश हिस्सा zsh के भीतर ही होगा। __गित्दिर फंक्शन शायद वही है जो आप चाहते हैं।
21

1
@ पंजाब: आप ऐसा क्यों नहीं बनाते हैं?
अमरबेल

क्या आपने पहले से ही zsh वितरण में कार्यों की जाँच की है?
MBO


1
नोट: वर्तमान उत्तरों में से कोई भी $GIT_DIRया $GIT_WORK_TREEपर्यावरण चर पर विचार नहीं करता है , या वे कैसे बातचीत करते हैं।
o11c

जवाबों:


154

बैश पूरा होने की फ़ाइल से कॉपी किया गया है, यह करने के लिए एक भोली तरीका है

# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
# Distributed under the GNU General Public License, version 2.0.

if [ -d .git ]; then
  echo .git;
else
  git rev-parse --git-dir 2> /dev/null;
fi;

आप इसे किसी फ़ंक्शन में लपेट सकते हैं या स्क्रिप्ट में उपयोग कर सकते हैं।

बैश और zsh के लिए उपयुक्त एक पंक्ति की स्थिति में संघनित

[ -d .git ] && echo .git || git rev-parse --git-dir > /dev/null 2>&1

3
@William Pursell जब आपको आवश्यकता नहीं है तो कांटा क्यों? मुख्य रूप से तुच्छ मामले में गति के लिए।
जॅबी

16
उत्तर का उपयोग करने के लिए अद्यतन किया जाना चाहिए git rev-parse --is-inside-git-dir। मैं git rev-parse --is-inside-work-treeअपने PS1 को सेट करने से पहले व्यक्तिगत रूप से उपयोग करता हूं।
13

11
--is-inside-git-dirयदि आप वास्तव में एक भंडार की .gitनिर्देशिका के अंदर हैं तो @juliohm सच में ही वापस आएगा । मुझे नहीं लगता कि ओपी उस की तलाश कर रहा है।
nyuszika7h

7
जब आप गिट रेपो से बाहर होंगे तो --is-inside-work-treeन तो --is-inside-git-dirकाम करेंगे। देखें: groups.google.com/forum/#!topic/git-users/dWc23LFhWxE
fisherwebdev

7
यह विफल हो जाएगा अगर git निर्देशिका इसके अलावा कुछ और है .git। मजबूती के लिए, छोड़ें [ -d .git ]और सिर्फ उपयोग करें git rev-parse ...
पीटर जॉन एकलाम

134

आप उपयोग कर सकते हैं:

git rev-parse --is-inside-work-tree

यदि आप एक git repos वर्किंग ट्री में हैं तो 'true' प्रिंट करेंगे।

ध्यान दें कि यह अभी भी STDERR को आउटपुट देता है यदि आप एक git रेपो से बाहर हैं (और 'गलत' प्रिंट नहीं करता है)।

इस उत्तर से लिया गया: https://stackoverflow.com/a/2044714/12983


यह यह जांचने का सबसे सरल तरीका है।
कलबर्ट

3
यह अभी भी एक नंगे भंडार के लिए झूठा छापेगा जिसमें कोई काम करने वाला पेड़ नहीं है
noggin182

यह उप-निर्देशिका पर विचार नहीं करता है। मैं करता सत्यापित करने की आवश्यकता git rev-parse --show-toplevelसबफ़ोल्डर मैं जाँच कर रहा हूँ के साथ मैच
alper

चुना हुआ उत्तर कुछ भी नहीं छापा। यह एक काम किया।
स्कूटीब्लैड्स

47

Git Rev-parse --गित-दिर का उपयोग करें

अगर जीआईटी रेव-पार्से --गित-डिर> / देव / नल 2> & 1; फिर
  : # यह एक मान्य गिट रिपॉजिटरी है (लेकिन वर्तमान में काम कर रहा है
    # निर्देशिका शीर्ष स्तर नहीं हो सकता है।
    # अगर आप ध्यान दें तो git Rev-parse कमांड का आउटपुट चेक करें)
अन्य
  : # यह कोई गिट रिपॉजिटरी नहीं है
फाई

27

या आप ऐसा कर सकते हैं:

inside_git_repo="$(git rev-parse --is-inside-work-tree 2>/dev/null)"

if [ "$inside_git_repo" ]; then
  echo "inside git repo"
else
  echo "not in git repo"
fi

2
मुझे यह पसंद है क्योंकि यह एक उप-निर्देशिका से भी काम करता है
जोहान


7

सुनिश्चित नहीं है कि ऐसा करने के लिए सार्वजनिक रूप से सुलभ / प्रलेखित तरीका है (कुछ आंतरिक गिट कार्य हैं जो आप स्वयं गिट स्रोत में उपयोग / दुरुपयोग कर सकते हैं)

आप कुछ ऐसा कर सकते थे;

if ! git ls-files >& /dev/null; then
  echo "not in git"
fi

7

@Alex Cory के उत्तर पर आधारित :

[ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]

किसी भी निरर्थक संचालन और -eमोड में काम नहीं करता है।

  • जैसा कि @ go2null ने उल्लेख किया है , यह नंगे रेपो में काम नहीं करेगा। यदि आप किसी भी कारण से नंगे रेपो के साथ काम करना चाहते हैं, तो आप git rev-parseइसके उत्पादन की अनदेखी करते हुए, सफल होने के लिए जांच कर सकते हैं ।
    • मैं इसे एक कमी नहीं मानता क्योंकि उपरोक्त लाइन स्क्रिप्टिंग के लिए बनाई गई है, और वस्तुतः सभी gitकमांड केवल एक वर्कट्री के अंदर मान्य हैं। इसलिए स्क्रिप्टिंग उद्देश्यों के लिए, आप सबसे अधिक संभावना एक "गिट रेपो" के अंदर ही नहीं बल्कि एक वर्कट्री के अंदर होने में रुचि रखते हैं।

यह नंगे गिट रेपो के अंदर विफल रहता है
go2null

आउटपुट की जांच करने के बजाय, रिटर्न वैल्यू की जांच करना बेहतर है। बिल्कुल भी आह्वान न करें [। बस करो if git rev-parse --is-inside-work-tree; then ...(वांछित के रूप में पुनर्निर्देशन के साथ।)
विलियम पर्ससेल

1
@WilliamPursell यहां से बाहर निकलने के मूल्य की जाँच नहीं करता है: stackoverflow.com/questions/2180270/…
ivan_pozdeev

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

अगर आप लिंक्ड कमेंट पढ़ते हैं, तो आपको पता चल जाएगा कि मुझे यहां "काम नहीं करता" से मतलब है।
ivan_pozdeev

6

एक और उपाय है कमांड के एग्जिट कोड की जांच करना।

git rev-parse 2> /dev/null; [ $? == 0 ] && echo 1

यदि आप git रिपॉजिटरी फ़ोल्डर में हैं तो यह 1 प्रिंट करेगा।


ध्यान दें कि यह आरसी 0 होगा भले ही आप .gitनिर्देशिका के अंदर हों - जो आप चाहते हैं या नहीं कर सकते हैं।
ivan_pozdeev

Git के, sanely लिखा तो आप कर सकते हैं बस पास आप नहीं चाहते फ़ाइलों git rev-parse 2>&-
jthill

3

यह उत्तर एक नमूना POSIX शेल फ़ंक्शन और @ jabbie के उत्तर को पूरक करने के लिए एक उपयोग उदाहरण प्रदान करता है ।

is_inside_git_repo() {
    git rev-parse --is-inside-work-tree >/dev/null 2>&1
}

gitरिटर्न ERRORLEVEL 0अगर यह एक Git भंडार के अंदर है, वरना यह errorlevel रिटर्न 128। (यह रिटर्न भी करता है trueया falseयदि यह जीआईटी रिपॉजिटरी के अंदर है।)

उदाहरण का उपयोग करें

for repo in *; do
    # skip files
    [ -d "$repo" ] || continue
    # run commands in subshell so each loop starts in the current dir
    (
        cd "$repo"
        # skip plain directories
        is_inside_git_repo || continue
        printf '== %s ==\n' "$repo"
        git remote update --prune 'origin' # example command
        # other commands here
    )
done

अपर्याप्त। अंदर .git, यह सफल होगा लेकिन प्रिंट false
ivan_pozdeev

@ivan_pozdeev: अगर git rev-parse --is-inside-work-treeरिटर्न trueया falseतो यह है एक Git रेपो अंदर, और कहा कि क्या समारोह रिटर्न है। यह है, फ़ंक्शन सही है
go2null

विस्तार करने के लिए, उत्तर में विवरण देखें, git से लौटाए गए मान को अनदेखा किया जाता है, त्रुटि का उपयोग किया जाता है।
go2null

2

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

git स्टेटस> / dev / null 2> & 1 && गूंज हैलो वर्ल्ड!

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


2
शायद कई मामलों के लिए पर्याप्त है, लेकिन यह एक नंगे गिट रेपो पर विफल रहता है।
वाइल्डकार्ड

3
git statusएक बड़े / पुराने रेपो पर बहुत धीमा हो सकता है। मैं इसे इस उद्देश्य के लिए उपयोग नहीं करेगा।
हेनरेबोथा

1

क्यों बाहर निकलें कोड का उपयोग नहीं? एक Git भंडार वर्तमान निर्देशिका में मौजूद है, तो git branchऔर git tagआदेशों 0 के निकास कोड नहीं लौटाना; अन्यथा, एक गैर-शून्य निकास कोड वापस आ जाएगा। इस तरह, आप यह निर्धारित कर सकते हैं कि क्या एक गिट रिपॉजिटरी मौजूद है या नहीं। बस, आप चला सकते हैं:

git tag > /dev/null 2>&1 && [ $? -eq 0 ]

फायदा : फ्लेक्सिब। यह नंगे और गैर-नंगे दोनों रिपोजिटरी के लिए काम करता है, और श, ज़श और बैश में।

व्याख्या

  1. git tag: मौजूद है या नहीं, यह निर्धारित करने के लिए रिपॉजिटरी के टैग प्राप्त करना।
  2. > /dev/null 2>&1: सामान्य और त्रुटि आउटपुट सहित किसी भी चीज़ को प्रिंट करने से रोकना।
  3. [ $? -eq 0 ]: जांचें कि क्या पिछला कमांड एक्जिट कोड 0 के साथ लौटा है या नहीं। जैसा कि आप जानते हैं, हर गैर-शून्य निकास का मतलब कुछ बुरा हुआ है। $?पिछला आदेश के निकास कोड हो जाता है, और [, -eqऔर ]तुलना करते हैं।

एक उदाहरण के रूप में, आप check-git-repoनिम्नलिखित सामग्रियों के साथ एक फ़ाइल बना सकते हैं, इसे निष्पादन योग्य बना सकते हैं और इसे चला सकते हैं:

#!/bin/sh

if git tag > /dev/null 2>&1 && [ $? -eq 0 ]; then
    echo "Repository exists!";
else
    echo "No repository here.";
fi

0

# जाँच करें कि क्या git रेपो

if [ $(git rev-parse --is-inside-work-tree) = true ]; then
    echo "yes, is a git repo"
    git pull
else
    echo "no, is not a git repo"
    git clone url --depth 1
fi

यह सबसे अच्छा अभ्यास नहीं है। यदि किसी वर्किंग डायरेक्टरी के बाहर चला जाए, तो आपको "घातक: नहीं git रिपॉजिटरी (या किसी भी पैरेंट डायरेक्टरी में से कोई एक) मिलेगा: .it" stderr पर लिखा है, और "no, git repo नहीं है" stdout पर। यहां [बिल्कुल भी आह्वान करने की जरूरत नहीं है । बस करते हैं:if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then ....
विलियम Pursell

मेरे मामले में, मैं इसके साथ सहज हूं, और मैं अपने लॉग में इस गड़बड़ को ट्रैक करना चाहता हूं। चीयर्स!
पास्कल एंडी

0
if ! [[ $(pwd) = *.git/* || $(pwd) = *.git ]]; then 
  if type -P git >/dev/null; then
    ! git rev-parse --is-inside-work-tree >/dev/null 2>&1 || {
     printf '\n%s\n\n' "GIT repository detected." && git status
    }
  fi
fi

धन्यवाद ivan_pozdeev , अब मेरे पास एक परीक्षण है अगर .गित निर्देशिका के अंदर कोड नहीं चलेगा तो कोई त्रुटि नहीं छपी या गलत निकास स्थिति।

" ! [[$ (Pwd) = .गित / || $ (pwd) = * .गित]] " परीक्षण यदि आप एक .गित रेपो के अंदर नहीं हैं तो यह git कमांड चलाएगा। अंतर्निहित प्रकार कमांड का उपयोग यह जांचने के लिए किया जाता है कि क्या आपने गिट स्थापित किया है या यह आपके पैट के भीतर है। सहायता प्रकार देखें


0

यह कैसे हुआ:

if git status -s 2>/dev/null;then
    echo "this is a git repo"
else
    echo "this is NOT a git repo"
fi

-1

आप अपने zshrc में एक या दूसरे गिट-प्रॉम्प्ट टूल से अपने $ PS1 को जोड़ या बदल सकते हैं । इस तरह से आप आसानी से इस बात से अवगत हो सकते हैं कि क्या आप git रेपो में हैं और रेपो की स्थिति क्या है।


3
ओपी का पूरा सवाल यह था कि इसे एक स्क्रिप्ट के भीतर से कैसे किया जाए
एंड्रयू सी

और __git_ps1 का उपयोग किसी स्क्रिप्ट के भीतर से कैसे नहीं किया जा सकता है? गिट-प्रॉम्प्ट का पूरा बिंदु वर्तमान निर्देशिका की गिट स्थिति की जांच करना है, जो कि पूछा गया था।
jxqz

-1
! git rev-parse --is-inside-work-tree >/dev/null 2>&1 || { 
  printf '%s\n\n' "GIT repository detected." && git status
}

! भले ही आप इसे एक डायरेक्टरी में चलाते हों, जो कि git repo नहीं है, यह आपको कुछ घातक त्रुटियाँ नहीं देगा

> / Dev / बातिल 2> & 1 संदेश भेजता है करने के लिए / dev / बातिल तुम सिर्फ बाहर निकलें स्थिति के बाद कर रहे हैं के बाद से। {} के बाद सभी आदेशों तो आदेश समूहों के लिए कर रहे हैं || अगर हम प्रयोग करते हैं तो git रि-पार्स सफल हुआ! जो गित रेव-पार्से की निकास स्थिति को नकार दिया। Printf सिर्फ रेपो की स्थिति मुद्रित करने के लिए कुछ संदेश और Git स्थिति मुद्रित करने के लिए है।

इसे किसी फंक्शन में लपेटें या स्क्रिप्ट में रखें। उम्मीद है की यह मदद करेगा


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