Jak nic nie popełnić bez błędu?

91

Próbuję napisać skrypt tkaniny, który robi git commit; jednak jeśli nie ma nic do zatwierdzenia, git kończy pracę ze statusem 1. Skrypt wdrażania traktuje to jako niepowodzenie i kończy pracę. Chcę wykrywać rzeczywiste niepowodzenia w zatwierdzaniu, więc nie mogę po prostu dać tkaninie koca ignorowania git commitbłędów. Jak mogę pozwolić na ignorowanie błędów zatwierdzania pustego, aby wdrażanie mogło być kontynuowane, ale nadal przechwytywało błędy spowodowane niepowodzeniem prawdziwego zatwierdzenia?

def commit():
    local("git add -p && git commit")
kojiro
źródło

Odpowiedzi:

154

Wyłapać ten warunek wcześniej, sprawdzając kod zakończenia git diff?

Na przykład (w powłoce):

git add -A
git diff-index --quiet HEAD || git commit -m 'bla'

EDYCJA: Naprawiono git diffpolecenie zgodnie z komentarzem Holgera.

Tobi
źródło
64
Zauważ, że git diffjest to polecenie „porcelain”, którego nie należy używać do tworzenia skryptów. To, czego najprawdopodobniej chcesz, to git diff-index --quiet HEAD || git commit -m 'bla'. Zobacz także tę odpowiedź .
Holger,
1
Aby wyjaśnić git diff --quiet --exit-code --cachedsprawę dokładniej, problem polega na tym, że ocena zostanie oceniona na 1(false) tylko dla zmodyfikowanych plików, które nie zostały przygotowane do zatwierdzenia (pliki niedodane). Głosowany w górę komentarz jest najlepszym rozwiązaniem do uwzględnienia nowych plików i usunięć.
Jorge Bucaran
2
Komentarz git diff-index --quiet HEAD || git commit -m 'bla'powinien być odpowiedzią na to pytanie.
Rakib
1
Ponieważ Tobi nie chciał poprawić swojej odpowiedzi zgodnie z komentarzem Holgera, sam zredagowałem jego odpowiedź.
vog,
Zauważ, że git diff-index --quiet HEAD nie sprawdza, czy lokalne repozytorium jest aktualne.
bortzmeyer
62

Ze strony podręcznika git commit:

--allow-empty
    Usually recording a commit that has the exact same tree as its
    sole parent commit is a mistake, and the command prevents you
    from making such a commit. This option bypassesthe safety, and
    is primarily for use by foreign SCM interface scripts.
Sven Marnach
źródło
41
To faktycznie stworzyłoby zatwierdzenie.
ThiefMaster
6
@ThiefMaster: Racja. Nie mogę powiedzieć z OP, czy to jest problem, czy nie. Myślę, że jeśli używasz automatycznych zatwierdzeń, i tak nie przejmujesz się tym, że twoja historia jest czysta.
Sven Marnach
1
Wolałbym, żeby nie popełniał, jeśli można tego uniknąć. Czy jest na to sposób?
kojiro
3
To nie jest odpowiedź na pytanie
manojlds 14.11.11
7
@manojlds: "Oczywiście OP nie chce tworzyć pustego zatwierdzenia." Zostawiłem dzisiaj kryształową kulę w domu, więc nie wiedziałem. przegapił -pchoć, ale nadal
Sven Marnach
5
with settings(warn_only=True):
  run('git commit ...')

Powoduje to, że tkanina ignoruje awarię. Ma tę zaletę, że nie tworzy pustych zatwierdzeń.

Możesz owinąć go dodatkową warstwą, with hide('warnings'):aby całkowicie stłumić wyjście, w przeciwnym razie otrzymasz informację w wyjściu tkaniny, że zatwierdzenie nie powiodło się (ale fabfile nadal jest wykonywany).

Tyler Eaves
źródło
3
OP napisał: „Chcę wykryć rzeczywiste błędy w zatwierdzaniu”; ten kod ukryje wszystkie niepowodzenia zatwierdzenia.
bfontaine
-2

spróbuj / złap dziecko!

from fabric.api import local
from fabric.colors import green


def commit(message='updates'):
    try:
        local('git add .')
        local('git commit -m "' + message + '"')
        local('git push')
        print(green('Committed and pushed to git.', bold=False))
    except:
        print(green('Done committing, likely nothing new to commit.', bold=False))
devpascoe
źródło
10
Aby wyjaśnić, dlaczego zostałeś odrzucony: mogą być inne błędy, które chcesz wyłapać. Nie chcesz po prostu zakładać, że w przypadku błędu może się zdarzyć, że nic nie musi zostać popełnione. - Poza tym, ale to nie ma związku: nigdy nie używaj ogólnego except:, except Exceptionzamiast tego używaj lub czegoś podobnego.
Albert