¿Cómo no cometer nada sin un error?

91

Estoy tratando de escribir un script de tela que haga a git commit; sin embargo, si no hay nada que confirmar, git sale con un estado de 1. La secuencia de comandos de implementación considera que no se ha realizado correctamente y se cierra. Quiero detectar fallas reales de confirmación, por lo que no puedo simplemente ignorar las git commitfallas de la tela . ¿Cómo puedo permitir que se ignoren las fallas de confirmación vacía para que la implementación pueda continuar, pero aún así detectar los errores causados ​​cuando falla una confirmación real?

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

Respuestas:

154

¿Detecta esta condición de antemano verificando el código de salida de git diff?

Por ejemplo (en cáscara):

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

EDITAR: git diffcomando fijo según el comentario de Holger.

Tobi
fuente
64
Tenga en cuenta que git diffes un comando "porcelana" que no debe utilizarse para la creación de scripts. Lo que probablemente quieras es git diff-index --quiet HEAD || git commit -m 'bla'. Vea también esta respuesta .
Holger
1
Para explicar más las cosas, el problema git diff --quiet --exit-code --cachedes que se evaluará como 1(falso) solo para los archivos modificados que no se han preparado para su confirmación (archivos no agregados). El comentario con voto positivo es la mejor solución para contabilizar nuevos archivos y eliminaciones.
Jorge Bucaran
2
El comentario sobre git diff-index --quiet HEAD || git commit -m 'bla'debería ser una respuesta a esta pregunta.
Rakib
1
Como a Tobi no le importaba arreglar su respuesta de acuerdo con el comentario de Holger, yo mismo edité su respuesta.
vog
Tenga en cuenta que git diff-index --quiet HEAD no prueba si el repositorio local está actualizado con el origen.
bortzmeyer
62

Desde la git commitpágina del 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
fuente
41
Sin embargo, esto en realidad crearía un compromiso.
ThiefMaster
6
@ThiefMaster: Correcto. No puedo decir desde el OP si esto es un problema o no. Supongo que si está utilizando confirmaciones automáticas, no le importa que su historial esté limpio de todos modos.
Sven Marnach
1
Preferiría que no se comprometa si se puede evitar. ¿Hay una manera de hacer eso?
kojiro
3
Esta no es la respuesta a la pregunta
manojlds
7
@manojlds: "Por supuesto que el OP no quiere crear una confirmación vacía". Hoy dejé mi bola de cristal en casa, así que no lo sabía. Sin -pembargo, se perdió el , pero aún así
Sven Marnach
5
with settings(warn_only=True):
  run('git commit ...')

Esto hace que la tela ignore la falla. Tiene la ventaja de no crear confirmaciones vacías.

Puede envolverlo en una capa adicional de with hide('warnings'):para suprimir totalmente la salida; de lo contrario, obtendrá una nota en la salida de la tela que indica que la confirmación falló (pero el fabfile continúa ejecutándose).

Tyler Eaves
fuente
3
OP escribió "Quiero detectar fallas reales de confirmación"; este código ocultará todas las fallas de confirmación.
bfontaine
-2

¡Intenta atrapar al 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
fuente
10
Para explicar por qué es votado en contra: Puede haber otros errores que desee detectar. No quiere simplemente asumir que en caso de error, es posible que no tenga que cometer nada. - Además, pero eso no está relacionado: nunca use un genérico except:, use except Exceptiono algo así.
Albert