Como fazer git commitar nada sem um erro?

92

Estou tentando escrever um script de tecido que faz um git commit; entretanto, se não houver nada para confirmar, o git sai com um status de 1. O script de implantação considera isso malsucedido e fecha. Eu quero detectar falhas reais de confirmação, então não posso simplesmente ignorar o tecido para git commitfalhas. Como posso permitir que falhas de confirmação vazia sejam ignoradas para que a implantação possa continuar, mas ainda detecte erros causados ​​quando uma confirmação real falha?

def commit():
    local("git add -p && git commit")
kojiro
fonte

Respostas:

157

Pegue essa condição de antemão verificando o código de saída de git diff?

Por exemplo (em shell):

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

EDIT: Corrigido o git diffcomando de acordo com o comentário de Holger.

Tobi
fonte
64
Observe que git diffé um comando "porcelain" que não deve ser usado para scripts. O que você provavelmente deseja é git diff-index --quiet HEAD || git commit -m 'bla'. Veja também esta resposta .
Holger
1
Para explicar melhor as coisas, o problema com git diff --quiet --exit-code --cachedé que ele será avaliado como 1(falso) apenas para arquivos modificados que não foram testados para confirmação (arquivos não adicionados). O comentário aprovado é a melhor solução para contabilizar novos arquivos e exclusões.
Jorge Bucaran
2
O comentário sobre git diff-index --quiet HEAD || git commit -m 'bla'deve ser uma resposta a esta pergunta.
Rakib
1
Como Tobi não se importou em corrigir sua resposta de acordo com o comentário de Holger, editei sua resposta eu mesmo.
vog
Observe que git diff-index --quiet HEAD não testa se o repositório local está atualizado com a origem.
bortzmeyer
62

Na git commitpágina de manual:

--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
fonte
43
No entanto, isso criaria um commit.
ThiefMaster
6
@ThiefMaster: Certo. Não posso dizer a partir do OP se isso é um problema ou não. Eu acho que se você está usando commits automáticos, você não se importa se seu histórico está limpo de qualquer maneira.
Sven Marnach
1
Eu preferiria não cometer, se puder ser evitado. Existe uma maneira de fazer isso?
kojiro
3
Esta não é a resposta para a pergunta
manojlds
7
@manojlds: "Claro que o OP não quer criar um commit vazio." Deixei minha bola de cristal em casa hoje, então não sabia. perdi -p, porém, mas ainda
Sven Marnach
5
with settings(warn_only=True):
  run('git commit ...')

Isso faz com que o tecido ignore a falha. Tem a vantagem de não criar commits vazios.

Você pode envolvê-lo em uma camada adicional de with hide('warnings'):para suprimir totalmente a saída, caso contrário, você obterá uma nota na saída da malha de que o commit falhou (mas o fabfile continua a ser executado).

Tyler Eaves
fonte
3
OP escreveu "Eu quero detectar falhas reais de confirmação"; este código irá ocultar todas as falhas de confirmação.
bfontaine
-2

tente / pegar bebê!

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
fonte
10
Para explicar por que você foi rejeitado: Pode haver outros erros que você deseja detectar. Você não quer apenas presumir que, em caso de erro, pode ser que nada precise ser confirmado. - Além disso, mas isso não está relacionado: nunca use um genérico except:, use except Exceptionou assim.
Albert,