Jak sprawdzić, czy bieżący katalog to repozytorium Git? (Gdy nie jestem w repozytorium Git, nie chcę wykonywać wielu poleceń i otrzymywać fatal: Not a git repositoryodpowiedzi).
Czy szukałeś inspiracji w pliku zakończenia bash (w contrib / dopełnienie / git-uzupełnianie.bash)? Używam polecenia __git_ps1 jako części mojego monitu bash. W rzeczywistości większość z nich będzie pochodzić z zsh. Funkcja __gitdir jest prawdopodobnie tą, której potrzebujesz.
Uwaga: żaden z obecnych odpowiedzi rozważyć $GIT_DIRczy $GIT_WORK_TREEzmienne środowiskowe lub ich sposobu interakcji.
o11c
Odpowiedzi:
154
Skopiowane z pliku zakończenia bash, naiwny sposób to zrobić
# Copyright (C) 2006,2007 Shawn O. Pearce <[email protected]>
# 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;
Możesz to zawinąć w funkcję lub użyć w skrypcie.
Skondensowane w jednym wierszu, odpowiednie dla bash i zsh
@William Pursell Po co rozwidlać, kiedy nie trzeba? Głównie dla prędkości w trywialnym przypadku.
jabbie
16
Odpowiedź powinna zostać zaktualizowana w celu użycia git rev-parse --is-inside-git-dir. Osobiście używam git rev-parse --is-inside-work-treeprzed ustawieniem mojego PS1.
juliohm,
11
@juliohm --is-inside-git-dirzwróci true tylko wtedy, gdy faktycznie znajdujesz się w .gitkatalogu repozytorium. Nie sądzę, że OP tego szuka.
To nadal będzie wyświetlać fałsz dla nagiego repozytorium, które nie ma działającego drzewa
noggin182,
Nie dotyczy to podkatalogu. Muszę sprawdzić, czy git rev-parse --show-toplevelpasuje do podfolderu, który sprawdzam
oprócz
Wybrana odpowiedź nawet niczego nie wydrukowała. Ten zadziałał.
ScottyBlades
47
Użyj git rev-parse --git-dir
if git rev-parse --git-dir> / dev / null 2> & 1; następnie
: # To jest poprawne repozytorium git (ale aktualnie działa
# katalog może nie być najwyższym poziomem.
# Sprawdź dane wyjściowe polecenia git rev-parsuj, jeśli cię to obchodzi)
jeszcze
: # to nie jest repozytorium git
fi
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
Nie jestem pewien, czy istnieje publicznie dostępny / udokumentowany sposób wykonania tej czynności (istnieją pewne wewnętrzne funkcje git, których można używać / nadużywać w samym źródle git)
Możesz zrobić coś takiego;
if ! git ls-files >& /dev/null; then
echo "not in git"
fi
nie zawiera żadnych zbędnych operacji i działa w -etrybie.
Jak zauważył @ go2null , nie będzie działać w nagim repo. Jeśli chcesz pracować z czystym repozytorium z jakiegokolwiek powodu, możesz po prostu sprawdzić, czy się git rev-parsepowiodło, ignorując jego wyniki.
Nie uważam tego za wadę, ponieważ powyższa linia jest przeznaczona do tworzenia skryptów i praktycznie wszystkie gitpolecenia są poprawne tylko w drzewie roboczym. Więc do celów skryptowych najprawdopodobniej jesteś zainteresowany nie tylko „repozytorium git”, ale także środowiskiem roboczym.
Zamiast sprawdzać dane wyjściowe, lepiej jest sprawdzić wartość zwracaną. W ogóle nie wzywaj [. Po prostu zrób if git rev-parse --is-inside-work-tree; then ...(z przekierowaniami zgodnie z życzeniem)
@Ivan_pozdeev Zależy od twojej definicji „pracy”. W takim przypadku powiedziałbym, że sprawdzanie wartości zwracanej działa, a sprawdzanie danych wyjściowych nie. W obu przypadkach, z punktu widzenia najlepszej praktyki pisania kodu w powłoce, bardziej odpowiednie jest sprawdzenie wartości zwracanej.
William Pursell,
@WilliamPursell, jeśli czytasz linkowany komentarz, wiedziałbyś, co mam na myśli przez „nie działa” tutaj.
ivan_pozdeev
6
Innym rozwiązaniem jest sprawdzenie kodu wyjścia polecenia.
git rev-parse 2> /dev/null; [ $? == 0 ] && echo 1
Spowoduje to wydrukowanie 1, jeśli jesteś w folderze repozytorium git.
gitzwraca poziom błędu, 0jeśli znajduje się w repozytorium git, w przeciwnym razie zwraca poziom błędu 128. (Zwraca również truelub falsejeśli znajduje się w repozytorium git.)
Przykład użycia
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
Niewystarczający. Wewnątrz .gitsię powiedzie, ale wydrukuj false.
ivan_pozdeev
@ivan_pozdeev: Jeśli git rev-parse --is-inside-work-treepowróci trueczy falseto jest wewnątrz repo git, i to, co funkcja zwraca. oznacza to, że funkcja jest poprawna
go2null
aby rozwinąć, zobacz opis w odpowiedzi, wartość zwracana z git jest ignorowana, używany jest poziom błędu.
go2null
2
to działa dla mnie. Nadal pojawiają się błędy, ale są one łatwe do stłumienia. działa również z podfolderów!
status git> / dev / null 2> & 1 && echo Hello World!
Możesz umieścić to w instrukcji if, jeśli chcesz warunkowo zrobić więcej.
Wystarczająco dobre w wielu przypadkach, ale nie udaje się to na zwykłym repozytorium git.
Wildcard,
3
git statusmoże być bardzo wolny na dużym / starym repo. Nie użyłbym tego do tego celu.
henrebotha
1
Dlaczego nie używać kodów wyjścia? Jeśli git repozytorium istnieje w bieżącym katalogu, to git branchi git tagpolecenia powrotu kod zakończenia 0; w przeciwnym razie zostanie zwrócony niezerowy kod wyjścia. W ten sposób możesz ustalić, czy repozytorium git istnieje, czy nie. Po prostu możesz uruchomić:
git tag >/dev/null 2>&1&&[ $?-eq 0]
Zaleta : Flexibe. Działa zarówno dla nagich jak i nie nagich repozytoriów, a także w sh, zsh i bash.
Wyjaśnienie
git tag: Pobieranie tagów repozytorium w celu ustalenia, czy istnieje, czy nie.
> /dev/null 2>&1: Zapobieganie drukowaniu czegokolwiek, w tym wydruków normalnych i błędów.
[ $? -eq 0 ]: Sprawdź, czy poprzednie polecenie zwróciło z kodem wyjścia 0, czy nie. Jak zapewne wiesz, każde niezerowe wyjście oznacza, że stało się coś złego. $?dostaje kod zakończenia poprzedniego polecenia, i [, -eqi ]wykonać porównanie.
Na przykład możesz utworzyć plik o check-git-reponastępującej treści, ustawić go jako wykonywalny i uruchomić:
#!/bin/shif git tag >/dev/null 2>&1&&[ $?-eq 0];then
echo "Repository exists!";else
echo "No repository here.";fi
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
To nie jest najlepsza praktyka. Jeśli zostanie uruchomiony poza katalogiem roboczym, otrzymasz „fatal: nie repozytorium git (lub którykolwiek z katalogów nadrzędnych): .git” zapisane na stderr, a „nie, nie jest repozytorium git” na stdout. W ogóle nie trzeba [tu przywoływać . Po prostu zrób:if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then ....
William Pursell,
W moim przypadku czuję się z tym dobrze i chcę śledzić tę usterkę w moich logach. Twoje zdrowie!
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
Dziękuję ivan_pozdeev , Teraz mam test, jeśli w katalogu .git kod nie będzie działał, więc nie zostaną wydrukowane żadne błędy ani fałszywy status wyjścia.
Test „ ! [[$ (Pwd) = .git / || $ (pwd) = * .git]] ”, jeśli nie jesteś w repozytorium .git , uruchomi to polecenie git. Wbudowane polecenie typu służy do sprawdzania, czy masz zainstalowany git lub czy znajduje się on w ŚCIEŻCE. zobacz rodzaj pomocy
Możesz dodać lub wymienić $ PS1 w swoim zshrc za pomocą jednego lub drugiego narzędzia git-prompt. W ten sposób możesz w wygodny sposób dowiedzieć się, czy jesteś w repozytorium git i czy stan repo jest w tym stanie.
The! neguje, więc nawet jeśli uruchomisz to w katalogu, który nie jest repozytorium git, nie spowoduje to poważnych błędów
> / Dev / null 2> & 1 wysyła wiadomości do / dev / null , ponieważ jesteś tylko po stanu wyjściowego. {} Jest do grup sterujących tak wszystkich poleceń Po zmianie || uruchomi się, jeśli git rev-parsowanie się powiedzie, ponieważ używamy! co negowało status wyjścia git rev-pars. Printf jest po prostu wydrukować jakiś stan wiadomości i git wydrukować status repo.
Zawiń go w funkcję lub umieść w skrypcie. Mam nadzieję że to pomoże
$GIT_DIR
czy$GIT_WORK_TREE
zmienne środowiskowe lub ich sposobu interakcji.Odpowiedzi:
Skopiowane z pliku zakończenia bash, naiwny sposób to zrobić
Możesz to zawinąć w funkcję lub użyć w skrypcie.
Skondensowane w jednym wierszu, odpowiednie dla bash i zsh
źródło
git rev-parse --is-inside-git-dir
. Osobiście używamgit rev-parse --is-inside-work-tree
przed ustawieniem mojego PS1.--is-inside-git-dir
zwróci true tylko wtedy, gdy faktycznie znajdujesz się w.git
katalogu repozytorium. Nie sądzę, że OP tego szuka.--is-inside-work-tree
nie--is-inside-git-dir
będzie działać, gdy jesteś poza repozytorium git. patrz: groups.google.com/forum/#!topic/git-users/dWc23LFhWxE.git
. Aby uzyskać solidność, pomiń[ -d .git ]
i po prostu użyjgit rev-parse ...
.Możesz użyć:
Które wypisze „prawda”, jeśli jesteś w drzewie roboczym repozytorium git.
Zauważ, że nadal zwraca dane wyjściowe do STDERR, jeśli jesteś poza repozytorium git (i nie wypisuje „fałszu”).
Zaczerpnięte z tej odpowiedzi: https://stackoverflow.com/a/2044714/12983
źródło
git rev-parse --show-toplevel
pasuje do podfolderu, który sprawdzamUżyj git rev-parse --git-dir
źródło
Lub możesz to zrobić:
źródło
-e
trybie:[ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]
Nie jestem pewien, czy istnieje publicznie dostępny / udokumentowany sposób wykonania tej czynności (istnieją pewne wewnętrzne funkcje git, których można używać / nadużywać w samym źródle git)
Możesz zrobić coś takiego;
źródło
Na podstawie odpowiedzi @Alex Cory :
nie zawiera żadnych zbędnych operacji i działa w
-e
trybie.git rev-parse
powiodło, ignorując jego wyniki.git
polecenia są poprawne tylko w drzewie roboczym. Więc do celów skryptowych najprawdopodobniej jesteś zainteresowany nie tylko „repozytorium git”, ale także środowiskiem roboczym.źródło
[
. Po prostu zróbif git rev-parse --is-inside-work-tree; then ...
(z przekierowaniami zgodnie z życzeniem)Innym rozwiązaniem jest sprawdzenie kodu wyjścia polecenia.
Spowoduje to wydrukowanie 1, jeśli jesteś w folderze repozytorium git.
źródło
.git
katalogu - czego możesz chcieć lub nie.git rev-parse 2>&-
.Ta odpowiedź przesyła próbkę funkcji POSIX powłoki i przykład użycia w celu uzupełnienia @ jabbie za odpowiedź .
git
zwraca poziom błędu,0
jeśli znajduje się w repozytorium git, w przeciwnym razie zwraca poziom błędu128
. (Zwraca równieżtrue
lubfalse
jeśli znajduje się w repozytorium git.)Przykład użycia
źródło
.git
się powiedzie, ale wydrukujfalse
.git rev-parse --is-inside-work-tree
powrócitrue
czyfalse
to jest wewnątrz repo git, i to, co funkcja zwraca. oznacza to, że funkcja jest poprawnato działa dla mnie. Nadal pojawiają się błędy, ale są one łatwe do stłumienia. działa również z podfolderów!
status git> / dev / null 2> & 1 && echo Hello World!
Możesz umieścić to w instrukcji if, jeśli chcesz warunkowo zrobić więcej.
źródło
git status
może być bardzo wolny na dużym / starym repo. Nie użyłbym tego do tego celu.Dlaczego nie używać kodów wyjścia? Jeśli git repozytorium istnieje w bieżącym katalogu, to
git branch
igit tag
polecenia powrotu kod zakończenia 0; w przeciwnym razie zostanie zwrócony niezerowy kod wyjścia. W ten sposób możesz ustalić, czy repozytorium git istnieje, czy nie. Po prostu możesz uruchomić:Zaleta : Flexibe. Działa zarówno dla nagich jak i nie nagich repozytoriów, a także w sh, zsh i bash.
Wyjaśnienie
git tag
: Pobieranie tagów repozytorium w celu ustalenia, czy istnieje, czy nie.> /dev/null 2>&1
: Zapobieganie drukowaniu czegokolwiek, w tym wydruków normalnych i błędów.[ $? -eq 0 ]
: Sprawdź, czy poprzednie polecenie zwróciło z kodem wyjścia 0, czy nie. Jak zapewne wiesz, każde niezerowe wyjście oznacza, że stało się coś złego.$?
dostaje kod zakończenia poprzedniego polecenia, i[
,-eq
i]
wykonać porównanie.Na przykład możesz utworzyć plik o
check-git-repo
następującej treści, ustawić go jako wykonywalny i uruchomić:źródło
# sprawdź, czy repozytorium git
źródło
[
tu przywoływać . Po prostu zrób:if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then ....
Dziękuję ivan_pozdeev , Teraz mam test, jeśli w katalogu .git kod nie będzie działał, więc nie zostaną wydrukowane żadne błędy ani fałszywy status wyjścia.
Test „ ! [[$ (Pwd) = .git / || $ (pwd) = * .git]] ”, jeśli nie jesteś w repozytorium .git , uruchomi to polecenie git. Wbudowane polecenie typu służy do sprawdzania, czy masz zainstalowany git lub czy znajduje się on w ŚCIEŻCE. zobacz rodzaj pomocy
źródło
Co powiesz na to:
źródło
Możesz dodać lub wymienić $ PS1 w swoim zshrc za pomocą jednego lub drugiego narzędzia git-prompt. W ten sposób możesz w wygodny sposób dowiedzieć się, czy jesteś w repozytorium git i czy stan repo jest w tym stanie.
źródło
The! neguje, więc nawet jeśli uruchomisz to w katalogu, który nie jest repozytorium git, nie spowoduje to poważnych błędów
> / Dev / null 2> & 1 wysyła wiadomości do / dev / null , ponieważ jesteś tylko po stanu wyjściowego. {} Jest do grup sterujących tak wszystkich poleceń Po zmianie || uruchomi się, jeśli git rev-parsowanie się powiedzie, ponieważ używamy! co negowało status wyjścia git rev-pars. Printf jest po prostu wydrukować jakiś stan wiadomości i git wydrukować status repo.
Zawiń go w funkcję lub umieść w skrypcie. Mam nadzieję że to pomoże
źródło
.git
się powiedzie, ale wydrukujfalse
.