Geçerli dizinin bir Git deposu olup olmadığını kontrol edin


199

Git yönetimi için bir dizi betik yazıyorum.

Geçerli dizinin Git deposu olup olmadığını nasıl kontrol edebilirim? (Git deposunda olmadığımda, bir sürü komut yürütmek ve bir sürü fatal: Not a git repositoryyanıt almak istemiyorum ).


İlham almak için bash tamamlama dosyasına (katkıda bulunan / tamamlama / git-completion.bash) baktınız mı? __Git_ps1 komutunu bash istemimin bir parçası olarak kullanıyorum. Aslında çoğu zsh içinde kaynaklanacak. __Gitdir işlevi muhtemelen istediğiniz işlevdir.
jabbie

1
@jabbie: neden bu cevabı vermiyorsun?
amarillion

Zsh dağıtımında zaten fonksiyonları kontrol ettiniz mi?
MBO


1
Not: mevcut cevapların hiçbiri $GIT_DIRveya $GIT_WORK_TREEortam değişkenlerini ya da nasıl etkileştiklerini dikkate almaz.
o11c

Yanıtlar:


155

Bash tamamlama dosyasından kopyalanan, aşağıdakileri yapmak için naif bir yoldur

# 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;

Bunu bir işlevde sarabilir veya bir komut dosyasında kullanabilirsiniz.

Bash ve zsh için uygun tek hatlı bir koşulda yoğunlaştırılmıştır

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

3
@William Pursell İhtiyacınız olmadığında neden çatal? Özellikle önemsiz durumlarda hız için.
jabbie

16
Cevap kullanılacak şekilde güncellenmelidir git rev-parse --is-inside-git-dir. git rev-parse --is-inside-work-treePS1'imi ayarlamadan önce kişisel olarak kullanıyorum .
juliohm

12
@juliohm --is-inside-git-dir, yalnızca bir veri havuzu .gitdizininin içindeyseniz true değerini döndürür . OP'nin bunu aradığını sanmıyorum.
nyuszika7h

7
Ne --is-inside-work-treede --is-inside-git-dirbir git repo dışında olduğunda çalışacaktır. bkz. groups.google.com/forum/#!topic/git-users/dWc23LFhWxE
fisherwebdev

7
Git dizini başka bir şeyse bu başarısız olur .git. Sağlamlık için, atlayın [ -d .git ]ve kullanın git rev-parse ....
Peter John Acklam

134

Kullanabilirsiniz:

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

Git depoları çalışma ağacındaysanız 'true' yazdıracaktır.

Git deposunun dışındaysanız (ve 'false' yazdırmazsa) yine de çıktıyı STDERR'a döndürdüğünü unutmayın.

Bu yanıttan alınmıştır: https://stackoverflow.com/a/2044714/12983


Bu kontrol etmek için en basit yoldur.
calbertts

3
Bu, çalışma ağacı olmayan çıplak bir depo için hala yanlış yazdıracak
noggin182

Bu, alt dizini dikkate almaz. git rev-parse --show-toplevelKontrol etmem gereken alt klasörle eşleştiğini doğrulamam gerekiyor
alper

Seçilen cevap hiçbir şey basmadı. Bu işe yaradı.
ScottyBlades

48

Git rev-parse kullan --git-dir

eğer git rev-parse --git-dir> / dev / null 2> & 1; sonra
  : # Bu geçerli bir git deposudur (ancak geçerli çalışma
    # dizin en üst seviye olmayabilir.
    # İsterseniz git rev-parse komutunun çıkışını kontrol edin)
Başka
  : # bu bir git deposu değil
fi


7

Bunu yapmanın halka açık / belgelenmiş bir yolu olup olmadığından emin değilim (git kaynağının kendisinde kullanabileceğiniz / kötüye kullanabileceğiniz bazı dahili git işlevleri vardır)

Gibi bir şey yapabilirsiniz;

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

7

@Alex Cory'nin cevabına dayanarak :

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

gereksiz işlemler içermez ve -emodda çalışır .

  • @ Go2null'un belirttiği gibi , bu çıplak bir repoda çalışmaz. Herhangi bir nedenle çıplak bir repo ile çalışmak istiyorsanız, sadece git rev-parseçıkışını görmezden gelerek başarılı olup olmadığını kontrol edebilirsiniz .
    • Bunu bir dezavantaj olarak görmüyorum, çünkü yukarıdaki satır komut dosyası oluşturma amaçlıdır ve neredeyse tüm gitkomutlar yalnızca bir çalışma ağacında geçerlidir. Komut dosyası oluşturma amacıyla, büyük olasılıkla yalnızca bir "git repo" içinde değil, bir çalışma ağacının içinde olmakla ilgileniyorsunuzdur.

Bu çıplak git repo içinde başarısız
go2null

Çıktıyı kontrol etmek yerine, dönüş değerini kontrol etmek daha iyi bir uygulamadır. Hiç çağırmayın [. Sadece yapın if git rev-parse --is-inside-work-tree; then ...(istendiği gibi yeniden yönlendirmelerle)
William Pursell

1
@WilliamPursell çıkış değerini kontrol etmek burada çalışmaz: stackoverflow.com/questions/2180270/…
ivan_pozdeev

@Ivan_pozdeev "İş" tanımınıza bağlıdır. Bu durumda, çıktıyı kontrol ederken dönüş değerini kontrol etmenin işe yaramadığını söyleyebilirim. Her iki durumda da, kabukta kod yazmak için en iyi uygulama açısından, dönüş değerini kontrol etmek daha uygundur.
William Pursell

@WilliamPursell Eğer bağlantılı yorum okuduysanız, burada "işe yaramaz" ne demek istediğimi bilirsiniz.
ivan_pozdeev

6

Başka bir çözüm, komutun çıkış kodunu kontrol etmektir.

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

Git depo klasöründeyseniz 1 yazdırılır.


.gitİstediğiniz veya istemediğiniz dizinin içinde olsanız bile, bunun rc 0 olacağını unutmayın .
ivan_pozdeev

Git istemediğin dosyaları kapatabilirsin diye git rev-parse 2>&-.
jthill

4

Bu yanıt örnek bir POSIX kabuk işlevi ve @ jabbie's'i tamamlamak için bir kullanım örneği sağlar cevabını .

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

git hata seviyesi döndürür 0 o bir git depo içinde ise aksi takdirde errorlevel döndürür 128. (Ayrıca geri döner trueveya falsegit deposunun içindeyse.)

Kullanım örneği

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

Yeterli değil. İçeride .gitbaşarılı olacak ama basacak false.
ivan_pozdeev

@ivan_pozdeev: Eğer git rev-parse --is-inside-work-treedöner trueya falseo zaman olduğu bir git repo iç ve bunun ne işlevin döndürdüğü olduğunu. yani, işlev doğrudur
go2null

genişletmek için yanıttaki açıklamaya bakın, git'ten döndürülen değer yoksayılır, kullanılan hata düzeyi.
go2null

2

bu benim için çalışıyor. Hataları hala alıyorsunuz, ancak bastırılması yeterince kolaydır. ayrıca alt klasörlerin içinden de çalışır!

git status> / dev / null 2> & 1 && echo Merhaba Dünya!

Koşullu olarak daha fazlasını yapmanız gerekiyorsa bunu bir if ifadesine koyabilirsiniz.


2
Belki birçok vaka için yeterince iyi, ama çıplak git repo başarısız.
Wildcard

3
git statusbüyük / eski bir repoda çok yavaş olabilir. Bu amaçla kullanmam.
henrebotha

1

Neden çıkış kodlarını kullanmıyorsunuz? Geçerli dizinde bir git deposu varsa git branchve git tagkomutlar 0 çıkış kodunu döndürür; Aksi takdirde, sıfırdan farklı bir çıkış kodu döndürülür. Bu şekilde bir git deposunun olup olmadığını belirleyebilirsiniz. Basitçe, şunları çalıştırabilirsiniz:

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

Avantajı : Flexibe. Hem çıplak hem de çıplak olmayan depolar için ve sh, zsh ve bash'da çalışır.

açıklama

  1. git tag: Var olup olmadığını belirlemek için havuzun etiketlerini alma.
  2. > /dev/null 2>&1: Normal ve hata çıktıları da dahil olmak üzere her şeyi yazdırmamak.
  3. [ $? -eq 0 ]: Önceki komutun çıkış kodu 0 ile dönüp dönmediğini kontrol edin. Bildiğiniz gibi, sıfır olmayan her çıkış kötü bir şey olduğu anlamına gelir. $?Bir önceki komutun çıkış kodu alır ve [, -eqve ]karşılaştırma yapmak.

Örnek olarak, check-git-repoaşağıdaki içeriklerle bir dosya oluşturabilir , yürütülebilir hale getirebilir ve çalıştırabilirsiniz:

#!/bin/sh

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

0

# git repo'nun olup olmadığını kontrol et

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

Bu en iyi uygulama değil. Bir çalışma dizininin dışında çalıştırılırsa, stderr üzerine yazılmış "fatal: bir git deposu (veya üst dizinlerden herhangi biri) değil: .git" ve stdout'ta "no, bir git repo değildir" alırsınız. Burada hiç çağırmaya gerek yok [. Sadece yap:if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then ....
William Pursell

Benim durumumda, bundan rahatım ve bu aksaklığı günlüklerimde izlemek istiyorum. Şerefe!
Pascal Andy

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

Teşekkür ederim ivan_pozdeev , Şimdi bir test var .git dizini içinde kodu çalışmaz böylece hiçbir hata yazdırıldı veya yanlış çıkış durumu.

" ! [[$ ( Pwd ) = .git / || $ (pwd) = * .git]] " bir .git deposunda değilseniz test eder, sonra git komutunu çalıştırır. Yerleşik tip komutu, git'in yüklü olup olmadığını veya PATH'inizde olup olmadığını kontrol etmek için kullanılır. yardım türüne bakın


0

Buna ne dersiniz:

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'nizdeki $ PS1'inizi ekleyebilir veya bir veya daha fazla git komut istemi aracıyla değiştirebilirsiniz . Bu şekilde bir git repo'sunda olup olmadığınızı ve repo durumunun içinde olup olmadığınızı rahatlıkla öğrenebilirsiniz.


3
OP'nin tüm sorusu bir senaryo içinde nasıl yapılacağıydı
Andrew C

ve __git_ps1 bir komut dosyasından nasıl kullanılamaz? Git komut isteminin bütün amacı, sorulan dizinin gitme durumunu kontrol etmektir.
jxqz

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

! bir git repo olmayan bir dizinde çalıştırsanız bile size bazı önemli hatalar vermeyecektir.

> / Dev / null 2> & 1 mesajlar gönderir / dev / null sadece çıkış durumu peşindeler beri. {} Sonuçta komutları böylece komut grupları içindir || git rev-ayrıştırma işlemi başarılı olduğumuzdan beri başarılı olursa çalışır! hangi git rev-parse çıkış durumunu olumsuzladı. printf sadece repo durumunu yazdırmak için bazı mesaj ve git durumunu yazdırmaktır.

Bir işleve sarın veya bir senaryoya koyun. Bu yardımcı olur umarım


1
Yeterli değil. İçeride .gitbaşarılı olacak ama basacak false.
ivan_pozdeev
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.