Status git zwróci 1, jeśli istnieją zmodyfikowane pliki niestacjonarne. Ale ogólnie uważam, że narzędzia git nie są szczególnie dokładne ze statusem zwrotu. EG git diff zwraca 0, niezależnie od tego, czy występują różnice.
intuicyjnie
11
@intuited: Jeśli chcesz diffwskazać obecność lub brak różnic zamiast udanego uruchomienia polecenia, musisz użyć --exit-codelub --quiet. Polecenia git są zasadniczo bardzo spójne ze zwracaniem zerowego lub niezerowego kodu wyjścia, aby wskazać powodzenie polecenia.
CB Bailey,
1
@Charles Bailey: Cześć, tęskniłem za tą opcją. Dzięki! Wydaje mi się, że tak naprawdę nigdy tego nie potrzebowałem, bo prawdopodobnie poszukałbym za to strony. Cieszę się, że mnie poprawiłeś :)
intuicyjnie,
1
Robert - jest to bardzo mylący temat dla społeczności (nie pomaga, że „porcelana” jest używana inaczej w różnych kontekstach). Wybrana odpowiedź ignoruje 2,5-krotnie wyższą odpowiedź, która jest bardziej niezawodna i zgodna z projektem git. Czy widziałeś odpowiedź @ChrisJ?
Mike
1
@Robert - Mam nadzieję, że możesz rozważyć zmianę zaakceptowanej odpowiedzi. Ten, który wybrałeś, opiera się na delikatniejszych poleceniach gitowych „porcelany”; faktyczna poprawna odpowiedź (także z dwukrotnymi poprawkami) zależy od poprawnych poleceń git „hydraulika”. Ta poprawna odpowiedź została pierwotnie napisana przez Chrisa Johnsena. Mówię o tym, ponieważ dzisiaj muszę po raz trzeci skierować kogoś na tę stronę, ale nie mogę po prostu wskazać odpowiedzi, wyjaśniam, dlaczego zaakceptowana odpowiedź jest nieoptymalna / błędna na granicy. Dziękuję Ci!
Mike
Odpowiedzi:
173
Świetny czas! Napisałem post na blogu o tym dokładnie kilka dni temu, kiedy wymyśliłem, jak dodać informacje o statusie git do mojego monitu.
Oto co robię:
W przypadku brudnego statusu:
# Returns "*" if the current git branch is dirty.function evil_git_dirty {[[ $(git diff --shortstat 2>/dev/null | tail -n1)!=""]]&& echo "*"}
W przypadku nieśledzonych plików (zauważ --porcelainflagę, do git statusktórej dajesz dobre wyniki analizowania):
# Returns the number of untracked filesfunction evil_git_num_untracked_files {
expr `git status --porcelain 2>/dev/null| grep "^??" | wc -l`}
Chociaż git diff --shortstatjest to wygodniejsze, możesz również użyć git status --porcelaindo uzyskania brudnych plików:
# Get number of files added to the index (but uncommitted)
expr $(git status --porcelain 2>/dev/null| grep "^M"| wc -l)# Get number of files that are uncommitted and not added
expr $(git status --porcelain 2>/dev/null| grep "^ M"| wc -l)# Get number of total uncommited files
expr $(git status --porcelain 2>/dev/null| egrep "^(M| M)"| wc -l)
Uwaga: 2>/dev/nullOdfiltrowuje komunikaty o błędach, dzięki czemu można używać tych poleceń w katalogach innych niż git. (Po prostu wrócą 0po liczbę plików.)
Warto zauważyć, że zakończenie git bash zawiera funkcję powłoki umożliwiającą wykonywanie praktycznie tego, co robisz za pomocą polecenia - __git_ps1. Wyświetla nazwy oddziałów, w tym specjalne traktowanie, jeśli jesteś w trakcie zmiany bazy, zastosowania, scalenia lub podziału na dwie części. I możesz ustawić zmienną środowiskową, GIT_PS1_SHOWDIRTYSTATEaby uzyskać gwiazdkę dla zmian niestacjonarnych i plus dla zmian etapowych. (Wydaje mi się, że można go również wskazać na nieśledzone pliki i dać trochę git-describedanych wyjściowych)
Cascabel
8
Ostrzeżenie: git diff --shortstatdaje fałszywie ujemny wynik, jeśli zmiany są już w indeksie.
Marko Topolnik
4
git status --porcelainjest preferowane, ponieważ git diff --shortstatnie przechwytuje nowo utworzonych pustych plików. Możesz go wypróbować w każdym czystym, działającym drzewie:touch foo && git diff --shortstat
Campadrenalin
7
NIE - porcelana oznacza, że produkcja jest przeznaczona dla ludzi i łatwo się psuje !! zobacz odpowiedź @ChrisJohnsen, która poprawnie używa stabilnych, przyjaznych skryptom opcji.
Mike,
7
@mike ze strony podręcznika git-status o opcji porcelany: „Daj wynik w łatwym do przeanalizowania formacie dla skryptów. Jest to podobne do krótkiego wyniku, ale pozostanie stabilne we wszystkich wersjach Git i niezależnie od konfiguracji użytkownika. „
itsadok
399
Kluczem do niezawodnego „skryptowania” Gita jest użycie poleceń „hydraulicznych”.
Deweloperzy zwracają uwagę podczas zmiany poleceń hydraulicznych, aby upewnić się, że zapewniają bardzo stabilne interfejsy (tj. Dana kombinacja stanu repozytorium, standardowego wejścia, opcji wiersza poleceń, argumentów itp. Spowoduje wygenerowanie tego samego wyniku we wszystkich wersjach Gita, w których polecenie / opcja istnieje). Nowe warianty danych wyjściowych w komendach hydraulicznych można wprowadzić za pomocą nowych opcji, ale to nie może wprowadzić żadnych problemów dla programów, które zostały już napisane w stosunku do starszych wersji (nie korzystałyby z nowych opcji, ponieważ nie istniały (a przynajmniej były nieużywane) w momencie pisania skryptu).
Niestety „codzienne” polecenia Git to polecenia „porcelanowe”, więc większość użytkowników Gita może nie być zaznajomiona z poleceniami hydraulicznymi. Rozróżnienie między porcelaną a poleceniem hydrauliki jest wykonane na głównej stronie man git (patrz podrozdziały zatytułowane Polecenia wysokiego poziomu (porcelana) i Polecenia niskiego poziomu (hydraulika) .
Aby dowiedzieć się o niezatwierdzonych zmianach, prawdopodobnie będziesz potrzebować git diff-index(porównaj indeks (i być może śledzone fragmenty działającego drzewa) z jakimś innym drzewiastym (np. HEAD)), Może git diff-files(porównaj działające drzewo z indeksem) i ewentualnie git ls-files(wylistuj pliki; np. Lista nieśledzona , nieignorowane pliki).
(Zauważ, że w poniższych poleceniach HEAD --użyto zamiast, HEADponieważ w przeciwnym razie polecenie nie powiedzie się, jeśli istnieje plik o nazwie HEAD.)
Aby sprawdzić, czy repozytorium wprowadziło zmiany (jeszcze nie zatwierdzone):
git diff-index --quiet --cached HEAD --
Jeśli wyjdzie z, 0wtedy nie będzie żadnych różnic ( 1oznacza, że były różnice).
Aby sprawdzić, czy działające drzewo ma zmiany, które można wprowadzić:
git diff-files --quiet
Kod wyjścia jest taki sam jak dla git diff-index( 0== brak różnic; 1== różnice).
Aby sprawdzić, czy kombinacja indeksu i plików śledzonych w drzewie roboczym ma zmiany w odniesieniu do HEAD:
git diff-index --quiet HEAD --
To jest jak połączenie dwóch poprzednich. Jedną z głównych różnic jest to, że nadal będzie zgłaszać „brak różnic”, jeśli masz zmianę etapową, którą „cofnąłeś” w działającym drzewie (wróciłeś do zawartości, która jest w nim HEAD). W tej samej sytuacji oba oddzielne polecenia zwracałyby raporty „obecnych różnic”.
Wspomniałeś także o nieśledzonych plikach. Możesz oznaczać „nieśledzony i niezauważony” lub zwykły „nieśledzony” (w tym pliki ignorowane). Tak czy inaczej, git ls-filesnarzędzie do pracy:
W przypadku „nieśledzonego” (obejmie pliki ignorowane, jeśli są obecne):
git ls-files --others
W przypadku „nieśledzonych i niezauważonych”:
git ls-files --exclude-standard --others
Moją pierwszą myślą jest sprawdzenie, czy te komendy mają dane wyjściowe:
test -z "$(git ls-files --others)"
Jeśli zakończy działanie, oznacza 0to, że nie ma żadnych nieśledzonych plików. Jeśli zakończy działanie, oznacza 1to, że pliki nie są śledzone.
Istnieje niewielka szansa, że przełoży się to na nieprawidłowe wyjścia z git ls-filesraportów na „brak nieśledzonych plików” (oba powodują niezerowe wyjścia z powyższego polecenia). Trochę bardziej niezawodna wersja może wyglądać następująco:
u="$(git ls-files --others)"&& test -z "$u"
Pomysł jest taki sam jak w poprzednim poleceniu, ale umożliwia git ls-filesrozprzestrzenianie się nieoczekiwanych błędów . W takim przypadku niezerowe wyjście może oznaczać „istnieją nieśledzone pliki” lub może oznaczać błąd. Jeśli zamiast tego chcesz, aby wyniki „błąd” były połączone z wynikiem „brak nieśledzonych plików”, użyj test -n "$u"(gdzie wyjście z 0oznacza „niektóre nieśledzone pliki”, a niezerowe oznacza błąd lub „brak nieśledzonych plików”).
Innym pomysłem jest użycie --error-unmatchniezerowego wyjścia, gdy nie ma nieśledzonych plików. Wiąże się to również z ryzykiem, że „brak nieśledzonych plików” (wyjście 1) z „wystąpił błąd” (wyjście niezerowe, ale prawdopodobnie 128). Ale sprawdzanie 0vs 1vs niezerowych kodów wyjścia jest chyba dość wytrzymała:
git ls-files --others --error-unmatch .>/dev/null 2>&1; ec=$?if test "$ec"=0;then
echo some untracked files
elif test "$ec"=1;then
echo no untracked files
else
echo error from ls-files
fi
Każdy z powyższych git ls-filesprzykładów może wziąć, --exclude-standardjeśli chcesz wziąć pod uwagę tylko nieśledzone i niezauważone pliki.
Chciałbym zaznaczyć, że git ls-files --othersdaje to lokalne nieśledzone pliki, podczas git status --porcelaingdy zaakceptowana odpowiedź daje wszystkie nieśledzone pliki znajdujące się w repozytorium git. Nie jestem jednym z tych, których chciał oryginalny plakat, ale różnica między nimi jest interesująca.
Eric O Lebigot,
1
@phunehehe: Musisz podać specyfikację ścieżki --error-unmatch. Spróbuj (np.) git ls-files --other --error-unmatch --exclude-standard .(Zwróć uwagę na kropkę, odnosi się ona do cwd; uruchom ją z katalogu najwyższego poziomu działającego drzewa).
Chris Johnsen
8
@phs: Być może trzeba będzie zrobić git update-index -q --refreshto, diff-indexaby uniknąć pewnych „fałszywych alarmów” spowodowanych przez niezgodne informacje stat (2).
Chris Johnsen
1
Ugryzła mnie git update-indexpotrzeba! Jest to ważne, jeśli coś dotyka plików bez wprowadzania modyfikacji.
Nakedible
2
@RobertSiemer Przez „lokalny” miałem na myśli pliki w bieżącym katalogu , które mogą znajdować się poniżej głównego repozytorium git. Te --porcelainwykazy rozwiązanie wszystkich Nieśledzone pliki znajdujące się w całym repozytorium git (minus git-ignorowane pliki), nawet jeśli jesteś w jednym z jego podkatalogów.
Eric O Lebigot,
139
Zakładając, że korzystasz z git 1.7.0 lub nowszej ...
Po przeczytaniu wszystkich odpowiedzi na tej stronie i przeprowadzeniu niektórych eksperymentów myślę, że metoda, która trafia we właściwe połączenie poprawności i zwięzłości, to:
test -n "$(git status --porcelain)"
Chociaż git pozwala na wiele niuansów między tym, co jest śledzone, ignorowane, nieśledzone, ale niezauważone itd., Uważam, że typowym przypadkiem jest automatyzacja skryptów kompilacji, w których chcesz zatrzymać wszystko, jeśli twoja kasa nie jest czysta.
W takim przypadku warto zasymulować, co zrobiłby programista: wpisz git statusi spójrz na wynik. Ale nie chcemy polegać na wyświetlaniu określonych słów, dlatego używamy --porcelaintrybu wprowadzonego w 1.7.0; po włączeniu czysty katalog nie powoduje wyjścia.
Następnie używamy, test -naby sprawdzić, czy było jakieś wyjście, czy nie.
To polecenie zwróci 1, jeśli katalog roboczy jest czysty, i 0, jeśli zostaną wprowadzone zmiany. Możesz zmienić na -na, -zjeśli chcesz mieć coś przeciwnego. Jest to przydatne do połączenia tego z poleceniem w skrypcie. Na przykład:
test -z "$(git status --porcelain)"|| red-alert "UNCLEAN UNCLEAN"
To skutecznie mówi „albo nie ma żadnych zmian, które należy wprowadzić, albo uruchomić alarm”; ten linijka może być lepsza niż instrukcja if, w zależności od pisanego skryptu.
Dla mnie wszystkie inne polecenia dawały różne wyniki dla tego samego repozytorium między Linuksem a Windows. To polecenie dało mi taki sam wynik w obu.
Adarsha,
6
Dziękuję za udzielenie odpowiedzi na pytanie i nie włóczenie się bez końca, nigdy nie udzielając jasnej odpowiedzi.
NateS
W przypadku skryptu ręcznego wdrażania połącz to z test -n "$(git diff origin/$branch)", aby zapobiec dopuszczeniu lokalnych zatwierdzeń podczas wdrażania
Przejrzałem kilka z tych odpowiedzi ... (i miał różne problemy z * nix i Windows, co było moim wymaganiem) ... okazało się, że następujące działało dobrze ...
git diff --no-ext-diff --quiet --exit-code
Aby sprawdzić kod wyjścia w * nix
echo $?#returns 1 if the repo has changes (0 if clean)
Aby sprawdzić kod wyjścia w oknie $
echo %errorlevel%#returns 1 if the repos has changes (0 if clean)
zwróci odpowiedni kod błędu w zależności od potrzeb
W ten sposób możesz użyć tego statusu „ulepszonego” w skrypcie.
Jak 0xfe wspomina w swojej doskonałej odpowiedzi , git status --porcelainjest pomocny w każdym rozwiązaniu opartym na skryptach
--porcelain
Daj wynik w stabilnym, łatwym do przeanalizowania formacie dla skryptów.
Obecnie jest to identyczne --short output, ale z pewnością nie zmieni się w przyszłości, dzięki czemu jest bezpieczne dla skryptów.
Problem polega na tym, że w przyszłych wersjach nie można niezawodnie oczekiwać, że ciąg „katalog roboczy czysty”. Flaga --porcelain była przeznaczona do analizowania, więc lepszym rozwiązaniem byłoby: wyjście $ (status git --porcelain | wc -l)
0xfe
@ 0xfe - Czy wiesz, kiedy --porcelainflaga została dodana? Nie działa z 1.6.4.2.
Robert Munteanu
@Robert: spróbuj git status --short.
VonC
3
git status --porcelaini git status --shortoba zostały wprowadzone w 1.7.0. --porcelainZostał wprowadzony specjalnie, aby umożliwić git status --shortzmianę formatu w przyszłości. Wystąpiłby więc git status --shortten sam problem co git status(wyjście może się zmienić w dowolnym momencie, ponieważ nie jest to polecenie „hydrauliczne”).
Chris Johnsen
@Chris, dzięki za informacje w tle. Zaktualizowałem odpowiedź, aby odzwierciedlić najlepszy sposób robienia tego od Gita 1.7.0.
Robert Munteanu
2
Często potrzebowałem prostego sposobu na niepowodzenie kompilacji, jeśli pod koniec wykonywania istnieją zmodyfikowane pliki śledzenia lub pliki nieśledzone, które nie są ignorowane.
Jest to bardzo ważne, aby uniknąć sytuacji, w której kompilacje produkują resztki.
Jak dotąd najlepsze polecenie, na którym skończyłem, wygląda następująco:
test -z "$(git status --porcelain | tee /dev/fd/2)"|| \
{{ echo "ERROR: git unclean at the end, failing build."&&return1}}
Może to wyglądać nieco skomplikowane i byłbym wdzięczny, gdyby ktoś znalazł wariant skrócony, który zachowuje pożądane zachowanie:
brak kodu wyjściowego i kodu zakończenia, jeśli wszystko jest w porządku
kod wyjścia 1, jeśli się nie powiedzie
komunikat o błędzie na stderr wyjaśniający, dlaczego nie działa
wyświetl listę plików powodujących awarię, ponownie stderr.
Gdy nie wykonujemy przy użyciu zestawu -e lub równoważnego, możemy zamiast tego zrobić u="$(git ls-files --others)" || exit 1(lub zwrócić, jeśli to działa dla używanej funkcji)
Pliki nieśledzone są ustawiane tylko wtedy, gdy polecenie zakończy się poprawnie.
po czym możemy sprawdzić obie właściwości i ustawić zmienną (lub cokolwiek innego).
Jest to wariant bardziej przyjazny dla powłoki, aby dowiedzieć się, czy w repozytorium istnieją jakieś nieśledzone pliki:
# Works in bash and zshif[["$(git status --porcelain 2>/dev/null)"=*\?\?*]];then
echo untracked files
fi
To nie rozwidla drugiego procesu grepi nie wymaga sprawdzenia, czy jesteś w repozytorium git, czy nie. Co jest przydatne w przypadku monitów powłoki itp.
Pytanie dotyczy konkretnie „skryptu” ... zmiana indeksu nie jest po prostu sprawdzana pod kątem stanu „brudnego”.
ScottJ
@ ScottJ, gdy rozwiązuje problem, nie wszyscy muszą koniecznie ściśle określać, czy indeks można modyfikować, czy nie. Rozważ przypadek zautomatyzowanego zadania, który dotyczy źródeł automatycznej łatki z numerem wersji i stwórz tag - wystarczy, że upewnisz się, że żadne inne lokalne modyfikacje nie przeszkadzają (niezależnie od tego, czy są w indeksie, czy nie). Jak dotąd był to niezawodny test na wszelkie zmiany, w tym nieśledzone pliki .
uvsmtid
-3
Oto najlepszy, najczystszy sposób. Wybrana odpowiedź nie działała dla mnie z jakiegoś powodu, nie wykryła wprowadzonych zmian, które były nowymi plikami, które nie zostały zatwierdzone.
function git_dirty {
text=$(git status)
changed_text="Changes to be committed"
untracked_files="Untracked files"
dirty=false
if[[ ${text}=*"$changed_text"*]];then
dirty=true
fiif[[ ${text}=*"$untracked_files"*]];then
dirty=true
fi
echo $dirty
}
diff
wskazać obecność lub brak różnic zamiast udanego uruchomienia polecenia, musisz użyć--exit-code
lub--quiet
. Polecenia git są zasadniczo bardzo spójne ze zwracaniem zerowego lub niezerowego kodu wyjścia, aby wskazać powodzenie polecenia.Odpowiedzi:
Świetny czas! Napisałem post na blogu o tym dokładnie kilka dni temu, kiedy wymyśliłem, jak dodać informacje o statusie git do mojego monitu.
Oto co robię:
W przypadku brudnego statusu:
W przypadku nieśledzonych plików (zauważ
--porcelain
flagę, dogit status
której dajesz dobre wyniki analizowania):Chociaż
git diff --shortstat
jest to wygodniejsze, możesz również użyćgit status --porcelain
do uzyskania brudnych plików:Uwaga:
2>/dev/null
Odfiltrowuje komunikaty o błędach, dzięki czemu można używać tych poleceń w katalogach innych niż git. (Po prostu wrócą0
po liczbę plików.)Edytuj :
Oto posty:
Dodawanie informacji o statusie Git do terminala
Ulepszone polecenie powłoki z obsługą Gita
źródło
__git_ps1
. Wyświetla nazwy oddziałów, w tym specjalne traktowanie, jeśli jesteś w trakcie zmiany bazy, zastosowania, scalenia lub podziału na dwie części. I możesz ustawić zmienną środowiskową,GIT_PS1_SHOWDIRTYSTATE
aby uzyskać gwiazdkę dla zmian niestacjonarnych i plus dla zmian etapowych. (Wydaje mi się, że można go również wskazać na nieśledzone pliki i dać trochęgit-describe
danych wyjściowych)git diff --shortstat
daje fałszywie ujemny wynik, jeśli zmiany są już w indeksie.git status --porcelain
jest preferowane, ponieważgit diff --shortstat
nie przechwytuje nowo utworzonych pustych plików. Możesz go wypróbować w każdym czystym, działającym drzewie:touch foo && git diff --shortstat
Kluczem do niezawodnego „skryptowania” Gita jest użycie poleceń „hydraulicznych”.
Deweloperzy zwracają uwagę podczas zmiany poleceń hydraulicznych, aby upewnić się, że zapewniają bardzo stabilne interfejsy (tj. Dana kombinacja stanu repozytorium, standardowego wejścia, opcji wiersza poleceń, argumentów itp. Spowoduje wygenerowanie tego samego wyniku we wszystkich wersjach Gita, w których polecenie / opcja istnieje). Nowe warianty danych wyjściowych w komendach hydraulicznych można wprowadzić za pomocą nowych opcji, ale to nie może wprowadzić żadnych problemów dla programów, które zostały już napisane w stosunku do starszych wersji (nie korzystałyby z nowych opcji, ponieważ nie istniały (a przynajmniej były nieużywane) w momencie pisania skryptu).
Niestety „codzienne” polecenia Git to polecenia „porcelanowe”, więc większość użytkowników Gita może nie być zaznajomiona z poleceniami hydraulicznymi. Rozróżnienie między porcelaną a poleceniem hydrauliki jest wykonane na głównej stronie man git (patrz podrozdziały zatytułowane Polecenia wysokiego poziomu (porcelana) i Polecenia niskiego poziomu (hydraulika) .
Aby dowiedzieć się o niezatwierdzonych zmianach, prawdopodobnie będziesz potrzebować
git diff-index
(porównaj indeks (i być może śledzone fragmenty działającego drzewa) z jakimś innym drzewiastym (np.HEAD
)), Możegit diff-files
(porównaj działające drzewo z indeksem) i ewentualniegit ls-files
(wylistuj pliki; np. Lista nieśledzona , nieignorowane pliki).(Zauważ, że w poniższych poleceniach
HEAD --
użyto zamiast,HEAD
ponieważ w przeciwnym razie polecenie nie powiedzie się, jeśli istnieje plik o nazwieHEAD
.)Aby sprawdzić, czy repozytorium wprowadziło zmiany (jeszcze nie zatwierdzone):
0
wtedy nie będzie żadnych różnic (1
oznacza, że były różnice).Aby sprawdzić, czy działające drzewo ma zmiany, które można wprowadzić:
git diff-index
(0
== brak różnic;1
== różnice).Aby sprawdzić, czy kombinacja indeksu i plików śledzonych w drzewie roboczym ma zmiany w odniesieniu do
HEAD
:HEAD
). W tej samej sytuacji oba oddzielne polecenia zwracałyby raporty „obecnych różnic”.Wspomniałeś także o nieśledzonych plikach. Możesz oznaczać „nieśledzony i niezauważony” lub zwykły „nieśledzony” (w tym pliki ignorowane). Tak czy inaczej,
git ls-files
narzędzie do pracy:W przypadku „nieśledzonego” (obejmie pliki ignorowane, jeśli są obecne):
W przypadku „nieśledzonych i niezauważonych”:
Moją pierwszą myślą jest sprawdzenie, czy te komendy mają dane wyjściowe:
0
to, że nie ma żadnych nieśledzonych plików. Jeśli zakończy działanie, oznacza1
to, że pliki nie są śledzone.Istnieje niewielka szansa, że przełoży się to na nieprawidłowe wyjścia z
git ls-files
raportów na „brak nieśledzonych plików” (oba powodują niezerowe wyjścia z powyższego polecenia). Trochę bardziej niezawodna wersja może wyglądać następująco:git ls-files
rozprzestrzenianie się nieoczekiwanych błędów . W takim przypadku niezerowe wyjście może oznaczać „istnieją nieśledzone pliki” lub może oznaczać błąd. Jeśli zamiast tego chcesz, aby wyniki „błąd” były połączone z wynikiem „brak nieśledzonych plików”, użyjtest -n "$u"
(gdzie wyjście z0
oznacza „niektóre nieśledzone pliki”, a niezerowe oznacza błąd lub „brak nieśledzonych plików”).Innym pomysłem jest użycie
--error-unmatch
niezerowego wyjścia, gdy nie ma nieśledzonych plików. Wiąże się to również z ryzykiem, że „brak nieśledzonych plików” (wyjście1
) z „wystąpił błąd” (wyjście niezerowe, ale prawdopodobnie128
). Ale sprawdzanie0
vs1
vs niezerowych kodów wyjścia jest chyba dość wytrzymała:Każdy z powyższych
git ls-files
przykładów może wziąć,--exclude-standard
jeśli chcesz wziąć pod uwagę tylko nieśledzone i niezauważone pliki.źródło
git ls-files --others
daje to lokalne nieśledzone pliki, podczasgit status --porcelain
gdy zaakceptowana odpowiedź daje wszystkie nieśledzone pliki znajdujące się w repozytorium git. Nie jestem jednym z tych, których chciał oryginalny plakat, ale różnica między nimi jest interesująca.--error-unmatch
. Spróbuj (np.)git ls-files --other --error-unmatch --exclude-standard .
(Zwróć uwagę na kropkę, odnosi się ona do cwd; uruchom ją z katalogu najwyższego poziomu działającego drzewa).git update-index -q --refresh
to,diff-index
aby uniknąć pewnych „fałszywych alarmów” spowodowanych przez niezgodne informacje stat (2).git update-index
potrzeba! Jest to ważne, jeśli coś dotyka plików bez wprowadzania modyfikacji.--porcelain
wykazy rozwiązanie wszystkich Nieśledzone pliki znajdujące się w całym repozytorium git (minus git-ignorowane pliki), nawet jeśli jesteś w jednym z jego podkatalogów.Zakładając, że korzystasz z git 1.7.0 lub nowszej ...
Po przeczytaniu wszystkich odpowiedzi na tej stronie i przeprowadzeniu niektórych eksperymentów myślę, że metoda, która trafia we właściwe połączenie poprawności i zwięzłości, to:
Chociaż git pozwala na wiele niuansów między tym, co jest śledzone, ignorowane, nieśledzone, ale niezauważone itd., Uważam, że typowym przypadkiem jest automatyzacja skryptów kompilacji, w których chcesz zatrzymać wszystko, jeśli twoja kasa nie jest czysta.
W takim przypadku warto zasymulować, co zrobiłby programista: wpisz
git status
i spójrz na wynik. Ale nie chcemy polegać na wyświetlaniu określonych słów, dlatego używamy--porcelain
trybu wprowadzonego w 1.7.0; po włączeniu czysty katalog nie powoduje wyjścia.Następnie używamy,
test -n
aby sprawdzić, czy było jakieś wyjście, czy nie.To polecenie zwróci 1, jeśli katalog roboczy jest czysty, i 0, jeśli zostaną wprowadzone zmiany. Możesz zmienić na
-n
a,-z
jeśli chcesz mieć coś przeciwnego. Jest to przydatne do połączenia tego z poleceniem w skrypcie. Na przykład:To skutecznie mówi „albo nie ma żadnych zmian, które należy wprowadzić, albo uruchomić alarm”; ten linijka może być lepsza niż instrukcja if, w zależności od pisanego skryptu.
źródło
test -n "$(git diff origin/$branch)"
, aby zapobiec dopuszczeniu lokalnych zatwierdzeń podczas wdrażaniaImplementacja z odpowiedzi VonC :
źródło
Przejrzałem kilka z tych odpowiedzi ... (i miał różne problemy z * nix i Windows, co było moim wymaganiem) ... okazało się, że następujące działało dobrze ...
Aby sprawdzić kod wyjścia w * nix
Aby sprawdzić kod wyjścia w oknie $
Źródło: https://github.com/sindresorhus/pure/issues/115 Dzięki @paulirish w tym poście za udostępnienie
źródło
Dlaczego nie „zamknąć”
git status
skryptu, który:W ten sposób możesz użyć tego statusu „ulepszonego” w skrypcie.
Jak 0xfe wspomina w swojej doskonałej odpowiedzi ,
git status --porcelain
jest pomocny w każdym rozwiązaniu opartym na skryptachźródło
Jedna możliwość majsterkowania, zaktualizowana zgodnie z sugestią 0xfe
Jak zauważył Chris Johnsen , działa to tylko na Git 1.7.0 lub nowszym.
źródło
--porcelain
flaga została dodana? Nie działa z 1.6.4.2.git status --short
.git status --porcelain
igit status --short
oba zostały wprowadzone w 1.7.0.--porcelain
Został wprowadzony specjalnie, aby umożliwićgit status --short
zmianę formatu w przyszłości. Wystąpiłby więcgit status --short
ten sam problem cogit status
(wyjście może się zmienić w dowolnym momencie, ponieważ nie jest to polecenie „hydrauliczne”).Często potrzebowałem prostego sposobu na niepowodzenie kompilacji, jeśli pod koniec wykonywania istnieją zmodyfikowane pliki śledzenia lub pliki nieśledzone, które nie są ignorowane.
Jest to bardzo ważne, aby uniknąć sytuacji, w której kompilacje produkują resztki.
Jak dotąd najlepsze polecenie, na którym skończyłem, wygląda następująco:
Może to wyglądać nieco skomplikowane i byłbym wdzięczny, gdyby ktoś znalazł wariant skrócony, który zachowuje pożądane zachowanie:
źródło
@ eduard-wirch odpowiedź była dość kompletna, ale ponieważ chciałem sprawdzić oba jednocześnie, oto mój ostateczny wariant.
Gdy nie wykonujemy przy użyciu zestawu -e lub równoważnego, możemy zamiast tego zrobić
u="$(git ls-files --others)" || exit 1
(lub zwrócić, jeśli to działa dla używanej funkcji)Pliki nieśledzone są ustawiane tylko wtedy, gdy polecenie zakończy się poprawnie.
po czym możemy sprawdzić obie właściwości i ustawić zmienną (lub cokolwiek innego).
źródło
Jest to wariant bardziej przyjazny dla powłoki, aby dowiedzieć się, czy w repozytorium istnieją jakieś nieśledzone pliki:
To nie rozwidla drugiego procesu
grep
i nie wymaga sprawdzenia, czy jesteś w repozytorium git, czy nie. Co jest przydatne w przypadku monitów powłoki itp.źródło
Możesz też zrobić
. Na końcu doda słowo „-dirty”, jeśli wykryje brudne drzewo robocze. Według
git-describe(1)
:. Uwaga: nieśledzone pliki nie są uważane za „brudne”, ponieważ, jak stwierdza strona podręcznika, zależy tylko na działającym drzewie.
źródło
Nie może być lepsze połączenie z odpowiedzi z tego wątku .. ale działa to dla mnie ... w twoim
.gitconfig
„s[alias]
sekcji ...źródło
Najprostszy automatyczny test, którego używam do wykrywania stanu nieczystości = wszelkie zmiany, w tym nieśledzone pliki :
UWAGA:
add --all
diff-index
nie zauważa nieśledzonych plików.git reset
po przetestowaniu kodu błędu, aby cofnąć scenę.źródło
Oto najlepszy, najczystszy sposób. Wybrana odpowiedź nie działała dla mnie z jakiegoś powodu, nie wykryła wprowadzonych zmian, które były nowymi plikami, które nie zostały zatwierdzone.
źródło